diff options
| author | Aleksey Samoilov <[email protected]> | 2026-09-09 08:07:15 -0400 |
|---|---|---|
| committer | Luke from DC <[email protected]> | 2026-09-10 18:20:55 +0000 |
| commit | 8db29b3efea6a07060d75842c0a5da1d8742c365 (patch) | |
| tree | 62accc6cf8572f1a4cc3869b412b3e73241a1386 | |
| parent | 6b27279e0de76222441196affaa95d0b90111c05 (diff) | |
| download | mate-panel-8db29b3efea6a07060d75842c0a5da1d8742c365.tar.bz2 mate-panel-8db29b3efea6a07060d75842c0a5da1d8742c365.tar.xz | |
wayland: implement scroll, middle-click close and urgent highlights
| -rw-r--r-- | applets/wncklet/wayland-backend.c | 146 | ||||
| -rw-r--r-- | applets/wncklet/wayland-backend.h | 2 | ||||
| -rw-r--r-- | applets/wncklet/window-list.c | 12 |
3 files changed, 158 insertions, 2 deletions
diff --git a/applets/wncklet/wayland-backend.c b/applets/wncklet/wayland-backend.c index 4a2d1755..0f7767ef 100644 --- a/applets/wncklet/wayland-backend.c +++ b/applets/wncklet/wayland-backend.c @@ -59,6 +59,8 @@ typedef struct ContextMenu *context_menu; XfwScreen *screen; GList *tasks; + gboolean scroll_enabled; + gboolean middle_click_close; } TasklistManager; typedef struct @@ -74,6 +76,7 @@ typedef struct gboolean maximized; gboolean minimized; gboolean fullscreen; + gboolean urgent; } ToplevelTask; static int tasklist_invocations = 0; @@ -89,6 +92,7 @@ static GtkTargetEntry source_targets[] = static gboolean has_initialized = FALSE; static ToplevelTask *toplevel_task_new (TasklistManager *tasklist, XfwWindow *window); +static gboolean tasklist_scroll_event (GtkWidget *widget, GdkEventScroll *event, TasklistManager *tasklist); static guint buttons, tasklist_width; @@ -105,10 +109,18 @@ update_task_state (ToplevelTask *task) task->maximized = (state & XFW_WINDOW_STATE_MAXIMIZED) != 0; task->minimized = (state & XFW_WINDOW_STATE_MINIMIZED) != 0; task->fullscreen = (state & XFW_WINDOW_STATE_FULLSCREEN) != 0; + task->urgent = (state & XFW_WINDOW_STATE_URGENT) != 0; if (task->button) + { + if (task->urgent) + gtk_style_context_add_class (gtk_widget_get_style_context (task->button), "urgent"); + else + gtk_style_context_remove_class (gtk_widget_get_style_context (task->button), "urgent"); + gtk_button_set_relief (GTK_BUTTON (task->button), task->active ? GTK_RELIEF_NORMAL : GTK_RELIEF_NONE); + } } static void @@ -324,6 +336,11 @@ tasklist_manager_new (void) (GDestroyNotify)tasklist_manager_disconnected_from_widget); tasklist->context_menu = context_menu_new (); + /* mouse scroll to switch windows */ + gtk_widget_add_events (tasklist->list, GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK); + g_signal_connect (tasklist->list, "scroll-event", + G_CALLBACK (tasklist_scroll_event), tasklist); + /* add all existing windows on this screen */ windows = xfw_screen_get_windows (screen); for (l = windows; l != NULL; l = l->next) @@ -589,6 +606,16 @@ toplevel_task_handle_clicked (GtkButton *button, ToplevelTask *task) static gboolean on_toplevel_button_press (GtkWidget *button, GdkEvent *event, TasklistManager *tasklist) { /* Assume event is a button press */ + + if (((GdkEventButton*)event)->button == GDK_BUTTON_MIDDLE && + tasklist->middle_click_close) + { + ToplevelTask *task = g_object_get_data (G_OBJECT (button), toplevel_task_key); + if (task && task->window) + xfw_window_close (task->window, ((GdkEventButton*)event)->time, NULL); + return TRUE; + } + if (((GdkEventButton*)event)->button == GDK_BUTTON_SECONDARY) { ContextMenu *menu = tasklist->context_menu; @@ -613,6 +640,104 @@ static gboolean on_toplevel_button_press (GtkWidget *button, GdkEvent *event, Ta } } +static gboolean +tasklist_scroll_event (GtkWidget *widget, GdkEventScroll *event, TasklistManager *tasklist) +{ + ToplevelTask *child; + GList *li, *lnew = NULL; + GdkScrollDirection direction; + gboolean wrap_windows = TRUE; + + if (!tasklist->scroll_enabled) + return TRUE; + + /* get the current active window button */ + for (li = tasklist->tasks; li != NULL; li = li->next) + { + child = li->data; + if (child->window && xfw_window_is_active (child->window)) + break; + } + + if (li == NULL) + return TRUE; + + if (event->direction != GDK_SCROLL_SMOOTH) + direction = event->direction; + else if (event->delta_y < 0) + direction = GDK_SCROLL_UP; + else if (event->delta_y > 0) + direction = GDK_SCROLL_DOWN; + else if (event->delta_x < 0) + direction = GDK_SCROLL_LEFT; + else if (event->delta_x > 0) + direction = GDK_SCROLL_RIGHT; + else + return TRUE; + + switch (direction) + { + case GDK_SCROLL_UP: + /* find the previous button on the tasklist */ + for (lnew = g_list_previous (li);; lnew = lnew->prev) + { + if (lnew == NULL) + { + if (wrap_windows) + { + lnew = g_list_last (li); + wrap_windows = FALSE; + if (lnew == NULL) + break; + } + else + break; + } + + child = lnew->data; + if (child->window != NULL) + break; + } + break; + + case GDK_SCROLL_DOWN: + /* find the next button on the tasklist */ + for (lnew = g_list_next (li);; lnew = lnew->next) + { + if (lnew == NULL) + { + if (wrap_windows) + { + lnew = g_list_first (li); + wrap_windows = FALSE; + if (lnew == NULL) + break; + } + else + break; + } + + child = lnew->data; + if (child->window != NULL) + break; + } + break; + + case GDK_SCROLL_LEFT: + case GDK_SCROLL_RIGHT: + default: + return TRUE; + } + + if (lnew != NULL) + { + child = lnew->data; + xfw_window_activate (child->window, NULL, event->time, NULL); + } + + return TRUE; +} + static ToplevelTask * toplevel_task_new (TasklistManager *tasklist, XfwWindow *window) { @@ -657,6 +782,11 @@ toplevel_task_new (TasklistManager *tasklist, XfwWindow *window) G_CALLBACK (on_toplevel_button_press), tasklist); + /* mouse scroll to switch windows */ + gtk_widget_add_events (task->button, GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK); + g_signal_connect (task->button, "scroll-event", + G_CALLBACK (tasklist_scroll_event), tasklist); + /* drag-and-drop to reorder task buttons */ gtk_drag_source_set (task->button, GDK_BUTTON1_MASK, source_targets, G_N_ELEMENTS (source_targets), @@ -810,3 +940,19 @@ wayland_tasklist_set_orientation (GtkWidget* tasklist_widget, GtkOrientation ori gtk_orientable_set_orientation (GTK_ORIENTABLE (tasklist->list), orient); gtk_orientable_set_orientation (GTK_ORIENTABLE (tasklist->outer_box), orient); } + +void +wayland_tasklist_set_middle_click_close (GtkWidget *tasklist_widget, gboolean enabled) +{ + TasklistManager *tasklist = tasklist_widget_get_tasklist (tasklist_widget); + g_return_if_fail (tasklist); + tasklist->middle_click_close = enabled; +} + +void +wayland_tasklist_set_scroll_enabled (GtkWidget *tasklist_widget, gboolean enabled) +{ + TasklistManager *tasklist = tasklist_widget_get_tasklist (tasklist_widget); + g_return_if_fail (tasklist); + tasklist->scroll_enabled = enabled; +} diff --git a/applets/wncklet/wayland-backend.h b/applets/wncklet/wayland-backend.h index e2402236..38cadf7c 100644 --- a/applets/wncklet/wayland-backend.h +++ b/applets/wncklet/wayland-backend.h @@ -37,6 +37,8 @@ extern "C" { GtkWidget* wayland_tasklist_new (void); void wayland_tasklist_set_orientation (GtkWidget* tasklist_widget, GtkOrientation orient); +void wayland_tasklist_set_middle_click_close (GtkWidget* tasklist_widget, gboolean enabled); +void wayland_tasklist_set_scroll_enabled (GtkWidget* tasklist_widget, gboolean enabled); #ifdef __cplusplus } diff --git a/applets/wncklet/window-list.c b/applets/wncklet/window-list.c index d7e9f438..c7fd152e 100644 --- a/applets/wncklet/window-list.c +++ b/applets/wncklet/window-list.c @@ -144,7 +144,13 @@ static void tasklist_update(TasklistData* tasklist) } #endif /* HAVE_X11 */ - /* Not implemented for Wayland */ +#ifdef HAVE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) + { + wayland_tasklist_set_scroll_enabled (tasklist->tasklist, tasklist->scroll_enable); + wayland_tasklist_set_middle_click_close (tasklist->tasklist, tasklist->middle_click_close); + } +#endif /* HAVE_WAYLAND */ } static void tasklist_apply_orientation(TasklistData* tasklist) @@ -848,7 +854,9 @@ gboolean window_list_applet_fill(MatePanelApplet* applet) ".mate-panel-menu-bar button,\n" " #tasklist-button {\n" " padding: 0px;\n" - " margin: 0px;\n }", + " margin: 0px;\n }\n" + " #tasklist-button.urgent {\n" + " font-weight: bold;\n }", -1, NULL); gtk_style_context_add_provider_for_screen (gtk_widget_get_screen (tasklist->applet), GTK_STYLE_PROVIDER (provider), |
