Replace Xclimsg() with Xclimsgx() to be screen aware with X11 messages.
authorAndriy Grytsenko <andrej@rep.kiev.ua>
Thu, 17 Nov 2016 22:54:18 +0000 (00:54 +0200)
committerAndriy Grytsenko <andrej@rep.kiev.ua>
Thu, 17 Nov 2016 23:07:11 +0000 (01:07 +0200)
ChangeLog
TODO
plugins/deskno/deskno.c
plugins/task-button.c
plugins/wincmd.c
src/gtk-run.c
src/misc.c
src/misc.h
src/panel.c
src/private.h

index 0ff202d..d8ad40f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -74,6 +74,7 @@
 * Removed unwanted conversions with energy for charge in 'batt' plugin
     which will mess up tooltip indications, and may make rate/percentage
     calculations invalid.
+* Replaced Xclimsg() with Xclimsgx() to be screen aware with X11 message.
 
 0.8.2
 -------------------------------------------------------------------------
diff --git a/TODO b/TODO
index d22ca82..3979f93 100644 (file)
--- a/TODO
+++ b/TODO
@@ -23,3 +23,4 @@
 * 'usb-unmount' plugin
 * in 0.10.0 fix "GTK2+" string to just "GTK+"
 * show/hide Raise/Restore/Maximize/Iconify in button menu depending on task
+* get rid of GDK_ROOT_WINDOW() and gdk_get_default_root_window()
index 6f614e1..74ef750 100644 (file)
@@ -99,11 +99,12 @@ static gboolean deskno_button_press_event(GtkWidget * widget, GdkEventButton * e
     int desknum = get_net_current_desktop();
     int desks = get_net_number_of_desktops();
     int newdesk = desknum + 1;
+    Screen *xscreen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(widget));
     if (newdesk >= desks)
         newdesk = 0;
 
     /* Ask the window manager to make the new desktop current. */
-    Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, newdesk, 0, 0, 0, 0);
+    Xclimsgx(xscreen, RootWindowOfScreen(xscreen), a_NET_CURRENT_DESKTOP, newdesk, 0, 0, 0, 0);
     return TRUE;
 }
 
@@ -112,6 +113,7 @@ static gboolean deskno_scrolled(GtkWidget * p, GdkEventScroll * ev, DesknoPlugin
 {
     int desknum = get_net_current_desktop();
     int desks = get_net_number_of_desktops();
+    Screen *xscreen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(p));
 
     switch (ev->direction) {
         case GDK_SCROLL_DOWN:
@@ -127,7 +129,7 @@ static gboolean deskno_scrolled(GtkWidget * p, GdkEventScroll * ev, DesknoPlugin
     if (desknum < 0 || desknum >= desks)
         return TRUE;
 
-    Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, desknum, 0, 0, 0, 0);
+    Xclimsgx(xscreen, RootWindowOfScreen(xscreen), a_NET_CURRENT_DESKTOP, desknum, 0, 0, 0, 0);
     return TRUE;
 }
 
index 69965bb..74359ee 100644 (file)
@@ -279,40 +279,21 @@ static void menu_raise_window(GtkWidget * widget, GtkWidget * taskbar)
 {
     TaskButton *tb = get_menu_task_button(taskbar);
     TaskDetails *tk = task_details_lookup(tb, tb->menu_target);
+    Screen *screen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(widget));
 
     if ((tk->desktop != ALL_WORKSPACES) && (tk->desktop != tb->desktop))
-        Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, tk->desktop, 0, 0, 0, 0);
-    XMapRaised(GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(widget)), tk->win);
+        Xclimsgx(screen, RootWindowOfScreen(screen), a_NET_CURRENT_DESKTOP,
+                 tk->desktop, 0, 0, 0, 0);
+    XMapRaised(DisplayOfScreen(screen), tk->win);
 }
 
 /* Handler for maximize/unmaximize. Taken from WNCK */
 static void do_maximize(GtkWidget *widget, Window xwindow, gboolean set)
 {
-    Screen  *screen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(widget));
-    Display *display = DisplayOfScreen(screen);
-    Window   root = RootWindowOfScreen(screen);
-    XEvent   xev;
-
-    xev.xclient.type = ClientMessage;
-    xev.xclient.serial = 0;
-    xev.xclient.send_event = True;
-    xev.xclient.display = display;
-    xev.xclient.window = xwindow;
-    xev.xclient.message_type = a_NET_WM_STATE;
-    xev.xclient.format = 32;
-    xev.xclient.data.l[0] = set ? a_NET_WM_STATE_ADD : a_NET_WM_STATE_REMOVE;
-    xev.xclient.data.l[1] = a_NET_WM_STATE_MAXIMIZED_VERT;
-    xev.xclient.data.l[2] = a_NET_WM_STATE_MAXIMIZED_HORZ;
-    xev.xclient.data.l[3] = 1; /* application */
-    xev.xclient.data.l[4] = 0;
-
-  //_wnck_error_trap_push (display);
-    XSendEvent(display,
-               root,
-               False,
-               SubstructureRedirectMask | SubstructureNotifyMask,
-               &xev);
-  //_wnck_error_trap_pop (display);
+    Xclimsgx(GDK_SCREEN_XSCREEN(gtk_widget_get_screen(widget)), xwindow,
+             a_NET_WM_STATE, set ? a_NET_WM_STATE_ADD : a_NET_WM_STATE_REMOVE,
+             a_NET_WM_STATE_MAXIMIZED_VERT, a_NET_WM_STATE_MAXIMIZED_HORZ,
+             1 /* application */, 0);
 }
 
 /* Handler for "activate" event on Restore item of right-click menu for task buttons. */
@@ -342,7 +323,8 @@ static void menu_move_to_workspace(GtkWidget * widget, GtkWidget * taskbar)
 {
     TaskButton *tb = get_menu_task_button(taskbar);
     int num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "num"));
-    Xclimsg(tb->menu_target, a_NET_WM_DESKTOP, num, 0, 0, 0, 0);
+    Xclimsgx(GDK_SCREEN_XSCREEN(gtk_widget_get_screen(widget)), tb->menu_target,
+             a_NET_WM_DESKTOP, num, 0, 0, 0, 0);
 }
 
 /* Handler for "activate" event on Close item of right-click menu for task buttons. */
@@ -492,17 +474,20 @@ static GtkWidget *get_task_button_menu(TaskButton *tb, TaskDetails *task)
  * We also switch the active desktop and viewport if needed. */
 static void task_raise_window(TaskButton *tb, TaskDetails *tk, guint32 time)
 {
+#if GTK_CHECK_VERSION(2, 24, 0)
     GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(tb));
-    Display *xdisplay = GDK_DISPLAY_XDISPLAY(display);
+#endif
+    Screen *xscreen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(GTK_WIDGET(tb)));
+    Display *xdisplay = DisplayOfScreen(xscreen);
 
     /* Change desktop if needed. */
     if ((tk->desktop != ALL_WORKSPACES) && (tk->desktop != tb->desktop))
-        Xclimsg(GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, tk->desktop, 0, 0, 0, 0);
+        Xclimsgx(xscreen, RootWindowOfScreen(xscreen), a_NET_CURRENT_DESKTOP, tk->desktop, 0, 0, 0, 0);
 
     /* Raise the window.  We can use NET_ACTIVE_WINDOW if the window manager supports it.
      * Otherwise, do it the old way with XMapRaised and XSetInputFocus. */
     if (tb->flags.use_net_active)
-        Xclimsg(tk->win, a_NET_ACTIVE_WINDOW, 2, time, 0, 0, 0);
+        Xclimsgx(xscreen, tk->win, a_NET_ACTIVE_WINDOW, 2, time, 0, 0, 0);
     else
     {
 #if GTK_CHECK_VERSION(2, 24, 0)
@@ -526,7 +511,7 @@ static void task_raise_window(TaskButton *tb, TaskDetails *tk, guint32 time)
     /* Change viewport if needed. */
     XWindowAttributes xwa;
     XGetWindowAttributes(xdisplay, tk->win, &xwa);
-    Xclimsg(tk->win, a_NET_DESKTOP_VIEWPORT, xwa.x, xwa.y, 0, 0, 0);
+    Xclimsgx(xscreen, tk->win, a_NET_DESKTOP_VIEWPORT, xwa.x, xwa.y, 0, 0, 0);
 }
 
 /* called when list of windows menu emits signal "selection-done" */
@@ -555,7 +540,8 @@ static gboolean task_button_window_do_release_event(GtkWidget *tb, TaskDetails *
     else if (event->button == 2)
     {
         /* Middle button.  Toggle the shaded state of the window. */
-        Xclimsg(task->win, a_NET_WM_STATE,
+        Xclimsgx(GDK_SCREEN_XSCREEN(gtk_widget_get_screen(tb)),
+                task->win, a_NET_WM_STATE,
                 2,      /* a_NET_WM_STATE_TOGGLE */
                 a_NET_WM_STATE_SHADED,
                 0, 0, 0);
index f0905e1..9b4ae48 100644 (file)
@@ -67,12 +67,13 @@ static void wincmd_adjust_toggle_state(WinCmdPlugin * wc)
 }
 
 /* Execute a window command. */
-static void wincmd_execute(WinCmdPlugin * wc, WindowCommand command)
+static void wincmd_execute(GdkScreen * screen, WinCmdPlugin * wc, WindowCommand command)
 {
     /* Get the list of all windows. */
     int client_count;
-    Window * client_list = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_CLIENT_LIST, XA_WINDOW, &client_count);
-    Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+    Screen * xscreen = GDK_SCREEN_XSCREEN(screen);
+    Window * client_list = get_xaproperty (RootWindowOfScreen(xscreen), a_NET_CLIENT_LIST, XA_WINDOW, &client_count);
+    Display *xdisplay = DisplayOfScreen(xscreen);
     if (client_list != NULL)
     {
         /* Loop over all windows. */
@@ -103,7 +104,7 @@ static void wincmd_execute(WinCmdPlugin * wc, WindowCommand command)
                         break;
 
                     case WC_SHADE:
-                        Xclimsg(client_list[i], a_NET_WM_STATE,
+                        Xclimsgx(xscreen, client_list[i], a_NET_WM_STATE,
                             ((( ! wc->toggle_preference) || ( ! wc->toggle_state)) ? a_NET_WM_STATE_ADD : a_NET_WM_STATE_REMOVE),
                             a_NET_WM_STATE_SHADED, 0, 0, 0);
                         break;
@@ -126,6 +127,7 @@ static gboolean wincmd_button_clicked(GtkWidget * widget, GdkEventButton * event
     if (event->button == 1)
     {
         GdkScreen* screen = gtk_widget_get_screen(widget);
+        Screen *xscreen = GDK_SCREEN_XSCREEN(screen);
         static GdkAtom atom = 0;
         if( G_UNLIKELY(0 == atom) )
             atom = gdk_atom_intern("_NET_SHOWING_DESKTOP", FALSE);
@@ -135,12 +137,12 @@ static gboolean wincmd_button_clicked(GtkWidget * widget, GdkEventButton * event
         if (gdk_x11_screen_supports_net_wm_hint(screen, atom))
         {
             int showing_desktop = ((( ! wc->toggle_preference) || ( ! wc->toggle_state)) ? 1 : 0);
-            Xclimsg(DefaultRootWindow(GDK_DISPLAY_XDISPLAY(gdk_display_get_default())),
+            Xclimsgx(xscreen, RootWindowOfScreen(xscreen),
                     a_NET_SHOWING_DESKTOP, showing_desktop, 0, 0, 0, 0);
             wincmd_adjust_toggle_state(wc);
         }
         else
-            wincmd_execute(wc, WC_ICONIFY);
+            wincmd_execute(screen, wc, WC_ICONIFY);
         return TRUE;
     }
 
@@ -152,7 +154,7 @@ static gboolean wincmd_button_released(GtkWidget * widget, GdkEventButton * even
     /* Middle-click to shade. */
     if (event->button == 2)
     {
-        wincmd_execute(wc, WC_SHADE);
+        wincmd_execute(gtk_widget_get_screen(widget), wc, WC_SHADE);
     }
 
     return FALSE;
index ea1c141..2f7030e 100644 (file)
@@ -361,29 +361,15 @@ static void activate_window(GtkWindow* toplevel_window)
                                           gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
     {
         GdkWindow* window = gtk_widget_get_window(widget);
-        GdkDisplay* display = gtk_widget_get_display(widget);
-        GdkWindow* root = gdk_screen_get_root_window(screen);
 
         /* show the window first */
         gtk_widget_show(widget);
 
         /* then, activate it */
-        XClientMessageEvent xclient;
-        memset(&xclient, 0, sizeof (xclient));
-        xclient.type = ClientMessage;
-        xclient.window = GDK_WINDOW_XID(window);
-        xclient.message_type = gdk_x11_get_xatom_by_name_for_display(display,
-                                                                   "_NET_ACTIVE_WINDOW");
-        xclient.format = 32;
-        xclient.data.l[0] = 2; /* source indication: 2 represents direct user actions. */
-        xclient.data.l[1] = gtk_get_current_event_time();
-        xclient.data.l[2] = None; /* currently active window */
-        xclient.data.l[3] = 0;
-        xclient.data.l[4] = 0;
-
-        XSendEvent(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XID(root), False,
-                  SubstructureRedirectMask|SubstructureNotifyMask,
-                  (XEvent *)&xclient);
+        Xclimsgx(GDK_SCREEN_XSCREEN(screen), GDK_WINDOW_XID(window),
+                 a_NET_ACTIVE_WINDOW, 2, /* source indication: 2 represents direct user actions. */
+                 gtk_get_current_event_time(),
+                 None /* currently active window */, 0, 0);
     } /* if _NET_ACTIVE_WINDOW command is not supported */
     else
         gtk_window_present(toplevel_window);
index bfc16db..7743c5c 100644 (file)
@@ -440,10 +440,14 @@ void resolve_atoms()
 
 
 void
-Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4)
+Xclimsgx(Screen *screen, Window win, Atom type, long l0, long l1, long l2, long l3, long l4)
 {
+    Display *display = DisplayOfScreen(screen);
     XClientMessageEvent xev;
     xev.type = ClientMessage;
+    xev.serial = 0;
+    xev.send_event = True;
+    xev.display = display;
     xev.window = win;
     xev.message_type = type;
     xev.format = 32;
@@ -452,9 +456,18 @@ Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4)
     xev.data.l[2] = l2;
     xev.data.l[3] = l3;
     xev.data.l[4] = l4;
-    XSendEvent(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), GDK_ROOT_WINDOW(), False,
-          (SubstructureNotifyMask | SubstructureRedirectMask),
-          (XEvent *) &xev);
+    // _error_trap_push (display);
+    XSendEvent(display, RootWindowOfScreen(screen), False,
+               (SubstructureNotifyMask | SubstructureRedirectMask),
+               (XEvent *) &xev);
+    // _error_trap_pop (display);
+}
+
+void
+Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4)
+{
+    Xclimsgx(DefaultScreenOfDisplay(GDK_DISPLAY_XDISPLAY(gdk_display_get_default())),
+             win, type, l0, l1, l2, l3, l4);
 }
 
 void
index f158a63..bdca551 100644 (file)
@@ -4,7 +4,7 @@
  *               2008-2009 Fred Chien <fred@lxde.org>
  *               2009 Marty Jack <martyj19@comcast.net>
  *               2011-2013 Henry Gebhardt <hsggebhardt@gmail.com>
- *               2014 Andriy Grytsenko <andrej@rep.kiev.ua>
+ *               2014-2016 Andriy Grytsenko <andrej@rep.kiev.ua>
  *
  * This file is a part of LXPanel project.
  *
@@ -118,7 +118,7 @@ typedef struct {
     unsigned int normal : 1;
 } NetWMWindowType;
 
-void Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4);
+void Xclimsgx(Screen *screen, Window win, Atom type, long l0, long l1, long l2, long l3, long l4);
 void Xclimsgwm(Window win, Atom type, Atom arg);
 void *get_xaproperty (Window win, Atom prop, Atom type, int *nitems);
 char *get_textproperty(Window win, Atom prop);
index b7a496c..502b973 100644 (file)
@@ -469,7 +469,7 @@ static void lxpanel_init(PanelToplevel *self)
 }
 
 /* Allocate and initialize new Panel structure. */
-static LXPanel* panel_allocate(void)
+static LXPanel* panel_allocate(GdkScreen *screen)
 {
     return g_object_new(LX_TYPE_PANEL,
                         "border-width", 0,
@@ -479,6 +479,7 @@ static LXPanel* panel_allocate(void)
                         "title", "panel",
                         "type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
                         "window-position", GTK_WIN_POS_NONE,
+                        "screen", screen,
                         NULL);
 }
 
@@ -1237,13 +1238,12 @@ static char* gen_panel_name( int edge, gint monitor )
 static void panel_popupmenu_create_panel( GtkMenuItem* item, LXPanel* panel )
 {
     gint m, e, monitors;
-    GdkScreen *screen;
-    LXPanel *new_panel = panel_allocate();
+    GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(panel));
+    LXPanel *new_panel = panel_allocate(screen);
     Panel *p = new_panel->priv;
     config_setting_t *global;
 
     /* Allocate the edge. */
-    screen = gtk_widget_get_screen(GTK_WIDGET(panel));
     g_assert(screen);
     monitors = gdk_screen_get_n_monitors(screen);
     /* try to allocate edge on current monitor first */
@@ -1598,7 +1598,8 @@ panel_start_gui(LXPanel *panel, config_setting_t *list)
     Atom state[3];
     XWMHints wmhints;
     gulong val;
-    Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+    Screen *xscreen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(GTK_WIDGET(panel)));
+    Display *xdisplay = DisplayOfScreen(xscreen);
     Panel *p = panel->priv;
     GtkWidget *w = GTK_WIDGET(panel);
     config_setting_t *s;
@@ -1663,7 +1664,7 @@ panel_start_gui(LXPanel *panel, config_setting_t *list)
     /* the settings that should be done after window is mapped */
 
     /* send it to running wm */
-    Xclimsg(p->topxwin, a_NET_WM_DESKTOP, G_MAXULONG, 0, 0, 0, 0);
+    Xclimsgx(xscreen, p->topxwin, a_NET_WM_DESKTOP, G_MAXULONG, 0, 0, 0, 0);
     /* and assign it ourself just for case when wm is not running */
     val = G_MAXULONG;
     XChangeProperty(xdisplay, p->topxwin, a_NET_WM_DESKTOP, XA_CARDINAL, 32,
@@ -1998,7 +1999,7 @@ LXPanel* panel_new( const char* config_file, const char* config_name )
 
     if (G_LIKELY(config_file))
     {
-        panel = panel_allocate();
+        panel = panel_allocate(gdk_screen_get_default());
         panel->priv->name = g_strdup(config_name);
         g_debug("starting panel from file %s",config_file);
         if (!config_read_file(panel->priv->config, config_file) ||
index 50c5614..4883883 100644 (file)
@@ -358,6 +358,8 @@ gboolean lxpanel_launch_app(const char* exec, GList* files, gboolean in_terminal
 
 extern GdkPixbuf* lxpanel_load_icon( const char* name, int width, int height, gboolean use_fallback );
 
+void Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4);
+
 
 /* Extracted from plugin.h */
 struct _Plugin;