From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alex Newsgroups: gmane.emacs.bugs Subject: bug#23568: 25.0.94; Mode line menus appear incorrectly in some monitor configurations Date: Mon, 05 Jun 2017 02:03:45 -0600 Message-ID: <87vaoauahq.fsf@gmail.com> References: <871t50xvm6.fsf@gmail.com> <87y3thjw4i.fsf@gmail.com> <87vaoh1os3.fsf@gmail.com> <592E8C4A.7000104@gmx.at> <87vaoglo72.fsf@gmail.com> <592FA8A5.8060100@gmx.at> <874lvzzbwf.fsf@gmail.com> <87zidrxwhn.fsf@gmail.com> <5931014B.20700@gmx.at> <8737bi97s9.fsf@gmail.com> <59312948.5000907@gmx.at> <87shjhopqs.fsf@gmail.com> <83vaodbmz7.fsf@gnu.org> <87poekev55.fsf@gmail.com> <834lvvbzdr.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1496649928 30324 195.159.176.226 (5 Jun 2017 08:05:28 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 5 Jun 2017 08:05:28 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) Cc: 23568@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Jun 05 10:05:21 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHn0q-0007CL-H7 for geb-bug-gnu-emacs@m.gmane.org; Mon, 05 Jun 2017 10:05:20 +0200 Original-Received: from localhost ([::1]:60198 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHn0p-0004Po-D7 for geb-bug-gnu-emacs@m.gmane.org; Mon, 05 Jun 2017 04:05:19 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42594) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHn0f-0004MJ-Id for bug-gnu-emacs@gnu.org; Mon, 05 Jun 2017 04:05:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dHn0a-0001Sb-LQ for bug-gnu-emacs@gnu.org; Mon, 05 Jun 2017 04:05:09 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:53780) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dHn0a-0001SS-Gd for bug-gnu-emacs@gnu.org; Mon, 05 Jun 2017 04:05:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dHn0Y-0002zK-2v for bug-gnu-emacs@gnu.org; Mon, 05 Jun 2017 04:05:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alex Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 05 Jun 2017 08:05:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 23568 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 23568-submit@debbugs.gnu.org id=B23568.149664984311415 (code B ref 23568); Mon, 05 Jun 2017 08:05:02 +0000 Original-Received: (at 23568) by debbugs.gnu.org; 5 Jun 2017 08:04:03 +0000 Original-Received: from localhost ([127.0.0.1]:56457 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHmza-0002y3-Lb for submit@debbugs.gnu.org; Mon, 05 Jun 2017 04:04:03 -0400 Original-Received: from mail-it0-f68.google.com ([209.85.214.68]:34871) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dHmzY-0002xS-8y for 23568@debbugs.gnu.org; Mon, 05 Jun 2017 04:04:00 -0400 Original-Received: by mail-it0-f68.google.com with SMTP id 67so20910191itx.2 for <23568@debbugs.gnu.org>; Mon, 05 Jun 2017 01:04:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=UhH5vLcGN9OZXMTG7JzSZSeEusg5TU8cKoPNr8KnmII=; b=XTnB06REQoirEeNSWL9cBTAWS79/zidUqDtkipIeaGhJw4XoSxjXL+qoNLTq3Cv1/y y1fsMIMsU+U7a7ObYhdFYtry6bsH2a9e/tNs8VyWUnlO0y1oR+mavdjdAIJWl7x4wV3C cK61E8jKLUSHbMogGpuWwmFrbZsUDtCVGX+gN+FufHaphSAsjLJfbignj0H8tzRFE7G4 KJxVD6gCWHFssgQNxK2z+ppok6MrSG8EW8gybv7DdWntpzcu4knoBsPisMVIXF0XhWM9 y9jH8K8iiLifobq0E8IixQOyKu9xqjadetgzSqG6SQ/hpa/RqV/Z6FOb/qIEAagQCamk 427A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=UhH5vLcGN9OZXMTG7JzSZSeEusg5TU8cKoPNr8KnmII=; b=QIfQIpG6i5FTKfrhEmUSrw6ELdqCwsGGlFxOBpqEOI/m694C7CQVWGe4sYHidTAsAn 9OfbzToUSTcbOnnKfYoALktVf978DvSESLj17AKGMEvQp6vXmhnJQJNRb6YktUbmrgQT 2UNQdIgM+KoiMXdKSRr9lr0xhdBPkbLbksTYNrh5D+ikedhXbFZ/UVm8VrpBAJwDMBCY 8gtdh+/lqPnAMQ3FQDPgYJeHYxoaaa1MpQhVcMrBwOe9nIv6p2l0VlvMyyBznmfuIgZE h6/TDhwjiLNCXPP2/jkdnl7L8qCBoH79GzUK/uylFzT39WtfprhtAtgtTdYKt9Ja3Iw3 4RUQ== X-Gm-Message-State: AODbwcBtSzIK0xR4KFSJP8WJDhMdvdI0K4xg9s4g+EflnoL4XnWNj/3Y HxQsXFdCi/5A2mj1 X-Received: by 10.36.6.16 with SMTP id 16mr10163338itv.60.1496649834220; Mon, 05 Jun 2017 01:03:54 -0700 (PDT) Original-Received: from lylat (S010664777d9cebe3.ss.shawcable.net. [70.64.85.59]) by smtp.gmail.com with ESMTPSA id m133sm171190ioa.19.2017.06.05.01.03.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 05 Jun 2017 01:03:52 -0700 (PDT) In-Reply-To: <834lvvbzdr.fsf@gnu.org> (Eli Zaretskii's message of "Sun, 04 Jun 2017 17:28:48 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:133285 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Alex >> Cc: rudalics@gmx.at, 23568@debbugs.gnu.org >> Date: Sat, 03 Jun 2017 13:19:50 -0600 >> I changed all instances of `display' to `frame'. I'm still not sure on >> the name, though. Perhaps a better prefix would be `physical-monitor-*', >> or just `monitor-*'? >> >> What do you think? > > LGTM, thanks. Just to be clear: you prefer the frame-* prefix? >> The xmenu.c part contains the actual bugfix, while the frame.el part is >> just a partial abstraction for the fix so that other procedures can use >> it (such as compute_tip_xy in xfns.c). >> >> The procedure I'm editing (menu_position_func) is inside an #ifdef >> USE_GTK, and uses x_display_pixel_{height,width} currently. I'm not sure >> if it's useful outside of X currently. >> >> I haven't tested the issue on other systems, but I don't think it's an >> issue in Windows as half of the code came from Windows code according to >> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22549#61. > > Ah, okay. Then maybe just add a comment there saying that the w32 > case is handled elsewhere, perhaps with a pointer to the function > which does that. Actually, it turns out that I used the half of the code that *didn't* come from compute_tip_xy from w32fns.c. I instead put a reference to commit c77ffc8019 in date form in the commit message. I tested it out on a Windows partition and indeed the problem doesn't appear there. >> Here's an updated diff: > > Thanks, it would be nice if you could also provide a ChangeLog-style > commit log message. That'd make the job of pushing the changes much > easier. Right, I just figure that it's easier to save that work until the end until most/all of the design considerations are taken care of. Also, I switched from using the geometry attribute (like c77ffc8019 used) to the workarea attribute as according to the GDK doc[1]: The work area should be considered when positioning menus and similar popups, to avoid placing them below panels, docks or other desktop components. I've attached a patch below. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Fix-the-placement-of-GTK-menus-on-multi-monitor-syst.patch Content-Description: multi-monitor-patch >From 82301e82288298436a568c4968d734df8e77c4d2 Mon Sep 17 00:00:00 2001 From: Alexander Gramiak Date: Mon, 5 Jun 2017 00:55:56 -0600 Subject: [PATCH] Fix the placement of GTK menus on multi-monitor systems. menu_position_func did not properly use the current monitor's resolution. Also see commit '2016-02-06 22:12:53 +0100'. * lisp/frame.el (frame-monitor-attribute, frame-monitor-geometry) (frame-monitor-workarea): New functions. * src/xmenu.c (menu_position_func): Take into account the workarea of the monitor that contains the mouse (Bug#23568). --- lisp/frame.el | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xmenu.c | 46 +++++++++++++++++++++++++++++++++------ 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/lisp/frame.el b/lisp/frame.el index 02871e0551..d0ac29694c 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1498,6 +1498,75 @@ frame-monitor-attributes for frames = (cdr (assq 'frames attributes)) if (memq frame frames) return attributes)) +(defun frame-monitor-attribute (attribute &optional frame x y) + "Return the value of the ATTRIBUTE of the current monitor. +If FRAME is omitted or nil, use currently selected frame. + +By default, the current monitor is said to be the physical +monitor dominating FRAME. A frame is dominated by a physical +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 physical monitors. + +If X and Y are both numbers, then ignore the value of FRAME; the +current monitor is determined to be the physical monitor that +contains the pixel coordinate (X, Y). + +See `display-monitor-attributes-list' for the list of attribute +keys and their meanings." + (if (and (numberp x) + (numberp y)) + (cl-loop for monitor in (display-monitor-attributes-list) + for geometry = (alist-get 'geometry monitor) + for min-x = (pop geometry) + for min-y = (pop geometry) + for max-x = (+ min-x (pop geometry)) + for max-y = (+ min-y (car geometry)) + when (and (<= min-x x) + (< x max-x) + (<= min-y y) + (< y max-y)) + return (alist-get attribute monitor)) + (alist-get attribute (frame-monitor-attributes frame)))) + +(defun frame-monitor-geometry (&optional frame x y) + "Return the geometry of the current monitor. +FRAME can be a frame name, a terminal name, or a frame. +If FRAME is omitted or nil, use the currently selected frame. + +By default, the current monitor is said to be the physical +monitor dominating FRAME. A frame is dominated by a physical +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 physical monitors. + +If X and Y are both numbers, then ignore the value of FRAME; the +current monitor is determined to be the physical monitor that +contains the pixel coordinate (X, Y). + +See `display-monitor-attributes-list' for information on the +geometry attribute." + (frame-monitor-attribute 'geometry frame x y)) + +(defun frame-monitor-workarea (&optional frame x y) + "Return the workarea of the current monitor. +FRAME can be a frame name, a terminal name, or a frame. +If FRAME is omitted or nil, use currently selected frame. + +By default, the current monitor is said to be the physical +monitor dominating FRAME. A frame is dominated by a physical +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 physical monitors. + +If X and Y are both numbers, then ignore the value of FRAME; the +current monitor is determined to be the physical monitor that +contains the pixel coordinate (X, Y). + +See `display-monitor-attributes-list' for information on the +workarea attribute." + (frame-monitor-attribute 'workarea frame x y)) + (declare-function x-frame-list-z-order "xfns.c" (&optional display)) (declare-function w32-frame-list-z-order "w32fns.c" (&optional display)) (declare-function ns-frame-list-z-order "nsfns.m" (&optional display)) diff --git a/src/xmenu.c b/src/xmenu.c index 2805249164..6c8a0c506c 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1160,9 +1160,37 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer { struct next_popup_x_y *data = user_data; GtkRequisition req; - struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (data->f); - int disp_width = x_display_pixel_width (dpyinfo); - int disp_height = x_display_pixel_height (dpyinfo); + int max_x = -1; + int max_y = -1; + + Lisp_Object frame, workarea; + + XSETFRAME (frame, data->f); + + /* TODO: Get the monitor workarea directly without calculating other + items in x-display-monitor-attributes-list. */ + workarea = call3 (Qframe_monitor_workarea, + Qnil, + make_number (data->x), + make_number (data->y)); + + if (CONSP (workarea)) + { + int min_x, min_y; + + min_x = XINT (XCAR (workarea)); + min_y = XINT (Fnth (make_number (1), workarea)); + max_x = min_x + XINT (Fnth (make_number (2), workarea)); + max_y = min_y + XINT (Fnth (make_number (3), workarea)); + } + + if (max_x < 0 || max_y < 0) + { + struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (data->f); + + max_x = x_display_pixel_width (dpyinfo); + max_y = x_display_pixel_height (dpyinfo); + } *x = data->x; *y = data->y; @@ -1170,10 +1198,10 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer /* Check if there is room for the menu. If not, adjust x/y so that the menu is fully visible. */ gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &req); - if (data->x + req.width > disp_width) - *x -= data->x + req.width - disp_width; - if (data->y + req.height > disp_height) - *y -= data->y + req.height - disp_height; + if (data->x + req.width > max_x) + *x -= data->x + req.width - max_x; + if (data->y + req.height > max_y) + *y -= data->y + req.height - max_y; } static void @@ -2361,6 +2389,10 @@ syms_of_xmenu (void) DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); defsubr (&Smenu_or_popup_active_p); +#ifdef USE_GTK + DEFSYM (Qframe_monitor_workarea, "frame-monitor-workarea"); +#endif + #if defined (USE_GTK) || defined (USE_X_TOOLKIT) defsubr (&Sx_menu_bar_open_internal); Ffset (intern_c_string ("accelerate-menu"), -- 2.11.0 --=-=-= Content-Type: text/plain Footnotes: [1] https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen-get-monitor-workarea --=-=-=--