summaryrefslogtreecommitdiff
path: root/mate-panel/panel-util.c
diff options
context:
space:
mode:
authorSamuel Thibault <[email protected]>2018-08-30 18:11:29 +0200
committerColomban Wendling <[email protected]>2018-10-17 18:12:37 +0200
commitcdaf08f254981d920918fcfdb1aa356dfdf66306 (patch)
tree03acfd5226bdf7adbe1df74372364f0e4794214e /mate-panel/panel-util.c
parentd9dcf9c2166b24677994ff1efe938e16c33c4b6c (diff)
downloadmate-panel-cdaf08f254981d920918fcfdb1aa356dfdf66306.tar.bz2
mate-panel-cdaf08f254981d920918fcfdb1aa356dfdf66306.tar.xz
menu-bar: transfer focus correctly on alt-F1
The background is in https://gitlab.gnome.org/GNOME/gtk/issues/85 . One of the conclusions, in https://gitlab.gnome.org/GNOME/gtk/issues/85#note_264804 , is that mate-panel needs to properly transfer focus on alt-F1 keyboard shortcut. It used to work only by luck before, only because gtk used to deactivate itself during a keyboard grab. But as discussed in https://gitlab.gnome.org/GNOME/gtk/issues/85 that behavior poses accessibility feedback issues, is not coherent, and keyboard grab feedback will not be available in wayland anyway. Thus @ebassi saying in https://gitlab.gnome.org/GNOME/gtk/issues/85#note_264804 that not transferring focus properly is the actual bug. This change explictly switches to the menu bar after saving which X Window had the focus, and on menu bar deactivation restores focus to that X Window. Fixes #851 This a backport of commit f0f4c5e1217eefd46edf9f98633fb32967c67461.
Diffstat (limited to 'mate-panel/panel-util.c')
-rw-r--r--mate-panel/panel-util.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/mate-panel/panel-util.c b/mate-panel/panel-util.c
index f9832473..a6b77dd1 100644
--- a/mate-panel/panel-util.c
+++ b/mate-panel/panel-util.c
@@ -23,11 +23,15 @@
#include <unistd.h>
#include <sys/types.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdkx.h>
#define MATE_DESKTOP_USE_UNSTABLE_API
#include <libmate-desktop/mate-desktop-utils.h>
@@ -47,6 +51,8 @@
#include "panel-icon-names.h"
#include "panel-lockdown.h"
+static Atom _net_active_window = None;
+
char *
panel_util_make_exec_uri_for_desktop (const char *exec)
{
@@ -1239,3 +1245,89 @@ panel_util_get_file_optional_homedir (const char *location)
return file;
}
+
+static void panel_menu_bar_get_net_active_window(Display *xdisplay)
+{
+ if (_net_active_window == None)
+ _net_active_window = XInternAtom (xdisplay,
+ "_NET_ACTIVE_WINDOW",
+ False);
+}
+
+Window panel_util_get_current_active_window (GtkWidget *toplevel)
+{
+ GdkScreen *screen;
+ GdkDisplay *display;
+ GdkWindow *root;
+ Display *xdisplay;
+ Window xroot;
+
+ Window res = None;
+
+ Atom return_type;
+ int return_format;
+ unsigned long n;
+ unsigned long bytes;
+ unsigned char *prop = NULL;
+
+ screen = gtk_window_get_screen (GTK_WINDOW(toplevel));
+ display = gdk_screen_get_display (screen);
+ root = gdk_screen_get_root_window (screen);
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ xroot = GDK_WINDOW_XID (root);
+
+ panel_menu_bar_get_net_active_window (xdisplay);
+ if (_net_active_window != None
+ && XGetWindowProperty (xdisplay, xroot, _net_active_window, 0, 1,
+ False, XA_WINDOW, &return_type, &return_format,
+ &n, &bytes, &prop) == Success)
+ {
+ if ((return_type == XA_WINDOW) && (return_format == 32) &&
+ (n == 1) && (prop)) {
+ res = *(Window *)prop;
+ }
+
+ if (prop)
+ XFree (prop);
+
+ }
+ return res;
+}
+
+void panel_util_set_current_active_window (GtkWidget *toplevel, Window window)
+{
+ GdkScreen *screen;
+ GdkDisplay *display;
+ GdkWindow *root;
+ Display *xdisplay;
+ Window xroot;
+ XEvent xev;
+
+ screen = gtk_window_get_screen (GTK_WINDOW(toplevel));
+ display = gdk_screen_get_display (screen);
+ root = gdk_screen_get_root_window (screen);
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ xroot = GDK_WINDOW_XID (root);
+
+ panel_menu_bar_get_net_active_window (xdisplay);
+ if (_net_active_window == None)
+ return;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = window;
+ xev.xclient.message_type = _net_active_window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 2; /* requestor type; we're not an app */
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = None; /* our currently active window */
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (xdisplay, xroot, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}