[Xfce4-commits] <xfwm4:master> Update mouse cursor theme and size dynamically (Bug #6854) Initially based on patch submitted by Matthew Rahtz <chiizufish at gmail.com> in bug #6854

Olivier Fourdan noreply at xfce.org
Wed Oct 19 21:28:01 CEST 2011


Updating branch refs/heads/master
         to 7eff3d69403059aa184310a0f231920b67c3b8e6 (commit)
       from 33d41a823b2f5fabf458af6f6513d34d3ce86327 (commit)

commit 7eff3d69403059aa184310a0f231920b67c3b8e6
Author: Olivier Fourdan <fourdan at xfce.org>
Date:   Wed Oct 19 21:23:56 2011 +0200

    Update mouse cursor theme and size dynamically (Bug #6854)
    Initially based on patch submitted by Matthew Rahtz <chiizufish at gmail.com> in bug #6854

 src/client.c   |   44 ++++++++++++++++++++++++++---
 src/client.h   |    2 +
 src/display.c  |   84 ++++++++++++++++++++++++++++++++------------------------
 src/display.h  |    2 +
 src/events.c   |   73 +++++++++++++++++++++++++++++++++++++-----------
 src/events.h   |    4 +-
 src/main.c     |    6 ++--
 src/mywindow.c |   18 ++++++++---
 src/mywindow.h |    2 +
 9 files changed, 167 insertions(+), 68 deletions(-)

diff --git a/src/client.c b/src/client.c
index 175e984..3a9218f 100644
--- a/src/client.c
+++ b/src/client.c
@@ -2595,8 +2595,6 @@ clientEnterContextMenuState (Client * c)
 void
 clientSetLayer (Client * c, guint l)
 {
-    ScreenInfo *screen_info;
-    DisplayInfo *display_info;
     GList *list_of_windows = NULL;
     GList *list = NULL;
     Client *c2 = NULL;
@@ -2604,9 +2602,6 @@ clientSetLayer (Client * c, guint l)
     g_return_if_fail (c != NULL);
     TRACE ("entering clientSetLayer for \"%s\" (0x%lx) on layer %d", c->name, c->window, l);
 
-    screen_info = c->screen_info;
-    display_info = screen_info->display_info;
-
     list_of_windows = clientListTransientOrModal (c);
     for (list = list_of_windows; list; list = g_list_next (list))
     {
@@ -3404,6 +3399,45 @@ clientScreenResize(ScreenInfo *screen_info, gboolean fully_visible)
     g_list_free (list_of_windows);
 }
 
+void
+clientUpdateCursor (Client *c)
+{
+    ScreenInfo *screen_info;
+    DisplayInfo *display_info;
+    guint i;
+
+    g_return_if_fail (c != NULL);
+
+    screen_info = c->screen_info;
+    display_info = screen_info->display_info;
+
+    for (i = 0; i <= SIDE_TOP; i++)
+    {
+        xfwmWindowSetCursor (&c->sides[i],
+            myDisplayGetCursorResize(display_info, CORNER_COUNT + i));
+    }
+
+    for (i = 0; i < CORNER_COUNT; i++)
+    {
+        xfwmWindowSetCursor (&c->corners[i],
+            myDisplayGetCursorResize(display_info, i));
+    }
+}
+
+void
+clientUpdateAllCursor (ScreenInfo *screen_info)
+{
+    Client *c;
+    guint i;
+
+    g_return_if_fail (screen_info != NULL);
+
+    for (c = screen_info->clients, i = 0; i < screen_info->client_count; c = c->next, ++i)
+    {
+        clientUpdateCursor (c);
+    }
+}
+
 static eventFilterStatus
 clientButtonPressEventFilter (XEvent * xevent, gpointer data)
 {
diff --git a/src/client.h b/src/client.h
index a5ef5ff..9e5aa41 100644
--- a/src/client.h
+++ b/src/client.h
@@ -428,6 +428,8 @@ void                     clientSetOpacity                       (Client *,
                                                                  guint, guint);
 void                     clientIncOpacity                       (Client *);
 void                     clientDecOpacity                       (Client *);
+void                     clientUpdateCursor                     (Client *);
+void                     clientUpdateAllCursor                  (ScreenInfo *);
 void                     clientScreenResize                     (ScreenInfo *,
                                                                  gboolean);
 void                     clientButtonPress                      (Client *,
diff --git a/src/display.c b/src/display.c
index cfe2f85..4234e29 100644
--- a/src/display.c
+++ b/src/display.c
@@ -300,28 +300,7 @@ myDisplayInit (GdkDisplay *gdisplay)
     display->have_xrandr = FALSE;
 #endif /* HAVE_RANDR */
 
-    display->root_cursor =
-        XCreateFontCursor (display->dpy, CURSOR_ROOT);
-    display->move_cursor =
-        XCreateFontCursor (display->dpy, CURSOR_MOVE);
-    display->busy_cursor =
-        cursorCreateSpinning (display->dpy);
-    display->resize_cursor[CORNER_TOP_LEFT] =
-        XCreateFontCursor (display->dpy, XC_top_left_corner);
-    display->resize_cursor[CORNER_TOP_RIGHT] =
-        XCreateFontCursor (display->dpy, XC_top_right_corner);
-    display->resize_cursor[CORNER_BOTTOM_LEFT] =
-        XCreateFontCursor (display->dpy, XC_bottom_left_corner);
-    display->resize_cursor[CORNER_BOTTOM_RIGHT] =
-        XCreateFontCursor (display->dpy, XC_bottom_right_corner);
-    display->resize_cursor[CORNER_COUNT + SIDE_LEFT] =
-        XCreateFontCursor (display->dpy, XC_left_side);
-    display->resize_cursor[CORNER_COUNT + SIDE_RIGHT] =
-        XCreateFontCursor (display->dpy, XC_right_side);
-    display->resize_cursor[CORNER_COUNT + SIDE_TOP] =
-        XCreateFontCursor (display->dpy, XC_top_side);
-    display->resize_cursor[CORNER_COUNT + SIDE_BOTTOM] =
-        XCreateFontCursor (display->dpy, XC_bottom_side);
+    myDisplayCreateCursor (display);
 
     myDisplayCreateTimestampWin (display);
 
@@ -349,14 +328,7 @@ myDisplayInit (GdkDisplay *gdisplay)
 DisplayInfo *
 myDisplayClose (DisplayInfo *display)
 {
-    int i;
-
-    XFreeCursor (display->dpy, display->busy_cursor);
-    display->busy_cursor = None;
-    XFreeCursor (display->dpy, display->move_cursor);
-    display->move_cursor = None;
-    XFreeCursor (display->dpy, display->root_cursor);
-    display->root_cursor = None;
+    myDisplayFreeCursor (display);
     XDestroyWindow (display->dpy, display->timestamp_win);
     display->timestamp_win = None;
 
@@ -366,12 +338,6 @@ myDisplayClose (DisplayInfo *display)
         display->hostname = NULL;
     }
 
-    for (i = 0; i < SIDE_COUNT + CORNER_COUNT; i++)
-    {
-        XFreeCursor (display->dpy, display->resize_cursor[i]);
-        display->resize_cursor[i] = None;
-    }
-
     g_slist_free (display->clients);
     display->clients = NULL;
 
@@ -405,6 +371,52 @@ myDisplayHaveRender (DisplayInfo *display)
     return (display->have_render);
 }
 
+void
+myDisplayCreateCursor (DisplayInfo *display)
+{
+    display->root_cursor =
+        XCreateFontCursor (display->dpy, CURSOR_ROOT);
+    display->move_cursor =
+        XCreateFontCursor (display->dpy, CURSOR_MOVE);
+    display->busy_cursor =
+        cursorCreateSpinning (display->dpy);
+    display->resize_cursor[CORNER_TOP_LEFT] =
+        XCreateFontCursor (display->dpy, XC_top_left_corner);
+    display->resize_cursor[CORNER_TOP_RIGHT] =
+        XCreateFontCursor (display->dpy, XC_top_right_corner);
+    display->resize_cursor[CORNER_BOTTOM_LEFT] =
+        XCreateFontCursor (display->dpy, XC_bottom_left_corner);
+    display->resize_cursor[CORNER_BOTTOM_RIGHT] =
+        XCreateFontCursor (display->dpy, XC_bottom_right_corner);
+    display->resize_cursor[CORNER_COUNT + SIDE_LEFT] =
+        XCreateFontCursor (display->dpy, XC_left_side);
+    display->resize_cursor[CORNER_COUNT + SIDE_RIGHT] =
+        XCreateFontCursor (display->dpy, XC_right_side);
+    display->resize_cursor[CORNER_COUNT + SIDE_TOP] =
+        XCreateFontCursor (display->dpy, XC_top_side);
+    display->resize_cursor[CORNER_COUNT + SIDE_BOTTOM] =
+        XCreateFontCursor (display->dpy, XC_bottom_side);
+}
+
+void
+myDisplayFreeCursor (DisplayInfo *display)
+{
+    int i;
+
+    XFreeCursor (display->dpy, display->busy_cursor);
+    display->busy_cursor = None;
+    XFreeCursor (display->dpy, display->move_cursor);
+    display->move_cursor = None;
+    XFreeCursor (display->dpy, display->root_cursor);
+    display->root_cursor = None;
+
+    for (i = 0; i < SIDE_COUNT + CORNER_COUNT; i++)
+    {
+        XFreeCursor (display->dpy, display->resize_cursor[i]);
+        display->resize_cursor[i] = None;
+    }
+}
+
 Cursor
 myDisplayGetCursorBusy (DisplayInfo *display)
 {
diff --git a/src/display.h b/src/display.h
index f2f5dc7..1ad2ef8 100644
--- a/src/display.h
+++ b/src/display.h
@@ -353,6 +353,8 @@ DisplayInfo             *myDisplayClose                         (DisplayInfo *);
 gboolean                 myDisplayHaveShape                     (DisplayInfo *);
 gboolean                 myDisplayHaveShapeInput                (DisplayInfo *);
 gboolean                 myDisplayHaveRender                    (DisplayInfo *);
+void                     myDisplayCreateCursor                  (DisplayInfo *);
+void                     myDisplayFreeCursor                    (DisplayInfo *);
 Cursor                   myDisplayGetCursorBusy                 (DisplayInfo *);
 Cursor                   myDisplayGetCursorMove                 (DisplayInfo *);
 Cursor                   myDisplayGetCursorRoot                 (DisplayInfo *);
diff --git a/src/events.c b/src/events.c
index e0901dc..ddbcdd9 100644
--- a/src/events.c
+++ b/src/events.c
@@ -63,6 +63,7 @@
 #include "events.h"
 #include "event_filter.h"
 #include "xsync.h"
+#include "display.h"
 
 #ifndef CHECK_BUTTON_TIME
 #define CHECK_BUTTON_TIME 0
@@ -2718,6 +2719,26 @@ double_click_distance_cb (GObject * obj, GdkEvent * ev, gpointer data)
     return (TRUE);
 }
 
+static void
+cursor_theme_cb (GObject * obj, GParamSpec * pspec, gpointer data)
+{
+    DisplayInfo * display_info;
+    GSList *list;
+
+    display_info = (DisplayInfo *) data;
+    g_return_if_fail (display_info);
+
+    myDisplayFreeCursor (display_info);
+    myDisplayCreateCursor (display_info);
+
+    for (list = display_info->screens; list; list = g_slist_next (list))
+    {
+        ScreenInfo *screen_info = (ScreenInfo *) list->data;
+        clientUpdateAllCursor (screen_info);
+        XDefineCursor (display_info->dpy, screen_info->xroot, display_info->root_cursor);
+   }
+}
+
 static gboolean
 client_event_cb (GtkWidget * widget, GdkEventClient * ev, gpointer data)
 {
@@ -2739,13 +2760,19 @@ client_event_cb (GtkWidget * widget, GdkEventClient * ev, gpointer data)
 static gboolean
 refresh_font_cb (GObject * obj, GdkEvent * ev, gpointer data)
 {
-    ScreenInfo *screen_info;
+    DisplayInfo * display_info;
+    GSList *list;
 
-    screen_info = (ScreenInfo *) data;
-    g_return_val_if_fail (screen_info, TRUE);
+    display_info = (DisplayInfo *) data;
+    g_return_val_if_fail (display_info, TRUE);
+
+    for (list = display_info->screens; list; list = g_slist_next (list))
+    {
+        ScreenInfo *screen_info = (ScreenInfo *) list->data;
+        myScreenUpdateFontHeight (screen_info);
+        clientUpdateAllFrames (screen_info, UPDATE_FRAME);
+    }
 
-    myScreenUpdateFontHeight (screen_info);
-    clientUpdateAllFrames (screen_info, UPDATE_FRAME);
     return (TRUE);
 }
 
@@ -2849,15 +2876,15 @@ monitors_changed_cb(GdkScreen *gscreen, gpointer data)
 }
 
 void
-initGtkCallbacks (ScreenInfo *screen_info)
+initPerScreenCallbacks (ScreenInfo *screen_info)
 {
-    GtkSettings *settings;
+    g_return_if_fail (screen_info);
 
     screen_info->button_handler_id =
         g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)),
                           "button_press_event", GTK_SIGNAL_FUNC (show_popup_cb), (gpointer) NULL);
     g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), "client_event",
-                      GTK_SIGNAL_FUNC (client_event_cb), (gpointer) (screen_info->display_info));
+                      GTK_SIGNAL_FUNC (client_event_cb), NULL);
     g_signal_connect (G_OBJECT(screen_info->gscr), "size-changed",
                       G_CALLBACK(size_changed_cb),
                       (gpointer) (screen_info));
@@ -2868,28 +2895,40 @@ initGtkCallbacks (ScreenInfo *screen_info)
                           G_CALLBACK(monitors_changed_cb),
                           (gpointer) (screen_info));
     }
+}
+
+void
+initPerDisplayCallbacks (DisplayInfo *display_info)
+{
+    GtkSettings *settings;
+
+    g_return_if_fail (display_info);
 
     settings = gtk_settings_get_default ();
     if (settings)
     {
         g_signal_connect (settings, "notify::gtk-theme-name",
-            G_CALLBACK (set_reload), (gpointer) (screen_info->display_info));
+            G_CALLBACK (set_reload), (gpointer) (display_info));
         g_signal_connect (settings, "notify::gtk-font-name",
-            G_CALLBACK (set_reload), (gpointer) (screen_info->display_info));
+            G_CALLBACK (set_reload), (gpointer) (display_info));
         g_signal_connect (settings, "notify::gtk-double-click-time",
-            G_CALLBACK (double_click_time_cb), (gpointer) (screen_info->display_info));
+            G_CALLBACK (double_click_time_cb), (gpointer) (display_info));
         g_signal_connect (settings, "notify::gtk-double-click-distance",
-            G_CALLBACK (double_click_distance_cb), (gpointer) (screen_info->display_info));
+            G_CALLBACK (double_click_distance_cb), (gpointer) (display_info));
+        g_signal_connect (settings, "notify::gtk-cursor-theme-name",
+            G_CALLBACK (cursor_theme_cb), (gpointer) (display_info));
+        g_signal_connect (settings, "notify::gtk-cursor-theme-size",
+            G_CALLBACK (cursor_theme_cb), (gpointer) (display_info));
         g_signal_connect_after (settings, "notify::gtk-xft-antialias",
-            G_CALLBACK (refresh_font_cb), (gpointer) (screen_info));
+            G_CALLBACK (refresh_font_cb), (gpointer) (display_info));
         g_signal_connect_after (settings, "notify::gtk-xft-dpi",
-            G_CALLBACK (refresh_font_cb), (gpointer) (screen_info));
+            G_CALLBACK (refresh_font_cb), (gpointer) (display_info));
         g_signal_connect_after (settings, "notify::gtk-xft-hinting",
-            G_CALLBACK (refresh_font_cb), (gpointer) (screen_info));
+            G_CALLBACK (refresh_font_cb), (gpointer) (display_info));
         g_signal_connect_after (settings, "notify::gtk-xft-hintstyle",
-            G_CALLBACK (refresh_font_cb), (gpointer) (screen_info));
+            G_CALLBACK (refresh_font_cb), (gpointer) (display_info));
         g_signal_connect_after (settings, "notify::gtk-xft-rgba",
-            G_CALLBACK (refresh_font_cb), (gpointer) (screen_info));
+            G_CALLBACK (refresh_font_cb), (gpointer) (display_info));
     }
 }
 
diff --git a/src/events.h b/src/events.h
index a6b5e63..f497cd9 100644
--- a/src/events.h
+++ b/src/events.h
@@ -40,6 +40,6 @@
 void                     initMenuEventWin                       (void);
 eventFilterStatus        xfwm4_event_filter                     (XEvent *,
                                                                  gpointer);
-void                     initGtkCallbacks                       (ScreenInfo *);
-
+void                     initPerScreenCallbacks                 (ScreenInfo *);
+void                     initPerDisplayCallbacks                (DisplayInfo *);
 #endif /* INC_EVENTS_H */
diff --git a/src/main.c b/src/main.c
index b812310..1eb755b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -390,7 +390,6 @@ static int
 initialize (gint compositor_mode, gboolean replace_wm)
 {
     struct sigaction act;
-    long ws;
     gint i, nscreens;
 
     TRACE ("entering initialize");
@@ -483,7 +482,7 @@ initialize (gint compositor_mode, gboolean replace_wm)
 
         sn_init_display (screen_info);
         myDisplayAddScreen (main_display_info, screen_info);
-        screen_info->current_ws = (int) ws;
+        screen_info->current_ws = 0;
         setUTF8StringHint (main_display_info, screen_info->xfwm4_win, NET_WM_NAME, "Xfwm4");
         setNetSupportedHint (main_display_info, screen_info->xroot, screen_info->xfwm4_win);
         initNetDesktopInfo (main_display_info, screen_info->xroot, screen_info->current_ws,
@@ -494,7 +493,7 @@ initialize (gint compositor_mode, gboolean replace_wm)
 
         clientFrameAll (screen_info);
 
-        initGtkCallbacks (screen_info);
+        initPerScreenCallbacks (screen_info);
 
         XDefineCursor (main_display_info->dpy, screen_info->xroot, myDisplayGetCursorRoot(main_display_info));
     }
@@ -506,6 +505,7 @@ initialize (gint compositor_mode, gboolean replace_wm)
     }
     main_display_info->xfilter = eventFilterInit ((gpointer) main_display_info);
     eventFilterPush (main_display_info->xfilter, xfwm4_event_filter, (gpointer) main_display_info);
+    initPerDisplayCallbacks (main_display_info);
 
     return sessionStart (main_display_info);
 }
diff --git a/src/mywindow.c b/src/mywindow.c
index 4a33373..beb7407 100644
--- a/src/mywindow.c
+++ b/src/mywindow.c
@@ -78,6 +78,17 @@ xfwmWindowInit (xfwmWindow * win)
 }
 
 void
+xfwmWindowSetCursor (xfwmWindow * win, Cursor cursor)
+{
+    g_return_if_fail (win != NULL);
+
+    if ((win->window != None) && (cursor != None))
+    {
+        XDefineCursor (myScreenGetXDisplay (win->screen_info), win->window, cursor);
+    }
+}
+
+void
 xfwmWindowCreate (ScreenInfo * screen_info, Visual *visual, gint depth, Window parent,
                   xfwmWindow * win, long eventmask, Cursor cursor)
 {
@@ -101,11 +112,7 @@ xfwmWindowCreate (ScreenInfo * screen_info, Visual *visual, gint depth, Window p
                                  valuemask, &attributes);
 
     TRACE ("Created XID 0x%lx", win->window);
-    if (cursor != None)
-    {
-        XDefineCursor (myScreenGetXDisplay (screen_info),
-                       win->window, cursor);
-    }
+
     win->map = FALSE;
     win->screen_info = screen_info;
     win->x = 0;
@@ -113,6 +120,7 @@ xfwmWindowCreate (ScreenInfo * screen_info, Visual *visual, gint depth, Window p
     win->width = 1;
     win->height = 1;
     xfwmWindowSetVisual (win, visual, depth);
+    xfwmWindowSetCursor (win, cursor);
 #ifdef HAVE_RENDER
     win->pict_format = XRenderFindVisualFormat (myScreenGetXDisplay (screen_info), win->visual);
 #endif
diff --git a/src/mywindow.h b/src/mywindow.h
index 8de31fb..56ff605 100644
--- a/src/mywindow.h
+++ b/src/mywindow.h
@@ -55,6 +55,8 @@ struct _xfwmWindow
 };
 
 void                     xfwmWindowInit                         (xfwmWindow *);
+void                     xfwmWindowSetCursor                    (xfwmWindow *,
+                                                                 Cursor);
 void                     xfwmWindowCreate                       (ScreenInfo *,
                                                                  Visual *,
                                                                  gint,


More information about the Xfce4-commits mailing list