diff --git a/ChangeLog b/ChangeLog index 5a285634e..3e40acb70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2005-07-11 Matthias Clasen + + React to cursor theme changes: (#308106) + + * src/prefs.h: + * src/prefs.c: Expose the GConf keys for cursor theme + and size as preferences META_PREF_CURSOR_THEME and + META_PREF_CURSOR_SIZE with getters meta_prefs_get_cursor_theme() + and meta_prefs_get_cursor_size(). + + * src/display.c (meta_display_open): Initialize the cursor + theme and size. + + * src/display.h: + * src/display.c (meta_display_set_cursor_theme): New function + to change the cursor theme and update all cursors. + + * src/screen.h + * src/screen.c (meta_screen_update_cursor): New function to + refesh the root cursor of a screen. + + * src/main.c (prefs_changed_callback): Update the cursor + theme when the cursor preferences change. + 2005-06-27 Elijah Newren * configure.in: post-release version bump to 2.10.3 diff --git a/src/display.c b/src/display.c index 358024fd8..99f0d72e7 100644 --- a/src/display.c +++ b/src/display.c @@ -59,6 +59,9 @@ #ifdef HAVE_XKB #include #endif +#ifdef HAVE_XCURSOR +#include +#endif #include #define USE_GDK_DISPLAY @@ -609,7 +612,16 @@ meta_display_open (const char *name) #else /* HAVE_RENDER */ meta_verbose ("Not compiled with Render support\n"); #endif /* !HAVE_RENDER */ - + +#ifdef HAVE_XCURSOR + { + XcursorSetTheme (display->xdisplay, meta_prefs_get_cursor_theme ()); + XcursorSetDefaultSize (display->xdisplay, meta_prefs_get_cursor_size ()); + } +#else /* HAVE_XCURSOR */ + meta_verbose ("Not compiled with Xcursor support\n"); +#endif /* !HAVE_XCURSOR */ + /* Create the leader window here. Set its properties and * use the timestamp from one of the PropertyNotify events * that will follow. @@ -3762,6 +3774,36 @@ meta_display_retheme_all (void) } } +void +meta_display_set_cursor_theme (const char *theme, + int size) +{ +#ifdef HAVE_XCURSOR + GSList *tmp, *tmp2; + + tmp = meta_displays_list (); + while (tmp != NULL) + { + MetaDisplay *display = tmp->data; + + XcursorSetTheme (display->xdisplay, theme); + XcursorSetDefaultSize (display->xdisplay, size); + + tmp2 = display->screens; + while (tmp2 != NULL) + { + MetaScreen *screen = tmp2->data; + + meta_screen_update_cursor (screen); + + tmp2 = tmp2->next; + } + + tmp = tmp->next; + } +#endif +} + static gboolean is_syncing = FALSE; gboolean diff --git a/src/display.h b/src/display.h index bd6f49eab..9c8c2f5e6 100644 --- a/src/display.h +++ b/src/display.h @@ -471,6 +471,9 @@ const char* meta_event_detail_to_string (int d); void meta_display_queue_retheme_all_windows (MetaDisplay *display); void meta_display_retheme_all (void); +void meta_display_set_cursor_theme (const char *theme, + int size); + void meta_display_ping_window (MetaDisplay *display, MetaWindow *window, Time timestamp, diff --git a/src/main.c b/src/main.c index fd4fcb74c..64219ed8d 100644 --- a/src/main.c +++ b/src/main.c @@ -561,6 +561,11 @@ prefs_changed_callback (MetaPreference pref, meta_display_retheme_all (); break; + case META_PREF_CURSOR_THEME: + case META_PREF_CURSOR_SIZE: + meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (), + meta_prefs_get_cursor_size ()); + break; default: /* handled elsewhere or otherwise */ break; diff --git a/src/prefs.c b/src/prefs.c index 4f06e7909..a3b91731f 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -66,6 +66,8 @@ #define KEY_VISUAL_BELL "/apps/metacity/general/visual_bell" #define KEY_AUDIBLE_BELL "/apps/metacity/general/audible_bell" #define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type" +#define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme" +#define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size" #ifdef HAVE_GCONF static GConfClient *default_client = NULL; @@ -90,6 +92,8 @@ static gboolean provide_visual_bell = TRUE; static gboolean bell_is_audible = TRUE; static gboolean reduced_resources = FALSE; static gboolean gnome_accessibility = FALSE; +static char *cursor_theme = NULL; +static int cursor_size = 24; static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID; static MetaButtonLayout button_layout = { @@ -142,6 +146,8 @@ static gboolean update_workspace_name (const char *name, const char *value); static gboolean update_reduced_resources (gboolean value); static gboolean update_gnome_accessibility (gboolean value); +static gboolean update_cursor_theme (const char *value); +static gboolean update_cursor_size (int size); static void change_notify (GConfClient *client, guint cnxn_id, @@ -323,6 +329,11 @@ meta_prefs_init (void) &err); cleanup_error (&err); + gconf_client_add_dir (default_client, "/desktop/gnome/peripherals/mouse", + GCONF_CLIENT_PRELOAD_RECURSIVE, + &err); + cleanup_error (&err); + str_val = gconf_client_get_string (default_client, KEY_MOUSE_BUTTON_MODS, &err); cleanup_error (&err); @@ -426,6 +437,17 @@ meta_prefs_init (void) cleanup_error (&err); update_gnome_accessibility (bool_val); + + str_val = gconf_client_get_string (default_client, KEY_CURSOR_THEME, + &err); + cleanup_error (&err); + update_cursor_theme (str_val); + g_free (str_val); + + int_val = gconf_client_get_int (default_client, KEY_CURSOR_SIZE, + &err); + cleanup_error (&err); + update_cursor_size (int_val); #endif /* HAVE_GCONF */ /* Load keybindings prefs */ @@ -453,6 +475,11 @@ meta_prefs_init (void) NULL, NULL, &err); + gconf_client_notify_add (default_client, "/desktop/gnome/peripherals/mouse", + change_notify, + NULL, + NULL, + &err); cleanup_error (&err); #endif /* HAVE_GCONF */ @@ -846,6 +873,38 @@ change_notify (GConfClient *client, if (update_gnome_accessibility (b)) queue_changed (META_PREF_GNOME_ACCESSIBILITY); } + else if (strcmp (key, KEY_CURSOR_THEME) == 0) + { + const char *str; + + if (value && value->type != GCONF_VALUE_STRING) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_CURSOR_THEME); + goto out; + } + + str = value ? gconf_value_get_string (value) : NULL; + + if (update_cursor_theme (str)) + queue_changed (META_PREF_CURSOR_THEME); + } + else if (strcmp (key, KEY_CURSOR_SIZE) == 0) + { + int d; + + if (value && value->type != GCONF_VALUE_INT) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_CURSOR_SIZE); + goto out; + } + + d = value ? gconf_value_get_int (value) : 24; + + if (update_cursor_size (d)) + queue_changed (META_PREF_CURSOR_SIZE); + } else { meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n", @@ -965,6 +1024,57 @@ meta_prefs_get_theme (void) return current_theme; } +#ifdef HAVE_GCONF +static gboolean +update_cursor_theme (const char *value) +{ + char *old_theme; + gboolean changed; + + old_theme = cursor_theme; + + if (value != NULL && *value) + { + cursor_theme = g_strdup (value); + } + + changed = TRUE; + if ((old_theme && cursor_theme && + strcmp (old_theme, cursor_theme) == 0) || + (old_theme == NULL && cursor_theme == NULL)) + changed = FALSE; + + if (old_theme != cursor_theme) + g_free (old_theme); + + return changed; +} +#endif /* HAVE_GCONF */ + +const char* +meta_prefs_get_cursor_theme (void) +{ + return cursor_theme; +} + +#ifdef HAVE_GCONF +static gboolean +update_cursor_size (int value) +{ + int old = cursor_size; + + cursor_size = value; + + return old != value; +} +#endif + +int +meta_prefs_get_cursor_size (void) +{ + return cursor_size; +} + #ifdef HAVE_GCONF static gboolean update_use_system_font (gboolean value) diff --git a/src/prefs.h b/src/prefs.h index b0d389949..8b437d737 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -48,7 +48,9 @@ typedef enum META_PREF_AUDIBLE_BELL, META_PREF_VISUAL_BELL_TYPE, META_PREF_REDUCED_RESOURCES, - META_PREF_GNOME_ACCESSIBILITY + META_PREF_GNOME_ACCESSIBILITY, + META_PREF_CURSOR_THEME, + META_PREF_CURSOR_SIZE } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -91,6 +93,9 @@ const char* meta_prefs_get_workspace_name (int i); void meta_prefs_change_workspace_name (int i, const char *name); +const char* meta_prefs_get_cursor_theme (void); +int meta_prefs_get_cursor_size (void); + /* Screen bindings */ #define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1" #define META_KEYBINDING_WORKSPACE_2 "switch_to_workspace_2" diff --git a/src/screen.c b/src/screen.c index 30b79aad3..04b453a18 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1152,6 +1152,18 @@ meta_screen_set_cursor (MetaScreen *screen, XFreeCursor (screen->display->xdisplay, xcursor); } +void +meta_screen_update_cursor (MetaScreen *screen) +{ + Cursor xcursor; + + xcursor = meta_display_create_x_cursor (screen->display, + screen->current_cursor); + XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); + XFlush (screen->display->xdisplay); + XFreeCursor (screen->display->xdisplay, xcursor); +} + void meta_screen_ensure_tab_popup (MetaScreen *screen, MetaTabList type) diff --git a/src/screen.h b/src/screen.h index 46bf2208f..9f271d217 100644 --- a/src/screen.h +++ b/src/screen.h @@ -141,6 +141,7 @@ MetaWorkspace* meta_screen_get_workspace_by_index (MetaScreen *screen, void meta_screen_set_cursor (MetaScreen *screen, MetaCursor cursor); +void meta_screen_update_cursor (MetaScreen *screen); void meta_screen_ensure_tab_popup (MetaScreen *screen, MetaTabList type);