emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk 91d450d 1/3: Fix pgtk-display-monitor-attributes-list to re


From: Yuuki Harano
Subject: feature/pgtk 91d450d 1/3: Fix pgtk-display-monitor-attributes-list to return physical pixel sizes.
Date: Sun, 3 Jan 2021 02:29:40 -0500 (EST)

branch: feature/pgtk
commit 91d450d1fbe78717f34f4c28789d3f4c6ecd6061
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Yuuki Harano <masm+github@masm11.me>

    Fix pgtk-display-monitor-attributes-list to return physical pixel sizes.
    
    * src/pgtkfns.c (Fpgtk_display_monitor_attributes_list): Re-port it.
---
 src/pgtkfns.c | 159 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 79 insertions(+), 80 deletions(-)

diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index cf84163..f52dab6 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -2383,109 +2383,108 @@ each physical monitor, use 
`display-monitor-attributes-list'.  */)
   return make_fixnum (x_display_pixel_height (dpyinfo));
 }
 
-DEFUN ("pgtk-display-monitor-attributes-list", 
Fpgtk_display_monitor_attributes_list, Spgtk_display_monitor_attributes_list, 
0, 1, 0,
+DEFUN ("pgtk-display-monitor-attributes-list", 
Fpgtk_display_monitor_attributes_list,
+       Spgtk_display_monitor_attributes_list,
+       0, 1, 0,
        doc: /* Return a list of physical monitor attributes on the X display 
TERMINAL.
 
 The optional argument TERMINAL specifies which display to ask about.
 TERMINAL should be a terminal object, a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.
 
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
+
+ source -- String describing the source from which multi-monitor
+          information is obtained, \"Gdk\"
+
 Internal use only, use `display-monitor-attributes-list' instead.  */)
   (Lisp_Object terminal)
 {
-  struct terminal *term = decode_live_terminal (terminal);
   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
-  GdkDisplay *gdpy = dpyinfo->gdpy;
-  GdkMonitor **gmons;
-  int i, n_monitors, primary_index;
-  struct MonitorInfo *monitors;
-  Lisp_Object monitor_frames = Qnil;
-  Lisp_Object frame = Qnil, rest = Qnil;
-  Lisp_Object rv = Qnil;
+  Lisp_Object attributes_list = Qnil;
 
-  if (term->type != output_pgtk)
-    return Qnil;
+  GdkDisplay *gdpy;
+  gint primary_monitor = 0, n_monitors, i;
+  Lisp_Object monitor_frames, rest, frame;
+  static const char *source = "Gdk";
+  struct MonitorInfo *monitors;
 
+  block_input ();
+  gdpy = dpyinfo->gdpy;
   n_monitors = gdk_display_get_n_monitors (gdpy);
-  if (n_monitors == 0)
-    return Qnil;
-
-  gmons = xmalloc (sizeof *gmons * n_monitors);
-  for (i = 0; i < n_monitors; i++)
-    gmons[i] = gdk_display_get_monitor (gdpy, i);
-
+  monitor_frames = make_nil_vector (n_monitors);
   monitors = xzalloc (n_monitors * sizeof *monitors);
-  for (i = 0; i < n_monitors; i++)
-    {
-      struct MonitorInfo *mon = &monitors[i];
-      GdkMonitor *gmon = gmons[i];
-      if (gmon != NULL)
-       {
-         GdkRectangle geom;
-         gdk_monitor_get_geometry (gmon, &geom);
-         mon->geom.x = geom.x;
-         mon->geom.y = geom.y;
-         mon->geom.width = geom.width;
-         mon->geom.height = geom.height;
-
-         gdk_monitor_get_workarea (gmon, &geom);
-         mon->work.x = geom.x;
-         mon->work.y = geom.y;
-         mon->work.width = geom.width;
-         mon->work.height = geom.height;
-
-         mon->mm_width = gdk_monitor_get_width_mm (gmon);
-         mon->mm_height = gdk_monitor_get_height_mm (gmon);
-
-         mon->name = xstrdup (gdk_monitor_get_model (gmon));
-       }
-    }
 
-  monitor_frames = Fmake_vector (make_fixnum (n_monitors), Qnil);
   FOR_EACH_FRAME (rest, frame)
-  {
-    struct frame *f = XFRAME (frame);
-
-    if (FRAME_PGTK_P (f))
-      {
-       GtkWidget *widget = FRAME_GTK_WIDGET (f);
-       GdkMonitor *gmon =
-         gdk_display_get_monitor_at_window (gdpy,
-                                            gtk_widget_get_window (widget));
-
-       if (gmon != NULL)
-         {
-           for (i = 0; i < n_monitors; i++)
-             {
-               if (gmons[i] == gmon)
-                 {
-                   ASET (monitor_frames, i,
-                         Fcons (frame, AREF (monitor_frames, i)));
-                   break;
-                 }
-             }
-         }
-      }
-  }
-
-  primary_index = -1;
-  for (i = 0; i < n_monitors; i++)
     {
-      if (gmons[i] != NULL && gdk_monitor_is_primary (gmons[i]))
+      struct frame *f = XFRAME (frame);
+
+      if (FRAME_PGTK_P (f)
+         && FRAME_DISPLAY_INFO (f) == dpyinfo
+         && !FRAME_TOOLTIP_P (f))
        {
-         primary_index = i;
-         break;
+         GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+
+          for (i = 0; i < n_monitors; i++)
+            if (gdk_display_get_monitor_at_window (gdpy, gwin)
+                == gdk_display_get_monitor (gdpy, i))
+              break;
+         ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
        }
     }
 
-  rv =
-    make_monitor_attribute_list (monitors, n_monitors, primary_index,
-                                monitor_frames, "Gdk");
-
+  for (i = 0; i < n_monitors; ++i)
+    {
+      gint width_mm, height_mm;
+      GdkRectangle rec, work;
+      struct MonitorInfo *mi = &monitors[i];
+      int scale = 1;
+
+      GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+      if (gdk_monitor_is_primary (monitor))
+        primary_monitor = i;
+      gdk_monitor_get_geometry (monitor, &rec);
+
+      width_mm = gdk_monitor_get_width_mm (monitor);
+      height_mm = gdk_monitor_get_height_mm (monitor);
+      gdk_monitor_get_workarea (monitor, &work);
+
+      /* GTK returns scaled sizes for the workareas.  */
+      scale = gdk_monitor_get_scale_factor (monitor);
+      rec.x *= scale;
+      rec.y *= scale;
+      rec.width *= scale;
+      rec.height *= scale;
+      work.x *= scale;
+      work.y *= scale;
+      work.width *= scale;
+      work.height *= scale;
+
+      mi->geom.x = rec.x;
+      mi->geom.y = rec.y;
+      mi->geom.width = rec.width;
+      mi->geom.height = rec.height;
+      mi->work.x = work.x;
+      mi->work.y = work.y;
+      mi->work.width = work.width;
+      mi->work.height = work.height;
+      mi->mm_width = width_mm;
+      mi->mm_height = height_mm;
+
+      dupstring (&mi->name, (gdk_monitor_get_model (monitor)));
+    }
+
+  attributes_list = make_monitor_attribute_list (monitors,
+                                                 n_monitors,
+                                                 primary_monitor,
+                                                 monitor_frames,
+                                                 source);
   free_monitors (monitors, n_monitors);
-  xfree (gmons);
+  unblock_input ();
 
-  return rv;
+  return attributes_list;
 }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]