From eda5735ce6b52e8cf738077027581bfe2257c3cb Mon Sep 17 00:00:00 2001 From: William Wold Date: Wed, 30 Sep 2020 13:01:32 -0700 Subject: Wncklet applets: don't crash on Wayland --- applets/Makefile.am | 6 +- applets/wncklet/showdesktop.c | 57 ++++++-- applets/wncklet/window-list.c | 151 ++++++++++++++++---- applets/wncklet/window-menu.c | 41 +++++- applets/wncklet/wncklet.c | 24 ++-- applets/wncklet/wncklet.h | 4 +- applets/wncklet/workspace-switcher.c | 267 +++++++++++++++++++++++------------ 7 files changed, 398 insertions(+), 152 deletions(-) (limited to 'applets') diff --git a/applets/Makefile.am b/applets/Makefile.am index bc2488f4..1f040ff9 100644 --- a/applets/Makefile.am +++ b/applets/Makefile.am @@ -1,11 +1,11 @@ SUBDIRS = \ clock \ - fish + fish \ + wncklet if ENABLE_X11 SUBDIRS += \ - notification_area \ - wncklet + notification_area endif -include $(top_srcdir)/git.mk diff --git a/applets/wncklet/showdesktop.c b/applets/wncklet/showdesktop.c index 7999174a..50304db6 100644 --- a/applets/wncklet/showdesktop.c +++ b/applets/wncklet/showdesktop.c @@ -25,17 +25,15 @@ #include #endif -#ifndef HAVE_X11 -#error file should only be built when HAVE_X11 is enabled -#endif - #include #include -#include +#ifdef HAVE_X11 +#include #define WNCK_I_KNOW_THIS_IS_UNSTABLE #include +#endif #include "wncklet.h" #include "showdesktop.h" @@ -55,7 +53,9 @@ typedef struct { GtkOrientation orient; int size; +#ifdef HAVE_X11 WnckScreen* wnck_screen; +#endif // HAVE_X11 guint showing_desktop: 1; guint button_activate; @@ -73,7 +73,7 @@ static void update_button_display(ShowDesktopData* sdd); static void theme_changed_callback(GtkIconTheme* icon_theme, ShowDesktopData* sdd); static void button_toggled_callback(GtkWidget* button, ShowDesktopData* sdd); -static void show_desktop_changed_callback(WnckScreen* screen, ShowDesktopData* sdd); +static void show_desktop_changed_callback(ShowDesktopData* sdd); /* this is when the panel orientation changes */ @@ -299,11 +299,13 @@ static void applet_destroyed(GtkWidget* applet, ShowDesktopData* sdd) sdd->button_activate = 0; } +#ifdef HAVE_X11 if (sdd->wnck_screen != NULL) { g_signal_handlers_disconnect_by_func(sdd->wnck_screen, show_desktop_changed_callback, sdd); sdd->wnck_screen = NULL; } +#endif // HAVE_X11 if (sdd->icon_theme != NULL) { @@ -361,21 +363,25 @@ static void show_desktop_applet_realized(MatePanelApplet* applet, gpointer data) sdd = (ShowDesktopData*) data; - if (sdd->wnck_screen != NULL) - g_signal_handlers_disconnect_by_func(sdd->wnck_screen, show_desktop_changed_callback, sdd); - if (sdd->icon_theme != NULL) g_signal_handlers_disconnect_by_func(sdd->icon_theme, theme_changed_callback, sdd); screen = gtk_widget_get_screen(sdd->applet); - sdd->wnck_screen = wnck_screen_get(gdk_x11_screen_get_screen_number (screen)); + +#ifdef HAVE_X11 + if (sdd->wnck_screen != NULL) + g_signal_handlers_disconnect_by_func(sdd->wnck_screen, show_desktop_changed_callback, sdd); + + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + sdd->wnck_screen = wnck_screen_get(gdk_x11_screen_get_screen_number (screen)); if (sdd->wnck_screen != NULL) wncklet_connect_while_alive(sdd->wnck_screen, "showing_desktop_changed", G_CALLBACK(show_desktop_changed_callback), sdd, sdd->applet); else g_warning("Could not get WnckScreen!"); +#endif // HAVE_X11 - show_desktop_changed_callback(sdd->wnck_screen, sdd); + show_desktop_changed_callback(sdd); sdd->icon_theme = gtk_icon_theme_get_for_screen (screen); wncklet_connect_while_alive(sdd->icon_theme, "changed", G_CALLBACK(theme_changed_callback), sdd, sdd->applet); @@ -514,7 +520,22 @@ static void display_about_dialog(GtkAction* action, ShowDesktopData* sdd) static void button_toggled_callback(GtkWidget* button, ShowDesktopData* sdd) { - if (!gdk_x11_screen_supports_net_wm_hint(gtk_widget_get_screen(button), gdk_atom_intern("_NET_SHOWING_DESKTOP", FALSE))) + gboolean can_show_desktop; + +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + can_show_desktop = gdk_x11_screen_supports_net_wm_hint(gtk_widget_get_screen(button), + gdk_atom_intern("_NET_SHOWING_DESKTOP", + FALSE)); + } + else +#endif + { // not using X11 + can_show_desktop = FALSE; + } + + if (!can_show_desktop) { static GtkWidget* dialog = NULL; @@ -527,7 +548,11 @@ static void button_toggled_callback(GtkWidget* button, ShowDesktopData* sdd) return; } - dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Your window manager does not support the show desktop button, or you are not running a window manager.")); + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("Your window manager does not support the show desktop button, or you are not running a window manager.")); g_object_add_weak_pointer(G_OBJECT(dialog), (gpointer) &dialog); @@ -540,16 +565,20 @@ static void button_toggled_callback(GtkWidget* button, ShowDesktopData* sdd) return; } +#ifdef HAVE_X11 if (sdd->wnck_screen != NULL) wnck_screen_toggle_showing_desktop(sdd->wnck_screen, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))); +#endif // HAVE_X11 update_button_display (sdd); } -static void show_desktop_changed_callback(WnckScreen* screen, ShowDesktopData* sdd) +static void show_desktop_changed_callback(ShowDesktopData* sdd) { +#ifdef HAVE_X11 if (sdd->wnck_screen != NULL) sdd->showing_desktop = wnck_screen_get_showing_desktop(sdd->wnck_screen); +#endif // HAVE_X11 update_button_state (sdd); } diff --git a/applets/wncklet/window-list.c b/applets/wncklet/window-list.c index bd4a9603..54105f60 100644 --- a/applets/wncklet/window-list.c +++ b/applets/wncklet/window-list.c @@ -8,9 +8,7 @@ * */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include #include @@ -19,12 +17,17 @@ #include #include -#define WNCK_I_KNOW_THIS_IS_UNSTABLE -#include #include -#ifdef HAVE_WINDOW_PREVIEWS + +#ifdef HAVE_X11 #include -#endif +#define WNCK_I_KNOW_THIS_IS_UNSTABLE +#include +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND +#include +#endif // HAVE_WAYLAND #define MATE_DESKTOP_USE_UNSTABLE_API #include @@ -34,9 +37,16 @@ #define WINDOW_LIST_ICON "mate-panel-window-list" #define WINDOW_LIST_SCHEMA "org.mate.panel.applet.window-list" + #ifdef HAVE_WINDOW_PREVIEWS #define WINDOW_LIST_PREVIEW_SCHEMA "org.mate.panel.applet.window-list-previews" -#endif +#endif // HAVE_WINDOW_PREVIEWS + +typedef enum { + TASKLIST_NEVER_GROUP, + TASKLIST_AUTO_GROUP, + TASKLIST_ALWAYS_GROUP +} TasklistGroupingType; typedef struct { GtkWidget* applet; @@ -48,7 +58,8 @@ typedef struct { gint thumbnail_size; #endif gboolean include_all_workspaces; - WnckTasklistGroupingType grouping; + + TasklistGroupingType grouping; gboolean move_unminimized_windows; GtkOrientation orientation; @@ -98,9 +109,65 @@ static void tasklist_update(TasklistData* tasklist) gtk_widget_set_size_request(GTK_WIDGET(tasklist->tasklist), tasklist->size, -1); } - wnck_tasklist_set_grouping(WNCK_TASKLIST(tasklist->tasklist), tasklist->grouping); - wnck_tasklist_set_include_all_workspaces(WNCK_TASKLIST(tasklist->tasklist), tasklist->include_all_workspaces); - wnck_tasklist_set_switch_workspace_on_unminimize(WNCK_TASKLIST(tasklist->tasklist), tasklist->move_unminimized_windows); +#ifdef HAVE_X11 + if (WNCK_IS_TASKLIST(tasklist->tasklist)) + { + WnckTasklistGroupingType grouping; + switch (tasklist->grouping) + { + case TASKLIST_NEVER_GROUP: grouping = WNCK_TASKLIST_NEVER_GROUP; + case TASKLIST_AUTO_GROUP: grouping = WNCK_TASKLIST_AUTO_GROUP; + case TASKLIST_ALWAYS_GROUP: grouping = WNCK_TASKLIST_ALWAYS_GROUP; + default: grouping = WNCK_TASKLIST_NEVER_GROUP; + } + wnck_tasklist_set_grouping(WNCK_TASKLIST(tasklist->tasklist), grouping); + wnck_tasklist_set_include_all_workspaces(WNCK_TASKLIST(tasklist->tasklist), tasklist->include_all_workspaces); + wnck_tasklist_set_switch_workspace_on_unminimize(WNCK_TASKLIST(tasklist->tasklist), tasklist->move_unminimized_windows); + } +#endif // HAVE_X11 + + // Not implemented for Wayland +} + +static void tasklist_apply_orientation(TasklistData* tasklist) +{ +#ifdef HAVE_X11 + if (WNCK_IS_TASKLIST(tasklist->tasklist)) + { + wnck_tasklist_set_orientation(WNCK_TASKLIST(tasklist->tasklist), tasklist->orientation); + } +#endif // HAVE_X11 + + // Not yet implemented for Wayland +} + +static void tasklist_set_button_relief(TasklistData* tasklist, GtkReliefStyle relief) +{ +#ifdef HAVE_X11 + if (WNCK_IS_TASKLIST(tasklist->tasklist)) + { + wnck_tasklist_set_button_relief(WNCK_TASKLIST(tasklist->tasklist), relief); + } +#endif // HAVE_X11 + + // Not implemented for Wayland +} + +static const int* tasklist_get_size_hint_list(TasklistData* tasklist, int* n_elements) +{ +#ifdef HAVE_X11 + if (WNCK_IS_TASKLIST(tasklist->tasklist)) + { + return wnck_tasklist_get_size_hint_list(WNCK_TASKLIST(tasklist->tasklist), n_elements); + } + else +#endif // HAVE_X11 + + { + // Not implemented for Wayland + *n_elements = 0; + return NULL; + } } static void response_cb(GtkWidget* widget, int id, TasklistData* tasklist) @@ -141,7 +208,7 @@ static void applet_change_orient(MatePanelApplet* applet, MatePanelAppletOrient return; tasklist->orientation = new_orient; - wnck_tasklist_set_orientation (WNCK_TASKLIST (tasklist->tasklist), new_orient); + tasklist_apply_orientation (tasklist); tasklist_update(tasklist); } @@ -153,11 +220,12 @@ static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBac case PANEL_NO_BACKGROUND: case PANEL_COLOR_BACKGROUND: case PANEL_PIXMAP_BACKGROUND: - wnck_tasklist_set_button_relief(WNCK_TASKLIST(tasklist->tasklist), GTK_RELIEF_NONE); + tasklist_set_button_relief(tasklist, GTK_RELIEF_NONE); break; } } +#ifdef HAVE_X11 #ifdef HAVE_WINDOW_PREVIEWS static GdkPixbuf *preview_window_thumbnail (WnckWindow *wnck_window, TasklistData *tasklist) { @@ -326,7 +394,8 @@ static gboolean applet_leave_notify_event (WnckTasklist *tl, GList *wnck_windows return FALSE; } -#endif +#endif // HAVE_WINDOW_PREVIEWS +#endif // HAVE_X11 static void applet_change_pixel_size(MatePanelApplet* applet, gint size, TasklistData* tasklist) { @@ -436,18 +505,18 @@ static void thumbnail_size_changed(GSettings *settings, gchar* key, TasklistData } #endif -static GtkWidget* get_grouping_button(TasklistData* tasklist, WnckTasklistGroupingType type) +static GtkWidget* get_grouping_button(TasklistData* tasklist, TasklistGroupingType type) { switch (type) { default: - case WNCK_TASKLIST_NEVER_GROUP: + case TASKLIST_NEVER_GROUP: return tasklist->never_group_radio; break; - case WNCK_TASKLIST_AUTO_GROUP: + case TASKLIST_AUTO_GROUP: return tasklist->auto_group_radio; break; - case WNCK_TASKLIST_ALWAYS_GROUP: + case TASKLIST_ALWAYS_GROUP: return tasklist->always_group_radio; break; } @@ -455,7 +524,7 @@ static GtkWidget* get_grouping_button(TasklistData* tasklist, WnckTasklistGroupi static void group_windows_changed(GSettings* settings, gchar* key, TasklistData* tasklist) { - WnckTasklistGroupingType type; + TasklistGroupingType type; GtkWidget* button; type = g_settings_get_enum (settings, key); @@ -536,7 +605,7 @@ static void applet_size_allocate(GtkWidget *widget, GtkAllocation *allocation, T int len; const int* size_hints; - size_hints = wnck_tasklist_get_size_hint_list (WNCK_TASKLIST (tasklist->tasklist), &len); + size_hints = tasklist_get_size_hint_list (tasklist, &len); g_assert(len % 2 == 0); @@ -563,6 +632,8 @@ static void applet_size_allocate(GtkWidget *widget, GtkAllocation *allocation, T mate_panel_applet_set_size_hints(MATE_PANEL_APPLET(tasklist->applet), size_hints, len, 0); } +#ifdef HAVE_X11 +// Currently only used on X11, but should work on Wayland as well when needed static GdkPixbuf* icon_loader_func(const char* icon, int size, unsigned int flags, void* data) { TasklistData* tasklist; @@ -608,6 +679,7 @@ static GdkPixbuf* icon_loader_func(const char* icon, int size, unsigned int flag return retval; } +#endif // HAVE_X11 gboolean window_list_applet_fill(MatePanelApplet* applet) { @@ -668,18 +740,37 @@ gboolean window_list_applet_fill(MatePanelApplet* applet) break; } - tasklist->tasklist = wnck_tasklist_new(); +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + tasklist->tasklist = wnck_tasklist_new(); - wnck_tasklist_set_orientation (WNCK_TASKLIST (tasklist->tasklist), tasklist->orientation); - wnck_tasklist_set_middle_click_close (WNCK_TASKLIST (tasklist->tasklist), TRUE); - wnck_tasklist_set_icon_loader(WNCK_TASKLIST(tasklist->tasklist), icon_loader_func, tasklist, NULL); + wnck_tasklist_set_middle_click_close (WNCK_TASKLIST (tasklist->tasklist), TRUE); + wnck_tasklist_set_icon_loader(WNCK_TASKLIST(tasklist->tasklist), icon_loader_func, tasklist, NULL); - g_signal_connect(G_OBJECT(tasklist->tasklist), "destroy", G_CALLBACK(destroy_tasklist), tasklist); #ifdef HAVE_WINDOW_PREVIEWS - g_signal_connect(G_OBJECT(tasklist->tasklist), "task_enter_notify", G_CALLBACK(applet_enter_notify_event), tasklist); - g_signal_connect(G_OBJECT(tasklist->tasklist), "task_leave_notify", G_CALLBACK(applet_leave_notify_event), tasklist); -#endif + g_signal_connect(G_OBJECT(tasklist->tasklist), "task_enter_notify", G_CALLBACK(applet_enter_notify_event), tasklist); + g_signal_connect(G_OBJECT(tasklist->tasklist), "task_leave_notify", G_CALLBACK(applet_leave_notify_event), tasklist); +#endif // HAVE_WINDOW_PREVIEWS + } + else +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) + { + tasklist->tasklist = gtk_label_new ("[Tasklist not supported on Wayland]"); + } + else +#endif // HAVE_WAYLAND + + { + tasklist->tasklist = gtk_label_new ("[Tasklist not supported on this platform]"); + } + tasklist_apply_orientation(tasklist); + + g_signal_connect(G_OBJECT(tasklist->tasklist), "destroy", G_CALLBACK(destroy_tasklist), tasklist); g_signal_connect(G_OBJECT(tasklist->applet), "size_allocate", G_CALLBACK(applet_size_allocate), tasklist); gtk_container_add(GTK_CONTAINER(tasklist->applet), tasklist->tasklist); @@ -863,7 +954,7 @@ static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist) GtkWidget* button; #ifdef HAVE_WINDOW_PREVIEWS GtkAdjustment *adjustment; -#endif +#endif // HAVE_WINDOW_PREVIEWS tasklist->show_current_radio = WID("show_current_radio"); tasklist->show_all_radio = WID("show_all_radio"); diff --git a/applets/wncklet/window-menu.c b/applets/wncklet/window-menu.c index dbe09f05..c751a161 100644 --- a/applets/wncklet/window-menu.c +++ b/applets/wncklet/window-menu.c @@ -35,8 +35,15 @@ #include #include +#ifdef HAVE_X11 +#include #define WNCK_I_KNOW_THIS_IS_UNSTABLE #include +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND +#include +#endif // HAVE_WAYLAND #include "wncklet.h" #include "window-menu.h" @@ -151,6 +158,9 @@ static void window_menu_size_allocate(MatePanelApplet* applet, GtkAllocation* al orient = mate_panel_applet_get_orient(applet); + if (!GTK_IS_CONTAINER (window_menu->selector)) + return; + children = gtk_container_get_children(GTK_CONTAINER(window_menu->selector)); child = GTK_WIDGET(children->data); g_list_free(children); @@ -178,7 +188,6 @@ static void window_menu_size_allocate(MatePanelApplet* applet, GtkAllocation* al static gboolean window_menu_key_press_event(GtkWidget* widget, GdkEventKey* event, WindowMenu* window_menu) { GtkMenuShell* menu_shell; - WnckSelector* selector; switch (event->keyval) { @@ -188,7 +197,6 @@ static gboolean window_menu_key_press_event(GtkWidget* widget, GdkEventKey* even case GDK_KEY_Return: case GDK_KEY_space: case GDK_KEY_KP_Space: - selector = WNCK_SELECTOR(window_menu->selector); /* * We need to call _gtk_menu_shell_activate() here as is done in * window_key_press_handler in gtkmenubar.c which pops up menu @@ -196,7 +204,7 @@ static gboolean window_menu_key_press_event(GtkWidget* widget, GdkEventKey* even * * As that function is private its code is replicated here. */ - menu_shell = GTK_MENU_SHELL(selector); + menu_shell = GTK_MENU_SHELL(window_menu->selector); gtk_menu_shell_select_first(menu_shell, FALSE); return TRUE; @@ -231,6 +239,7 @@ gboolean window_menu_applet_fill(MatePanelApplet* applet) window_menu->orient = mate_panel_applet_get_orient(applet); g_signal_connect(window_menu->applet, "destroy", G_CALLBACK(window_menu_destroy), window_menu); + g_signal_connect(window_menu->applet, "key_press_event", G_CALLBACK(window_menu_key_press_event), window_menu); action_group = gtk_action_group_new("WindowMenu Applet Actions"); gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE); @@ -240,12 +249,30 @@ gboolean window_menu_applet_fill(MatePanelApplet* applet) action_group); g_object_unref(action_group); - window_menu->selector = wnck_selector_new(); - gtk_container_add(GTK_CONTAINER(window_menu->applet), window_menu->selector); +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + window_menu->selector = wnck_selector_new(); + mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(window_menu->applet), GTK_WIDGET(window_menu->selector)); - mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(window_menu->applet), GTK_WIDGET(window_menu->selector)); + } + else +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) + { + window_menu->selector = gtk_label_new ("[Window menu not supported on Wayland]"); + } + else +#endif // HAVE_WAYLAND + + { + window_menu->selector = gtk_label_new ("[Window menu not supported on this platform]"); + } + + gtk_container_add(GTK_CONTAINER(window_menu->applet), window_menu->selector); - g_signal_connect(window_menu->applet, "key_press_event", G_CALLBACK(window_menu_key_press_event), window_menu); g_signal_connect(window_menu->applet, "size-allocate", G_CALLBACK(window_menu_size_allocate), window_menu); g_signal_connect_after(G_OBJECT(window_menu->applet), "focus-in-event", G_CALLBACK(gtk_widget_queue_draw), window_menu); diff --git a/applets/wncklet/wncklet.c b/applets/wncklet/wncklet.c index c24b41f0..ed141b1f 100644 --- a/applets/wncklet/wncklet.c +++ b/applets/wncklet/wncklet.c @@ -25,18 +25,17 @@ #include #endif -#ifndef HAVE_X11 -#error file should only be built when HAVE_X11 is enabled -#endif - #include #include #include #include + +#ifdef HAVE_X11 #include #define WNCK_I_KNOW_THIS_IS_UNSTABLE #include +#endif #include "wncklet.h" #include "window-menu.h" @@ -96,8 +95,11 @@ void wncklet_display_help(GtkWidget* widget, const char* doc_id, const char* lin } } +#ifdef HAVE_X11 WnckScreen* wncklet_get_screen(GtkWidget* applet) { + g_return_val_if_fail (GDK_IS_X11_DISPLAY (gdk_display_get_default ()), NULL); + int screen_num; if (!gtk_widget_has_screen(applet)) @@ -107,6 +109,7 @@ WnckScreen* wncklet_get_screen(GtkWidget* applet) return wnck_screen_get(screen_num); } +#endif // HAVE_X11 void wncklet_connect_while_alive(gpointer object, const char* signal, GCallback func, gpointer func_data, gpointer alive_object) { @@ -120,13 +123,18 @@ void wncklet_connect_while_alive(gpointer object, const char* signal, GCallback static gboolean wncklet_factory(MatePanelApplet* applet, const char* iid, gpointer data) { gboolean retval = FALSE; - static gboolean type_registered = FALSE; - if (!type_registered) +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { - wnck_set_client_type(WNCK_CLIENT_TYPE_PAGER); - type_registered = TRUE; + static gboolean type_registered = FALSE; + if (!type_registered) + { + wnck_set_client_type(WNCK_CLIENT_TYPE_PAGER); + type_registered = TRUE; + } } +#endif // HAVE_X11 if (!strcmp(iid, "WindowMenuApplet")) retval = window_menu_applet_fill(applet); diff --git a/applets/wncklet/wncklet.h b/applets/wncklet/wncklet.h index d561937f..145cbce3 100644 --- a/applets/wncklet/wncklet.h +++ b/applets/wncklet/wncklet.h @@ -24,8 +24,6 @@ #ifndef __WNCKLET_H__ #define __WNCKLET_H__ -#include - #include #include #include @@ -36,6 +34,8 @@ extern "C" { #endif +typedef struct _WnckScreen WnckScreen; + void wncklet_display_help(GtkWidget* widget, const char* doc_id, const char* link_id, const char* icon_name); WnckScreen* wncklet_get_screen(GtkWidget* applet); diff --git a/applets/wncklet/workspace-switcher.c b/applets/wncklet/workspace-switcher.c index 9d5a210e..9ff7d723 100644 --- a/applets/wncklet/workspace-switcher.c +++ b/applets/wncklet/workspace-switcher.c @@ -21,9 +21,17 @@ #include #include +#include + +#ifdef HAVE_X11 +#include #define WNCK_I_KNOW_THIS_IS_UNSTABLE #include -#include +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND +#include +#endif // HAVE_WAYLAND #include @@ -58,7 +66,10 @@ typedef struct { GtkWidget* pager; +#ifdef HAVE_X11 WnckScreen* screen; +#endif // HAVE_X11 + PagerWM wm; /* Properties: */ @@ -79,7 +90,7 @@ typedef struct { GtkOrientation orientation; int n_rows; /* for vertical layout this is cols */ - WnckPagerDisplayMode display_mode; + gboolean display_names; /* if to display names or content */ gboolean display_all; gboolean wrap_workspaces; @@ -91,20 +102,34 @@ static void display_help_dialog(GtkAction* action, PagerData* pager); static void display_about_dialog(GtkAction* action, PagerData* pager); static void destroy_pager(GtkWidget* widget, PagerData* pager); -static void pager_update(PagerData* pager) +#ifdef HAVE_X11 +static void pager_update_wnck(PagerData* pager, WnckPager* wnck_pager) { - wnck_pager_set_orientation(WNCK_PAGER(pager->pager), pager->orientation); - wnck_pager_set_n_rows(WNCK_PAGER(pager->pager), pager->n_rows); - wnck_pager_set_show_all(WNCK_PAGER(pager->pager), pager->display_all); + WnckPagerDisplayMode display_mode = WNCK_PAGER_DISPLAY_CONTENT; - if (pager->wm == PAGER_WM_MARCO) - wnck_pager_set_display_mode(WNCK_PAGER(pager->pager), pager->display_mode); - else if (pager->wm == PAGER_WM_METACITY) - wnck_pager_set_display_mode(WNCK_PAGER(pager->pager), pager->display_mode); - else if (pager->wm == PAGER_WM_I3) - wnck_pager_set_display_mode(WNCK_PAGER(pager->pager), pager->display_mode); - else - wnck_pager_set_display_mode(WNCK_PAGER(pager->pager), WNCK_PAGER_DISPLAY_CONTENT); + if (pager->display_names && ( + pager->wm == PAGER_WM_MARCO || + pager->wm == PAGER_WM_METACITY || + pager->wm == PAGER_WM_I3)) + { + display_mode = WNCK_PAGER_DISPLAY_NAME; + } + + wnck_pager_set_orientation(wnck_pager, pager->orientation); + wnck_pager_set_n_rows(wnck_pager, pager->n_rows); + wnck_pager_set_show_all(wnck_pager, pager->display_all); + wnck_pager_set_display_mode(wnck_pager, display_mode); +} +#endif // HAVE_X11 + +static void pager_update(PagerData* pager) +{ +#ifdef HAVE_X11 + if (WNCK_IS_PAGER(pager->pager)) + { + pager_update_wnck(pager, WNCK_PAGER(pager->pager)); + } +#endif // HAVE_X11 } static void update_properties_for_wm(PagerData* pager) @@ -176,11 +201,16 @@ static void update_properties_for_wm(PagerData* pager) } } -static void window_manager_changed(WnckScreen* screen, PagerData* pager) +static void window_manager_changed(PagerData* pager) { - const char *wm_name; + const char *wm_name = NULL; - wm_name = wnck_screen_get_window_manager_name(screen); +#ifdef HAVE_X11 + if (pager->screen) + { + wm_name = wnck_screen_get_window_manager_name (pager->screen); + } +#endif // HAVE_X11 if (!wm_name) pager->wm = PAGER_WM_UNKNOWN; @@ -201,15 +231,22 @@ static void window_manager_changed(WnckScreen* screen, PagerData* pager) static void applet_realized(MatePanelApplet* applet, PagerData* pager) { - pager->screen = wncklet_get_screen(GTK_WIDGET(applet)); +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + pager->screen = wncklet_get_screen(GTK_WIDGET(applet)); + wncklet_connect_while_alive(pager->screen, "window_manager_changed", G_CALLBACK(window_manager_changed), pager, pager->applet); + } +#endif // HAVE_X11 - window_manager_changed(pager->screen, pager); - wncklet_connect_while_alive(pager->screen, "window_manager_changed", G_CALLBACK(window_manager_changed), pager, pager->applet); + window_manager_changed(pager); } static void applet_unrealized(MatePanelApplet* applet, PagerData* pager) { +#ifdef HAVE_X11 pager->screen = NULL; +#endif // HAVE_X11 pager->wm = PAGER_WM_UNKNOWN; } @@ -248,8 +285,13 @@ static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBac gtk_style_context_set_path (new_context, gtk_widget_get_path (GTK_WIDGET (pager->pager))); g_object_unref (new_context); - wnck_pager_set_shadow_type (WNCK_PAGER (pager->pager), - type == PANEL_NO_BACKGROUND ? GTK_SHADOW_NONE : GTK_SHADOW_IN); +#ifdef HAVE_X11 + if (WNCK_IS_PAGER(pager->pager)) + { + wnck_pager_set_shadow_type (WNCK_PAGER (pager->pager), + type == PANEL_NO_BACKGROUND ? GTK_SHADOW_NONE : GTK_SHADOW_IN); + } +#endif // HAVE_X11 } static void applet_style_updated (MatePanelApplet *applet, GtkStyleContext *context) @@ -294,8 +336,19 @@ static gboolean applet_scroll(MatePanelApplet* applet, GdkEventScroll* event, Pa if (event->direction == GDK_SCROLL_SMOOTH) return FALSE; - index = wnck_workspace_get_number(wnck_screen_get_active_workspace(pager->screen)); - n_workspaces = wnck_screen_get_workspace_count(pager->screen); +#ifdef HAVE_X11 + if (pager->screen) + { + index = wnck_workspace_get_number(wnck_screen_get_active_workspace(pager->screen)); + n_workspaces = wnck_screen_get_workspace_count(pager->screen); + } + else +#endif // HAVE_X11 + { + index = 0; + n_workspaces = 1; + } + n_columns = n_workspaces / pager->n_rows; if (n_workspaces % pager->n_rows != 0) @@ -381,7 +434,12 @@ static gboolean applet_scroll(MatePanelApplet* applet, GdkEventScroll* event, Pa break; } - wnck_workspace_activate(wnck_screen_get_workspace(pager->screen, index), event->time); +#ifdef HAVE_X11 + if (pager->screen) + { + wnck_workspace_activate(wnck_screen_get_workspace(pager->screen, index), event->time); + } +#endif // HAVE_X11 return TRUE; } @@ -434,14 +492,7 @@ static void display_workspace_names_changed(GSettings* settings, gchar* key, Pag value = g_settings_get_boolean (settings, key); - if (value) - { - pager->display_mode = WNCK_PAGER_DISPLAY_NAME; - } - else - { - pager->display_mode = WNCK_PAGER_DISPLAY_CONTENT; - } + pager->display_names = g_settings_get_boolean (settings, key); pager_update(pager); @@ -521,7 +572,6 @@ gboolean workspace_switcher_applet_fill(MatePanelApplet* applet) { PagerData* pager; GtkActionGroup* action_group; - gboolean display_names; pager = g_new0(PagerData, 1); @@ -535,19 +585,10 @@ gboolean workspace_switcher_applet_fill(MatePanelApplet* applet) pager->n_rows = CLAMP(pager->n_rows, 1, MAX_REASONABLE_ROWS); - display_names = g_settings_get_boolean(pager->settings, "display-workspace-names"); + pager->display_names = g_settings_get_boolean(pager->settings, "display-workspace-names"); pager->wrap_workspaces = g_settings_get_boolean(pager->settings, "wrap-workspaces"); - if (display_names) - { - pager->display_mode = WNCK_PAGER_DISPLAY_NAME; - } - else - { - pager->display_mode = WNCK_PAGER_DISPLAY_CONTENT; - } - pager->display_all = g_settings_get_boolean(pager->settings, "display-all-workspaces"); switch (mate_panel_applet_get_orient(applet)) @@ -563,10 +604,29 @@ gboolean workspace_switcher_applet_fill(MatePanelApplet* applet) break; } - pager->pager = wnck_pager_new(); - pager->screen = NULL; +#ifdef HAVE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + { + pager->pager = wnck_pager_new(); + wnck_pager_set_shadow_type(WNCK_PAGER(pager->pager), GTK_SHADOW_IN); + pager->screen = NULL; + } + else +#endif // HAVE_X11 + +#ifdef HAVE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) + { + pager->pager = gtk_label_new ("[Pager not supported on Wayland]"); + } + else +#endif // HAVE_WAYLAND + + { + pager->pager = gtk_label_new ("[Pager not supported on this platform]"); + } + pager->wm = PAGER_WM_UNKNOWN; - wnck_pager_set_shadow_type(WNCK_PAGER(pager->pager), GTK_SHADOW_IN); GtkStyleContext *context; context = gtk_widget_get_style_context (GTK_WIDGET (applet)); @@ -671,9 +731,28 @@ static void num_rows_value_changed(GtkSpinButton* button, PagerData* pager) g_settings_set_int(pager->settings, "num-rows", gtk_spin_button_get_value_as_int(button)); } +static const char *get_workspace_name(PagerData* pager, int workspace_index) +{ +#ifdef HAVE_X11 + if (pager->screen) + { + WnckWorkspace *workspace = wnck_screen_get_workspace(pager->screen, workspace_index); + return wnck_workspace_get_name(workspace); + } +#endif // HAVE_X11 + + // Fallback + return "workspace"; +} + static void update_workspaces_model(PagerData* pager) { - int nr_ws = wnck_screen_get_workspace_count (pager->screen); + int nr_ws = 1; + +#ifdef HAVE_X11 + if (pager->screen) + nr_ws = wnck_screen_get_workspace_count (pager->screen); +#endif // HAVE_X11 if (pager->properties_dialog) { @@ -687,17 +766,20 @@ static void update_workspaces_model(PagerData* pager) for (i = 0; i < nr_ws; i++) { - WnckWorkspace *workspace = wnck_screen_get_workspace(pager->screen, i); gtk_list_store_append(pager->workspaces_store, &iter); - gtk_list_store_set(pager->workspaces_store, &iter, 0, wnck_workspace_get_name(workspace), -1); + const char* name = get_workspace_name(pager, i); + gtk_list_store_set(pager->workspaces_store, &iter, 0, name, -1); } } } +#ifdef HAVE_X11 static void workspace_renamed(WnckWorkspace* space, PagerData* pager) { GtkTreeIter iter; + g_return_if_fail(WNCK_IS_WORKSPACE(space)); + if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (pager->workspaces_store), &iter, NULL, wnck_workspace_get_number (space))) gtk_list_store_set(pager->workspaces_store, &iter, 0, wnck_workspace_get_name(space), -1); } @@ -716,10 +798,17 @@ static void workspace_destroyed(WnckScreen* screen, WnckWorkspace* space, PagerD g_return_if_fail(WNCK_IS_SCREEN(screen)); update_workspaces_model(pager); } +#endif // HAVE_X11 static void num_workspaces_value_changed(GtkSpinButton* button, PagerData* pager) { - wnck_screen_change_workspace_count(pager->screen, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pager->num_workspaces_spin))); +#ifdef HAVE_X11 + if (pager->screen) + { + int workspace_count = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pager->num_workspaces_spin)); + wnck_screen_change_workspace_count(pager->screen, workspace_count); + } +#endif // HAVE_X11 } static gboolean workspaces_tree_focused_out(GtkTreeView* treeview, GdkEventFocus* event, PagerData* pager) @@ -733,28 +822,33 @@ static gboolean workspaces_tree_focused_out(GtkTreeView* treeview, GdkEventFocus static void workspace_name_edited(GtkCellRendererText* cell_renderer_text, const gchar* path, const gchar* new_text, PagerData* pager) { - const gint* indices; - WnckWorkspace* workspace; - GtkTreePath* p; +#ifdef HAVE_X11 + if (pager->screen) + { + const gint* indices; + WnckWorkspace* workspace; + GtkTreePath* p; - p = gtk_tree_path_new_from_string(path); - indices = gtk_tree_path_get_indices(p); - workspace = wnck_screen_get_workspace(pager->screen, indices[0]); + p = gtk_tree_path_new_from_string(path); + indices = gtk_tree_path_get_indices(p); + workspace = wnck_screen_get_workspace(pager->screen, indices[0]); - if (workspace != NULL) - { - gchar* temp_name = g_strdup(new_text); + if (workspace != NULL) + { + gchar* temp_name = g_strdup(new_text); - wnck_workspace_change_name(workspace, g_strstrip(temp_name)); + wnck_workspace_change_name(workspace, g_strstrip(temp_name)); - g_free(temp_name); - } - else - { - g_warning("Edited name of workspace %d which no longer exists", indices[0]); - } + g_free(temp_name); + } + else + { + g_warning("Edited name of workspace %d which no longer exists", indices[0]); + } - gtk_tree_path_free(p); + gtk_tree_path_free(p); + } +#endif } static void properties_dialog_destroyed(GtkWidget* widget, PagerData* pager) @@ -851,7 +945,6 @@ static void setup_dialog(GtkBuilder* builder, PagerData* pager) gboolean value; GtkTreeViewColumn* column; GtkCellRenderer* cell; - int nr_ws, i; GSettings *marco_general_settings = NULL; GSettings *marco_workspaces_settings = NULL; @@ -903,14 +996,7 @@ static void setup_dialog(GtkBuilder* builder, PagerData* pager) g_signal_connect(G_OBJECT(pager->display_workspaces_toggle), "toggled", (GCallback) display_workspace_names_toggled, pager); - if (pager->display_mode == WNCK_PAGER_DISPLAY_NAME) - { - value = TRUE; - } - else - { - value = FALSE; - } + value = pager->display_names; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pager->display_workspaces_toggle), value); @@ -944,12 +1030,24 @@ static void setup_dialog(GtkBuilder* builder, PagerData* pager) g_signal_connect(WID("done_button"), "clicked", (GCallback) close_dialog, pager); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(pager->num_workspaces_spin), wnck_screen_get_workspace_count(pager->screen)); - g_signal_connect(G_OBJECT(pager->num_workspaces_spin), "value_changed", (GCallback) num_workspaces_value_changed, pager); +#ifdef HAVE_X11 + if (pager->screen) + { + int i, nr_ws; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(pager->num_workspaces_spin), wnck_screen_get_workspace_count(pager->screen)); + wncklet_connect_while_alive(pager->screen, "workspace_created", G_CALLBACK(workspace_created), pager, pager->properties_dialog); + wncklet_connect_while_alive(pager->screen, "workspace_destroyed", G_CALLBACK(workspace_destroyed), pager, pager->properties_dialog); - wncklet_connect_while_alive(pager->screen, "workspace_created", G_CALLBACK(workspace_created), pager, pager->properties_dialog); + nr_ws = wnck_screen_get_workspace_count(pager->screen); - wncklet_connect_while_alive(pager->screen, "workspace_destroyed", G_CALLBACK(workspace_destroyed), pager, pager->properties_dialog); + for (i = 0; i < nr_ws; i++) + { + wncklet_connect_while_alive(G_OBJECT(wnck_screen_get_workspace(pager->screen, i)), "name_changed", G_CALLBACK(workspace_renamed), pager, pager->properties_dialog); + } + } +#endif // HAVE_X11 + + g_signal_connect(G_OBJECT(pager->num_workspaces_spin), "value_changed", (GCallback) num_workspaces_value_changed, pager); g_signal_connect(G_OBJECT(pager->workspaces_tree), "focus_out_event", (GCallback) workspaces_tree_focused_out, pager); @@ -965,13 +1063,6 @@ static void setup_dialog(GtkBuilder* builder, PagerData* pager) gtk_tree_view_append_column(GTK_TREE_VIEW(pager->workspaces_tree), column); g_signal_connect(cell, "edited", (GCallback) workspace_name_edited, pager); - nr_ws = wnck_screen_get_workspace_count(pager->screen); - - for (i = 0; i < nr_ws; i++) - { - wncklet_connect_while_alive(G_OBJECT(wnck_screen_get_workspace(pager->screen, i)), "name_changed", G_CALLBACK(workspace_renamed), pager, pager->properties_dialog); - } - update_properties_for_wm(pager); } -- cgit v1.2.1