From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: =?iso-8859-1?Q?Jan_Dj=E4rv?= Newsgroups: gmane.emacs.devel Subject: Re: x-display-pixel-width/height inconsistency Date: Sat, 27 Apr 2013 10:04:46 +0200 Message-ID: <5073D6B8-95E4-4012-AA74-106F428379DC@swipnet.se> References: <514A5DE1.10009@gmx.de> <831ub767wf.fsf@gnu.org> <83mwtu4p7c.fsf@gnu.org> <83vc8h313t.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 (Mac OS X Mail 6.3 \(1503\)) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1367049886 20458 80.91.229.3 (27 Apr 2013 08:04:46 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 27 Apr 2013 08:04:46 +0000 (UTC) Cc: emacs-devel@gnu.org To: YAMAMOTO Mitsuharu Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Apr 27 10:04:50 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UW07l-00012i-OJ for ged-emacs-devel@m.gmane.org; Sat, 27 Apr 2013 10:04:50 +0200 Original-Received: from localhost ([::1]:44714 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UW07l-00047K-7X for ged-emacs-devel@m.gmane.org; Sat, 27 Apr 2013 04:04:49 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:44561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UW07g-00047D-QK for emacs-devel@gnu.org; Sat, 27 Apr 2013 04:04:47 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UW07e-0002Qh-Hf for emacs-devel@gnu.org; Sat, 27 Apr 2013 04:04:44 -0400 Original-Received: from mailout.melmac.se ([62.20.26.67]:64462) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UW07e-0002QV-6F for emacs-devel@gnu.org; Sat, 27 Apr 2013 04:04:42 -0400 Original-Received: from mail01.melmac.se (mail01.melmac.se [62.20.26.80]) by mailout.melmac.se (Postfix) with ESMTP id AE11F95F6 for ; Sat, 27 Apr 2013 10:04:39 +0200 (CEST) Original-Received: (qmail 12074 invoked by uid 89); 27 Apr 2013 08:03:38 -0000 Original-Received: from h-46-59-42-18.na.cust.bahnhof.se (HELO coolsville.localdomain) (boel.djarv@bdtv.se@46.59.42.18) by mail01.melmac.se with ESMTPA; 27 Apr 2013 08:03:38 -0000 Original-Received: from [172.20.199.13] (zeplin [172.20.199.13]) by coolsville.localdomain (Postfix) with ESMTPSA id 1B9757FA058; Sat, 27 Apr 2013 10:04:39 +0200 (CEST) In-Reply-To: X-Mailer: Apple Mail (2.1503) X-detected-operating-system: by eggs.gnu.org: Solaris 10 X-Received-From: 62.20.26.67 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:159179 Archived-At: Hello. A general objection is that XRandr/Xinerama is not used, so the non-Gtk+ = code relies on a freedesktop compliant window manager, rather than = taking the general approach. If XRandr/Xinerama is used, no split = between Gtk+ and non-Gtk+ code is needed. Xrandr/Xinerama is what Gtk+ = use anyway so we are not adding any new dependencies. Jan D. 27 apr 2013 kl. 07:13 skrev YAMAMOTO Mitsuharu = : >>>>>> On Sun, 24 Mar 2013 13:36:03 +0900, YAMAMOTO Mitsuharu = said: >=20 >>>> Tweeking x-display-pixel-width/height in a platform-specific way >>>> or adding functions such as display-usable-bounds in the NS port >>>> without considering the whole design for operations on monitors >>>> looks rather ad hoc to me. >=20 >>> Then please present a design that would make sense, not just an >>> ad-hoc set of changes to align all the platforms to the X11 >>> behavior. >=20 >> Aligning all the platforms to the X11 is not ad hoc but makes >> several things consistent, not only behaviors among multiple >> platforms but also the argument convention among x-display-* >> functions. >=20 >> A possible design for the new function would be: >=20 >> DEFUN ("x-display-monitor-attributes-list", >=20 > The patch below implements this primitive for GTK+ builds (and also > contains a "degenerated" fallback for non-GTK+ X11 builds) as a > starting point for the discussion about its design. >=20 > What would the preferred format for rectangles be? The patch uses the > format that geometry-related functions (such as x-parse-geometry) are > using, but it might look a bit awkward for this purpose because of > quoting "+" for possibly negative coordinates for positions. >=20 > YAMAMOTO Mitsuharu > mituharu@math.s.chiba-u.ac.jp >=20 > =3D=3D=3D modified file 'src/xfns.c' > *** src/xfns.c 2013-04-07 04:41:19 +0000 > --- src/xfns.c 2013-04-26 13:58:27 +0000 > *************** > *** 126,131 **** > --- 126,132 ---- > static Lisp_Object Qsuppress_icon; > static Lisp_Object Qundefined_color; > static Lisp_Object Qcompound_text, Qcancel_timer; > + static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes; > Lisp_Object Qfont_param; >=20 > #ifdef GLYPH_DEBUG > *************** > *** 3791,3796 **** > --- 3792,4067 ---- > else > return Qnil; > } > +=20 > + /* Return an alist of the form > + ((left . (+ XOFFSET)) (top . (+ YOFFSET)) > + (width . WIDTH) (height . HEIGHT)) > + with converting XOFFSET, YOFFSET, WIDTH and HEIGHT to Lisp > + integers. */ > +=20 > + static Lisp_Object > + x_create_geometry_alist (EMACS_INT xoffset, EMACS_INT yoffset, > + EMACS_INT width, EMACS_INT height) > + { > + return list4 (Fcons (Qleft, list2 (Qplus, make_number (xoffset))), > + Fcons (Qtop, list2 (Qplus, make_number (yoffset))), > + Fcons (Qwidth, make_number (width)), > + Fcons (Qheight, make_number (height))); > + } > +=20 > + /* Return an alist of the form ((width . WIDTH) (height . HEIGHT)). > + with converting WIDTH and HEIGHT to Lisp integers. */ > +=20 > + static Lisp_Object > + x_create_size_alist (EMACS_INT width, EMACS_INT height) > + { > + return list2 (Fcons (Qwidth, make_number (width)), > + Fcons (Qheight, make_number (height))); > + } > +=20 > + /* Store the geometry of the workarea on display DPYINFO into *RECT. > + Return false if and only if the workarea information cannot be > + obtained via the _NET_WORKAREA root window property. */ > +=20 > + static bool > + x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle = *rect) > + { > + Display *dpy =3D dpyinfo->display; > + long offset, max_len; > + Atom target_type, actual_type; > + unsigned long actual_size, bytes_remaining; > + int rc, actual_format; > + unsigned char *tmp_data =3D NULL; > + bool result =3D false; > +=20 > + x_catch_errors (dpy); > + offset =3D 0; > + max_len =3D 1; > + target_type =3D XA_CARDINAL; > + rc =3D XGetWindowProperty (dpy, dpyinfo->root_window, > + dpyinfo->Xatom_net_current_desktop, > + offset, max_len, False, target_type, > + &actual_type, &actual_format, &actual_size, > + &bytes_remaining, &tmp_data); > + if (rc =3D=3D Success && actual_type =3D=3D target_type && = !x_had_errors_p (dpy) > + && actual_format =3D=3D 32 && actual_size =3D=3D max_len) > + { > + long current_desktop =3D ((long *) tmp_data)[0]; > +=20 > + XFree (tmp_data); > + tmp_data =3D NULL; > +=20 > + offset =3D 4 * current_desktop; > + max_len =3D 4; > + rc =3D XGetWindowProperty (dpy, dpyinfo->root_window, > + dpyinfo->Xatom_net_workarea, > + offset, max_len, False, target_type, > + &actual_type, &actual_format, = &actual_size, > + &bytes_remaining, &tmp_data); > + if (rc =3D=3D Success && actual_type =3D=3D target_type && = !x_had_errors_p (dpy) > + && actual_format =3D=3D 32 && actual_size =3D=3D max_len) > + { > + long *workareas =3D (long *) tmp_data; > +=20 > + rect->x =3D workareas[0]; > + rect->y =3D workareas[1]; > + rect->width =3D workareas[2]; > + rect->height =3D workareas[3]; > +=20 > + XFree (tmp_data); > + tmp_data =3D NULL; > +=20 > + result =3D true; > + } > + } > + if (tmp_data) > + XFree (tmp_data); > + x_uncatch_errors (); > +=20 > + return result; > + } > +=20 > + DEFUN ("x-display-monitor-attributes-list", = Fx_display_monitor_attributes_list, > + Sx_display_monitor_attributes_list, > + 0, 1, 0, > + doc: /* Return a list of physical monitor attributes on X = display. > + Each element of the list represents the attributes of each physical > + monitor. The first element corresponds to the primary monitor. > +=20 > + Attributes for a physical monitor is represented as an alist of > + attribute names and values as follows: > +=20 > + Name | Value > + ---------+-------------------------------------------------- > + geometry | Position and size in the form of > + | ((left . (+ XOFFSET)) (top . (+ YOFFSET)) > + | (width . WIDTH) (height . HEIGHT)). > + | > + workarea | Position and size of the workarea in the form of > + | ((left . (+ XOFFSET)) (top . (+ YOFFSET)) > + | (width . WIDTH) (height . HEIGHT)). > + | > + mm-size | Width and height in millimeters in the form of > + | ((width . WIDTH) (height . HEIGHT)). > + | > + frames | List of frames belonging to the physical monitor. > +=20 > + where XOFFSET, YOFFSET, WIDTH, and HEIGHT are integers. A frame > + belongs to a monitor when either the largest area of the frame = resides > + in the monitor, or the monitor is the closest to the frame if the > + frame does not intersect any monitors. Every non-tip frame = (including > + invisible one) in a graphical display belongs to exactly one = monitor. > +=20 > + 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. = */) > + (Lisp_Object terminal) > + { > + struct x_display_info *dpyinfo =3D check_x_display_info = (terminal); > + Lisp_Object attributes_list =3D Qnil, rest, frame; > +=20 > + #ifdef USE_GTK > + float mm_width_per_pixel, mm_height_per_pixel; > + GdkDisplay *gdpy; > + GdkScreen *gscreen; > + gint primary_monitor =3D 0, n_monitors, i; > + Lisp_Object primary_monitor_attributes =3D Qnil; > + Lisp_Object monitor_frames; > +=20 > + block_input (); > + mm_width_per_pixel =3D ((float) WidthMMOfScreen (dpyinfo->screen) > + / x_display_pixel_width (dpyinfo)); > + mm_height_per_pixel =3D ((float) HeightMMOfScreen = (dpyinfo->screen) > + / x_display_pixel_height (dpyinfo)); > + gdpy =3D gdk_x11_lookup_xdisplay (dpyinfo->display); > + gscreen =3D gdk_display_get_default_screen (gdpy); > + #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >=3D 20 > + primary_monitor =3D gdk_screen_get_primary_monitor (gscreen); > + #endif > + n_monitors =3D gdk_screen_get_n_monitors (gscreen); > + monitor_frames =3D Fmake_vector (make_number (n_monitors), Qnil); > + FOR_EACH_FRAME (rest, frame) > + { > + struct frame *f =3D XFRAME (frame); > +=20 > + if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) =3D=3D dpyinfo > + && !EQ (frame, tip_frame)) > + { > + GdkWindow *gwin =3D gtk_widget_get_window (FRAME_GTK_WIDGET = (f)); > +=20 > + i =3D gdk_screen_get_monitor_at_window (gscreen, gwin); > + ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, = i))); > + } > + } > +=20 > + i =3D n_monitors; > + while (i-- > 0) > + { > + Lisp_Object geometry, workarea, attributes =3D Qnil; > + gint width_mm =3D -1, height_mm =3D -1; > + GdkRectangle rec; > +=20 > + attributes =3D Fcons (Fcons (Qframes, AREF (monitor_frames, = i)), > + attributes); > +=20 > + gdk_screen_get_monitor_geometry (gscreen, i, &rec); > + geometry =3D x_create_geometry_alist (rec.x, rec.y, rec.width, = rec.height); > +=20 > + #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >=3D 14 > + width_mm =3D gdk_screen_get_monitor_width_mm (gscreen, i); > + height_mm =3D gdk_screen_get_monitor_height_mm (gscreen, i); > + #endif > + if (width_mm < 0) > + width_mm =3D rec.width * mm_width_per_pixel + 0.5; > + if (height_mm < 0) > + height_mm =3D rec.height * mm_height_per_pixel + 0.5; > + attributes =3D Fcons (Fcons (Qmm_size, > + x_create_size_alist (width_mm, = height_mm)), > + attributes); > +=20 > + #if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION =3D=3D 3 && = GTK_MINOR_VERSION >=3D 4) > + gdk_screen_get_monitor_workarea (gscreen, i, &rec); > + workarea =3D x_create_geometry_alist (rec.x, rec.y, rec.width, = rec.height); > + #else > + /* Emulate the behavior of GTK+ 3.4. */ > + { > + XRectangle workarea_r; > +=20 > + workarea =3D Qnil; > + if (i =3D=3D primary_monitor && x_get_net_workarea (dpyinfo, = &workarea_r)) > + { > + GdkRectangle work; > +=20 > + work.x =3D workarea_r.x; > + work.y =3D workarea_r.y; > + work.width =3D workarea_r.width; > + work.height =3D workarea_r.height; > + if (gdk_rectangle_intersect (&rec, &work, &work)) > + workarea =3D x_create_geometry_alist (work.x, work.y, > + work.width, = work.height); > + } > + if (NILP (workarea)) > + workarea =3D geometry; > + } > + #endif > + attributes =3D Fcons (Fcons (Qworkarea, workarea), = attributes); > +=20 > + attributes =3D Fcons (Fcons (Qgeometry, geometry), = attributes); > +=20 > + if (i =3D=3D primary_monitor) > + primary_monitor_attributes =3D attributes; > + else > + attributes_list =3D Fcons (attributes, attributes_list); > + } > +=20 > + if (!NILP (primary_monitor_attributes)) > + attributes_list =3D Fcons (primary_monitor_attributes, = attributes_list); > + unblock_input (); > + #else /* not USE_GTK */ > + /* Fallback: treat (possibly) multiple physical monitors as if = they > + formed a single monitor as a whole. This should provide a > + consistent result at least on single monitor environments. */ > + Lisp_Object geometry, workarea, frames, attributes =3D Qnil; > + int width_mm, height_mm; > + XRectangle workarea_r; > +=20 > + block_input (); > + frames =3D Qnil; > + FOR_EACH_FRAME (rest, frame) > + { > + struct frame *f =3D XFRAME (frame); > +=20 > + if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) =3D=3D dpyinfo > + && !EQ (frame, tip_frame)) > + frames =3D Fcons (frame, frames); > + } > + attributes =3D Fcons (Fcons (Qframes, frames), attributes); > +=20 > + width_mm =3D WidthMMOfScreen (dpyinfo->screen); > + height_mm =3D HeightMMOfScreen (dpyinfo->screen); > + attributes =3D Fcons (Fcons (Qmm_size, > + x_create_size_alist (width_mm, height_mm)), > + attributes); > +=20 > + geometry =3D x_create_geometry_alist (0, 0, x_display_pixel_width = (dpyinfo), > + x_display_pixel_height (dpyinfo)); > +=20 > + if (x_get_net_workarea (dpyinfo, &workarea_r)) > + workarea =3D x_create_geometry_alist (workarea_r.x, = workarea_r.y, > + workarea_r.width, = workarea_r.height); > + else > + workarea =3D geometry; > + attributes =3D Fcons (Fcons (Qworkarea, workarea), attributes); > +=20 > + attributes =3D Fcons (Fcons (Qgeometry, geometry), attributes); > +=20 > + attributes_list =3D list1 (attributes); > + unblock_input (); > + #endif /* not USE_GTK */ > +=20 > + return attributes_list; > + } > +=20 > =0C > int > x_pixel_width (register struct frame *f) > *************** > *** 5701,5706 **** > --- 5972,5981 ---- > DEFSYM (Qundefined_color, "undefined-color"); > DEFSYM (Qcompound_text, "compound-text"); > DEFSYM (Qcancel_timer, "cancel-timer"); > + DEFSYM (Qgeometry, "geometry"); > + DEFSYM (Qworkarea, "workarea"); > + DEFSYM (Qmm_size, "mm-size"); > + DEFSYM (Qframes, "frames"); > DEFSYM (Qfont_param, "font-parameter"); > /* This is the end of symbol initialization. */ >=20 > *************** > *** 5864,5869 **** > --- 6139,6145 ---- > defsubr (&Sx_display_visual_class); > defsubr (&Sx_display_backing_store); > defsubr (&Sx_display_save_under); > + defsubr (&Sx_display_monitor_attributes_list); > defsubr (&Sx_wm_set_size_hint); > defsubr (&Sx_create_frame); > defsubr (&Sx_open_connection); >=20 > =3D=3D=3D modified file 'src/xterm.c' > *** src/xterm.c 2013-03-25 17:58:35 +0000 > --- src/xterm.c 2013-04-26 00:15:04 +0000 > *************** > *** 10251,10256 **** > --- 10251,10258 ---- > { "_NET_WM_WINDOW_OPACITY", = &dpyinfo->Xatom_net_wm_window_opacity }, > { "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window }, > { "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents }, > + { "_NET_CURRENT_DESKTOP", &dpyinfo->Xatom_net_current_desktop = }, > + { "_NET_WORKAREA", &dpyinfo->Xatom_net_workarea }, > /* Session management */ > { "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID }, > { "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop }, >=20 > =3D=3D=3D modified file 'src/xterm.h' > *** src/xterm.h 2013-04-07 04:41:19 +0000 > --- src/xterm.h 2013-04-26 00:15:24 +0000 > *************** > *** 346,352 **** > Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, > Xatom_net_wm_state_maximized_horz, = Xatom_net_wm_state_maximized_vert, > Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden, > ! Xatom_net_frame_extents; >=20 > /* XSettings atoms and windows. */ > Atom Xatom_xsettings_sel, Xatom_xsettings_prop, = Xatom_xsettings_mgr; > --- 346,353 ---- > Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, > Xatom_net_wm_state_maximized_horz, = Xatom_net_wm_state_maximized_vert, > Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden, > ! Xatom_net_frame_extents, > ! Xatom_net_current_desktop, Xatom_net_workarea; >=20 > /* XSettings atoms and windows. */ > Atom Xatom_xsettings_sel, Xatom_xsettings_prop, = Xatom_xsettings_mgr; >=20