summaryrefslogtreecommitdiff
path: root/applets/wncklet/window-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'applets/wncklet/window-list.c')
-rw-r--r--applets/wncklet/window-list.c545
1 files changed, 423 insertions, 122 deletions
diff --git a/applets/wncklet/window-list.c b/applets/wncklet/window-list.c
index 40c5f07b..a87649b1 100644
--- a/applets/wncklet/window-list.c
+++ b/applets/wncklet/window-list.c
@@ -8,9 +8,7 @@
*
*/
-#ifdef HAVE_CONFIG_H
- #include <config.h>
-#endif
+#include <config.h>
#include <string.h>
@@ -19,12 +17,18 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#define WNCK_I_KNOW_THIS_IS_UNSTABLE
-#include <libwnck/libwnck.h>
#include <gio/gio.h>
-#ifdef HAVE_WINDOW_PREVIEWS
+
+#ifdef HAVE_X11
#include <gdk/gdkx.h>
-#endif
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+#endif /* HAVE_X11 */
+
+#ifdef HAVE_WAYLAND
+#include <gdk/gdkwayland.h>
+#include "wayland-backend.h"
+#endif /* HAVE_WAYLAND */
#define MATE_DESKTOP_USE_UNSTABLE_API
#include <libmate-desktop/mate-desktop-utils.h>
@@ -34,9 +38,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,8 +59,11 @@ typedef struct {
gint thumbnail_size;
#endif
gboolean include_all_workspaces;
- WnckTasklistGroupingType grouping;
+
+ TasklistGroupingType grouping;
gboolean move_unminimized_windows;
+ gboolean scroll_enable;
+ gboolean middle_click_close;
GtkOrientation orientation;
int size;
@@ -61,9 +75,11 @@ typedef struct {
/* Properties: */
GtkWidget* properties_dialog;
+ GtkWidget* wayland_info_label;
GtkWidget* show_current_radio;
GtkWidget* show_all_radio;
#ifdef HAVE_WINDOW_PREVIEWS
+ GtkWidget* window_thumbnail_box;
GtkWidget* show_thumbnails_check;
GtkWidget* thumbnail_size_label;
GtkWidget* thumbnail_size_spin;
@@ -71,9 +87,13 @@ typedef struct {
GtkWidget* never_group_radio;
GtkWidget* auto_group_radio;
GtkWidget* always_group_radio;
- GtkWidget* minimized_windows_label;
GtkWidget* move_minimized_radio;
+ GtkWidget* mouse_scroll_check;
+ GtkWidget* middle_click_close_check;
GtkWidget* change_workspace_radio;
+ GtkWidget* minimized_windows_box;
+ GtkWidget* window_grouping_box;
+ GtkWidget* window_list_content_box;
GSettings* settings;
#ifdef HAVE_WINDOW_PREVIEWS
@@ -98,9 +118,79 @@ 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;
+ break;
+ case TASKLIST_AUTO_GROUP:
+ grouping = WNCK_TASKLIST_AUTO_GROUP;
+ break;
+ case TASKLIST_ALWAYS_GROUP:
+ grouping = WNCK_TASKLIST_ALWAYS_GROUP;
+ break;
+ 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);
+ wnck_tasklist_set_scroll_enabled (WNCK_TASKLIST(tasklist->tasklist), tasklist->scroll_enable);
+ wnck_tasklist_set_middle_click_close (WNCK_TASKLIST (tasklist->tasklist), tasklist->middle_click_close);
+ }
+#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 */
+
+#ifdef HAVE_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()))
+ {
+ wayland_tasklist_set_orientation(tasklist->tasklist, tasklist->orientation);
+ }
+#endif
+}
+
+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 +231,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,99 +243,141 @@ 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)
+static cairo_surface_t*
+preview_window_thumbnail (WnckWindow *wnck_window,
+ TasklistData *tasklist,
+ int *thumbnail_width,
+ int *thumbnail_height,
+ int *thumbnail_scale)
{
GdkWindow *window;
- GdkPixbuf *screenshot;
- GdkPixbuf *thumbnail;
- guchar *pixels;
+ Window win;
+ cairo_surface_t *thumbnail;
+ cairo_t *cr;
double ratio;
- int width, height;
- int scale;
+ int width, height, scale;
- window = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), wnck_window_get_xid (wnck_window));
+ win = wnck_window_get_xid (wnck_window);
- if (window == NULL)
+ if ((window = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), win)) == NULL)
+ {
return NULL;
+ }
- scale = gdk_window_get_scale_factor (window);
+ *thumbnail_scale = scale = gdk_window_get_scale_factor (window);
width = gdk_window_get_width (window) * scale;
height = gdk_window_get_height (window) * scale;
- /* Generate window screenshot for preview */
- screenshot = gdk_pixbuf_get_from_window (window, 0, 0, width / scale, height / scale);
- g_object_unref (window);
-
- if (screenshot == NULL)
- return NULL;
-
- /* Determine whether the contents of the screenshot are empty */
- pixels = gdk_pixbuf_get_pixels (screenshot);
- if (!g_strcmp0 ((const char *)pixels, ""))
- {
- g_object_unref (screenshot);
- return NULL;
- }
-
/* Scale to configured size while maintaining aspect ratio */
if (width > height)
{
- ratio = (double) height / (double) width;
- width = MIN(width, tasklist->thumbnail_size);
- height = width * ratio;
+ int max_size = MIN (width, tasklist->thumbnail_size * scale);
+ ratio = (double) max_size / (double) width;
+ *thumbnail_width = max_size;
+ *thumbnail_height = (int) ((double) height * ratio);
}
else
{
- ratio = (double) width / (double) height;
- height = MIN(height, tasklist->thumbnail_size);
- width = height * ratio;
+ int max_size = MIN (height, tasklist->thumbnail_size * scale);
+ ratio = (double) max_size / (double) height;
+ *thumbnail_height = max_size;
+ *thumbnail_width = (int) ((double) width * ratio);
}
- thumbnail = gdk_pixbuf_scale_simple (screenshot, width, height, GDK_INTERP_BILINEAR);
- g_object_unref (screenshot);
+ gdk_x11_display_error_trap_push (gdk_window_get_display (window));
+
+ thumbnail = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ *thumbnail_width,
+ *thumbnail_height);
+ cairo_surface_set_device_scale (thumbnail, scale, scale);
+ cr = cairo_create (thumbnail);
+ cairo_scale (cr, ratio, ratio);
+ gdk_cairo_set_source_window (cr, window, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ if (gdk_x11_display_error_trap_pop (gdk_window_get_display (window)))
+ {
+ cairo_surface_destroy (thumbnail);
+ thumbnail = NULL;
+ }
+
+ g_object_unref (window);
return thumbnail;
}
+static int g_int_compare(gconstpointer a, gconstpointer b)
+{
+ gint a_val = GPOINTER_TO_INT(a);
+ gint b_val = GPOINTER_TO_INT(b);
+ if (a_val > b_val) return -1;
+ if (a_val == b_val) return 0;
+ return 1;
+}
+
+static int find_offset(GList *list, gdouble target)
+{
+ GList *node = list;
+ while (node != NULL) {
+ int value = GPOINTER_TO_INT(node->data);
+ if (value <= target)
+ return value;
+ node = node->next;
+ }
+ return -1;
+}
+
#define PREVIEW_PADDING 5
-static void preview_window_reposition (TasklistData *tasklist, GdkPixbuf *thumbnail)
+static void
+preview_window_reposition (WnckTasklist *tl,
+ TasklistData *tasklist,
+ int width,
+ int height,
+ int scale)
{
+ /* Known issues:
+ * - When grouping is toggled the previews won't be centered correctly until a new window is opened or one is closed.
+ * - Previews are not shown at all for grouped windows, this function is not called when hovering over those.
+ */
+
GdkMonitor *monitor;
GdkRectangle monitor_geom;
- int x_pos, y_pos;
- int width, height;
+ MatePanelAppletOrient orient;
+ gdouble x_pos, y_pos;
+ int x_offset, y_offset;
- width = gdk_pixbuf_get_width (thumbnail);
- height = gdk_pixbuf_get_height (thumbnail);
-
- /* Resize window to fit thumbnail */
- gtk_window_resize (GTK_WINDOW (tasklist->preview), width, height);
-
- /* Set position at pointer, then re-adjust from there to just outside of the pointer */
- gtk_window_set_position (GTK_WINDOW (tasklist->preview), GTK_WIN_POS_MOUSE);
- gtk_window_get_position (GTK_WINDOW (tasklist->preview), &x_pos, &y_pos);
+ /* Get mouse position */
+ gdk_device_get_position_double (gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())), NULL, &x_pos, &y_pos);
/* Get geometry of monitor where tasklist is located to calculate correct position of preview */
monitor = gdk_display_get_monitor_at_point (gdk_display_get_default (), x_pos, y_pos);
gdk_monitor_get_geometry (monitor, &monitor_geom);
+ /* Get the position where the window list applet starts */
+ gdk_window_get_origin (gtk_widget_get_window (gtk_widget_get_parent (GTK_WIDGET(tl))), &x_offset, &y_offset);
+
+ /* Get panel orientation */
+ orient = mate_panel_applet_get_orient (MATE_PANEL_APPLET (tasklist->applet));
+
/* Add padding to clear the panel */
- switch (mate_panel_applet_get_orient (MATE_PANEL_APPLET (tasklist->applet)))
+ switch (orient)
{
case MATE_PANEL_APPLET_ORIENT_LEFT:
- x_pos = monitor_geom.width + monitor_geom.x - (width + tasklist->size) - PREVIEW_PADDING;
+ x_pos = monitor_geom.width + monitor_geom.x - width - tasklist->size - PREVIEW_PADDING;
break;
case MATE_PANEL_APPLET_ORIENT_RIGHT:
x_pos = tasklist->size + PREVIEW_PADDING;
break;
case MATE_PANEL_APPLET_ORIENT_UP:
- y_pos = monitor_geom.height + monitor_geom.y - (height + tasklist->size) - PREVIEW_PADDING;
+ y_pos = monitor_geom.height + monitor_geom.y - height - tasklist->size - PREVIEW_PADDING;
break;
case MATE_PANEL_APPLET_ORIENT_DOWN:
default:
@@ -253,24 +385,77 @@ static void preview_window_reposition (TasklistData *tasklist, GdkPixbuf *thumbn
break;
}
+ /* Collect the allocation.x/y values of each button into lists.
+ * We need to iterate over all of them because grouped buttons will be the last children,
+ * even though they are positioned at the beginning. And not all buttons will have the exact same width.
+ * This allows us to avoid off-by-one errors that would cause the preview to be positioned over the adjacent button. */
+ GList *alloc_x_list = NULL;
+ GList *alloc_y_list = NULL;
+ GtkAllocation last_alloc;
+ GList* children = gtk_container_get_children (GTK_CONTAINER(tl));
+ while (children != NULL)
+ {
+ if (g_strcmp0 (gtk_widget_get_name (children->data), "tasklist-button") == 0) {
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (children->data, &alloc);
+
+ /* Skip grouped buttons: these usually have alloc width/heigh=1, except right after grouping is toggled.
+ * Then simply open or close a new window to get the correct offset. */
+ if (alloc.width < 2 || alloc.height < 2)
+ {
+ children = children->next;
+ continue;
+ }
+
+ /* Keep x and y offsets in sorted lists */
+ alloc_x_list = g_list_insert_sorted (alloc_x_list, GINT_TO_POINTER(alloc.x), g_int_compare);
+ alloc_y_list = g_list_insert_sorted (alloc_y_list, GINT_TO_POINTER(alloc.y), g_int_compare);
+
+ /* The width/height from the last allocation will be used for centering the preview.
+ * It might be off by a pixel because not all buttons have the exact same width/height but this isn't critical. */
+ last_alloc = alloc;
+ }
+ children = children->next;
+ }
+
+ /* Center preview at the midpoint of the tasklist button */
+ if (orient == MATE_PANEL_APPLET_ORIENT_LEFT || orient == MATE_PANEL_APPLET_ORIENT_RIGHT)
+ {
+ /* Vertical panel */
+ y_pos = y_offset + find_offset (alloc_y_list, y_pos - y_offset) + (last_alloc.height - height) / 2;
+ y_pos = y_pos < PREVIEW_PADDING ? PREVIEW_PADDING : y_pos;
+ }
+ else if (orient == MATE_PANEL_APPLET_ORIENT_UP || orient == MATE_PANEL_APPLET_ORIENT_DOWN)
+ {
+ /* Horizontal panel */
+ x_pos = x_offset + find_offset (alloc_x_list, x_pos - x_offset) + (last_alloc.width - width) / 2;
+ x_pos = x_pos < PREVIEW_PADDING ? PREVIEW_PADDING : x_pos;
+ }
+
+ g_list_free (alloc_x_list);
+ g_list_free (alloc_y_list);
+
gtk_window_move (GTK_WINDOW (tasklist->preview), x_pos, y_pos);
}
-static gboolean preview_window_draw (GtkWidget *widget, cairo_t *cr, GdkPixbuf *thumbnail)
+static gboolean preview_window_draw (GtkWidget *widget, cairo_t *cr, cairo_surface_t *thumbnail)
{
GtkStyleContext *context;
context = gtk_widget_get_style_context (widget);
- gtk_render_icon (context, cr, thumbnail, 0, 0);
+ gtk_render_icon_surface (context, cr, thumbnail, 0, 0);
return FALSE;
}
static gboolean applet_enter_notify_event (WnckTasklist *tl, GList *wnck_windows, TasklistData *tasklist)
{
- GdkPixbuf *thumbnail;
+ cairo_surface_t *thumbnail;
WnckWindow *wnck_window = NULL;
int n_windows;
+ int thumbnail_width;
+ int thumbnail_height;
+ int thumbnail_scale;
if (tasklist->preview != NULL)
{
@@ -298,7 +483,7 @@ static gboolean applet_enter_notify_event (WnckTasklist *tl, GList *wnck_windows
wnck_screen_get_active_workspace (wnck_screen_get_default ())))
return FALSE;
- thumbnail = preview_window_thumbnail (wnck_window, tasklist);
+ thumbnail = preview_window_thumbnail (wnck_window, tasklist, &thumbnail_width, &thumbnail_height, &thumbnail_scale);
if (thumbnail == NULL)
return FALSE;
@@ -307,13 +492,16 @@ static gboolean applet_enter_notify_event (WnckTasklist *tl, GList *wnck_windows
tasklist->preview = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_set_app_paintable (tasklist->preview, TRUE);
+ gtk_window_set_default_size (GTK_WINDOW (tasklist->preview), thumbnail_width/thumbnail_scale, thumbnail_height/thumbnail_scale);
gtk_window_set_resizable (GTK_WINDOW (tasklist->preview), TRUE);
-
- preview_window_reposition (tasklist, thumbnail);
+ preview_window_reposition (tl, tasklist, thumbnail_width/thumbnail_scale, thumbnail_height/thumbnail_scale, thumbnail_scale);
gtk_widget_show (tasklist->preview);
- g_signal_connect_data (G_OBJECT (tasklist->preview), "draw", G_CALLBACK (preview_window_draw), thumbnail, (GClosureNotify) G_CALLBACK (g_object_unref), 0);
+ g_signal_connect_data (tasklist->preview, "draw",
+ G_CALLBACK (preview_window_draw), thumbnail,
+ (GClosureNotify) G_CALLBACK (cairo_surface_destroy),
+ 0);
return FALSE;
}
@@ -328,7 +516,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)
{
@@ -401,9 +590,7 @@ static void tasklist_properties_update_content_radio(TasklistData* tasklist)
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
- gtk_widget_set_sensitive(tasklist->minimized_windows_label, tasklist->include_all_workspaces);
- gtk_widget_set_sensitive(tasklist->move_minimized_radio, tasklist->include_all_workspaces);
- gtk_widget_set_sensitive(tasklist->change_workspace_radio, tasklist->include_all_workspaces);
+ gtk_widget_set_sensitive(tasklist->minimized_windows_box, tasklist->include_all_workspaces);
}
static void display_all_workspaces_changed(GSettings* settings, gchar* key, TasklistData* tasklist)
@@ -431,6 +618,11 @@ static void tasklist_update_thumbnail_size_spin(TasklistData* tasklist)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), (gdouble)tasklist->thumbnail_size);
}
+static void show_thumbnails_changed(GSettings* settings, gchar* key, TasklistData* tasklist)
+{
+ tasklist->show_window_thumbnails = g_settings_get_boolean (settings, key);
+}
+
static void thumbnail_size_changed(GSettings *settings, gchar* key, TasklistData* tasklist)
{
tasklist->thumbnail_size = g_settings_get_int(settings, key);
@@ -438,18 +630,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;
}
@@ -457,7 +649,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);
@@ -493,7 +685,6 @@ static void tasklist_update_unminimization_radio(TasklistData* tasklist)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
}
-
static void move_unminimized_windows_changed(GSettings* settings, gchar* key, TasklistData* tasklist)
{
gboolean value;
@@ -506,6 +697,18 @@ static void move_unminimized_windows_changed(GSettings* settings, gchar* key, Ta
tasklist_update_unminimization_radio(tasklist);
}
+static void scroll_enabled_changed (GSettings* settings, gchar* key, TasklistData* tasklist)
+{
+ tasklist->scroll_enable = g_settings_get_boolean (settings, key);
+ tasklist_update(tasklist);
+}
+
+static void middle_click_close_changed (GSettings* settings, gchar* key, TasklistData* tasklist)
+{
+ tasklist->middle_click_close = g_settings_get_boolean (settings, key);
+ tasklist_update(tasklist);
+}
+
static void setup_gsettings(TasklistData* tasklist)
{
tasklist->settings = mate_panel_applet_settings_new (MATE_PANEL_APPLET (tasklist->applet), WINDOW_LIST_SCHEMA);
@@ -519,6 +722,11 @@ static void setup_gsettings(TasklistData* tasklist)
tasklist->preview_settings = mate_panel_applet_settings_new (MATE_PANEL_APPLET (tasklist->applet), WINDOW_LIST_PREVIEW_SCHEMA);
g_signal_connect (tasklist->preview_settings,
+ "changed::show-window-thumbnails",
+ G_CALLBACK (show_thumbnails_changed),
+ tasklist);
+
+ g_signal_connect (tasklist->preview_settings,
"changed::thumbnail-window-size",
G_CALLBACK (thumbnail_size_changed),
tasklist);
@@ -531,6 +739,14 @@ static void setup_gsettings(TasklistData* tasklist)
"changed::move-unminimized-windows",
G_CALLBACK (move_unminimized_windows_changed),
tasklist);
+ g_signal_connect (tasklist->settings,
+ "changed::scroll-enabled",
+ G_CALLBACK (scroll_enabled_changed),
+ tasklist);
+ g_signal_connect (tasklist->settings,
+ "changed::middle-click-close",
+ G_CALLBACK (middle_click_close_changed),
+ tasklist);
}
static void applet_size_allocate(GtkWidget *widget, GtkAllocation *allocation, TasklistData *tasklist)
@@ -538,7 +754,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);
@@ -565,6 +781,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;
@@ -610,6 +828,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)
{
@@ -651,6 +870,10 @@ gboolean window_list_applet_fill(MatePanelApplet* applet)
tasklist->move_unminimized_windows = g_settings_get_boolean (tasklist->settings, "move-unminimized-windows");
+ tasklist->scroll_enable = g_settings_get_boolean (tasklist->settings, "scroll-enabled");
+
+ tasklist->middle_click_close = g_settings_get_boolean (tasklist->settings, "middle-click-close");
+
tasklist->size = mate_panel_applet_get_size(applet);
#if !defined(WNCKLET_INPROCESS) && !GTK_CHECK_VERSION (3, 23, 0)
@@ -670,38 +893,69 @@ 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_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 (tasklist->tasklist, "task-enter-notify",
+ G_CALLBACK (applet_enter_notify_event),
+ tasklist);
+ g_signal_connect (tasklist->tasklist, "task-leave-notify",
+ G_CALLBACK (applet_leave_notify_event),
+ tasklist);
+#endif /* HAVE_WINDOW_PREVIEWS */
+ }
+ else
+#endif /* HAVE_X11 */
- g_signal_connect(G_OBJECT(tasklist->applet), "size_allocate", G_CALLBACK(applet_size_allocate), tasklist);
+#ifdef HAVE_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()))
+ {
+ tasklist->tasklist = wayland_tasklist_new();
+ }
+ else
+#endif /* HAVE_WAYLAND */
- gtk_container_add(GTK_CONTAINER(tasklist->applet), tasklist->tasklist);
+ {
+ tasklist->tasklist = gtk_label_new ("[Tasklist not supported on this platform]");
+ }
- g_signal_connect(G_OBJECT(tasklist->applet), "realize", G_CALLBACK(applet_realized), tasklist);
- g_signal_connect(G_OBJECT(tasklist->applet), "change_orient", G_CALLBACK(applet_change_orient), tasklist);
- g_signal_connect(G_OBJECT(tasklist->applet), "change_size", G_CALLBACK(applet_change_pixel_size), tasklist);
- g_signal_connect(G_OBJECT(tasklist->applet), "change_background", G_CALLBACK(applet_change_background), tasklist);
+ tasklist_apply_orientation(tasklist);
- mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(tasklist->applet), GTK_WIDGET(tasklist->applet));
+ g_signal_connect (tasklist->tasklist, "destroy",
+ G_CALLBACK (destroy_tasklist),
+ tasklist);
+ g_signal_connect (tasklist->applet, "size-allocate",
+ G_CALLBACK (applet_size_allocate),
+ tasklist);
+
+ gtk_container_add(GTK_CONTAINER(tasklist->applet), tasklist->tasklist);
+
+ g_signal_connect (tasklist->applet, "realize",
+ G_CALLBACK (applet_realized),
+ tasklist);
+ g_signal_connect (tasklist->applet, "change-orient",
+ G_CALLBACK (applet_change_orient),
+ tasklist);
+ g_signal_connect (tasklist->applet, "change-size",
+ G_CALLBACK (applet_change_pixel_size),
+ tasklist);
+ g_signal_connect (tasklist->applet, "change-background",
+ G_CALLBACK(applet_change_background),
+ tasklist);
action_group = gtk_action_group_new("Tasklist Applet Actions");
gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
gtk_action_group_add_actions(action_group, tasklist_menu_actions, G_N_ELEMENTS(tasklist_menu_actions), tasklist);
-
/* disable the item of system monitor, if not exists.
* example, mate-system-monitor, o gnome-system-monitor */
char* programpath;
- int i;
+ gsize i;
for (i = 0; i < G_N_ELEMENTS(system_monitors); i += 1)
{
@@ -723,7 +977,6 @@ gboolean window_list_applet_fill(MatePanelApplet* applet)
_system_monitor_found:;
/* end of system monitor item */
-
mate_panel_applet_setup_menu_from_resource (MATE_PANEL_APPLET (tasklist->applet),
WNCKLET_RESOURCE_PATH "window-list-menu.xml",
action_group);
@@ -747,12 +1000,11 @@ gboolean window_list_applet_fill(MatePanelApplet* applet)
static void call_system_monitor(GtkAction* action, TasklistData* tasklist)
{
- char *programpath;
- int i;
+ gsize i;
for (i = 0; i < G_N_ELEMENTS(system_monitors); i += 1)
{
- programpath = g_find_program_in_path(system_monitors[i]);
+ char *programpath = g_find_program_in_path(system_monitors[i]);
if (programpath != NULL)
{
@@ -766,7 +1018,6 @@ static void call_system_monitor(GtkAction* action, TasklistData* tasklist)
}
}
-
static void display_help_dialog(GtkAction* action, TasklistData* tasklist)
{
wncklet_display_help(tasklist->applet, "mate-user-guide", "windowlist", WINDOW_LIST_ICON);
@@ -794,13 +1045,13 @@ static void display_about_dialog(GtkAction* action, TasklistData* tasklist)
"comments", _("The Window List shows a list of all windows in a set of buttons and lets you browse them."),
"copyright", _("Copyright \xc2\xa9 2002 Red Hat, Inc.\n"
"Copyright \xc2\xa9 2011 Perberos\n"
- "Copyright \xc2\xa9 2012-2020 MATE developers"),
+ "Copyright \xc2\xa9 2012-2021 MATE developers"),
"documenters", documenters,
"icon-name", WINDOW_LIST_ICON,
"logo-icon-name", WINDOW_LIST_ICON,
"translator-credits", _("translator-credits"),
"version", VERSION,
- "website", "http://www.mate-desktop.org/",
+ "website", PACKAGE_URL,
NULL);
}
@@ -861,13 +1112,26 @@ static void setup_sensitivity(TasklistData* tasklist, GtkBuilder* builder, const
}
}
+#ifdef HAVE_WAYLAND
+static void setup_dialog_wayland(TasklistData* tasklist)
+{
+ gtk_widget_show(tasklist->wayland_info_label);
+
+ gtk_widget_set_sensitive(tasklist->window_list_content_box, FALSE);
+ gtk_widget_set_sensitive(tasklist->window_grouping_box, FALSE);
+ gtk_widget_set_sensitive(tasklist->minimized_windows_box, FALSE);
+
+#ifdef HAVE_WINDOW_PREVIEWS
+ gtk_widget_set_sensitive(tasklist->window_thumbnail_box, FALSE);
+#endif /* HAVE_WINDOW_PREVIEWS */
+}
+#endif /* HAVE_WAYLAND */
+
static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist)
{
GtkWidget* button;
-#ifdef HAVE_WINDOW_PREVIEWS
- GtkAdjustment *adjustment;
-#endif
+ tasklist->wayland_info_label = WID("wayland_info_label");
tasklist->show_current_radio = WID("show_current_radio");
tasklist->show_all_radio = WID("show_all_radio");
@@ -880,6 +1144,7 @@ static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist)
setup_sensitivity(tasklist, builder, "never_group_radio", "auto_group_radio", "always_group_radio", "group-windows" /* key */);
#ifdef HAVE_WINDOW_PREVIEWS
+ tasklist->window_thumbnail_box = WID("window_thumbnail_box");
tasklist->show_thumbnails_check = WID("show_thumbnails_check");
tasklist->thumbnail_size_label = WID("thumbnail_size_label");
tasklist->thumbnail_size_spin = WID("thumbnail_size_spin");
@@ -895,17 +1160,17 @@ static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist)
g_object_bind_property(tasklist->show_thumbnails_check, "active", tasklist->thumbnail_size_label, "sensitive", G_BINDING_DEFAULT);
g_object_bind_property(tasklist->show_thumbnails_check, "active", tasklist->thumbnail_size_spin, "sensitive", G_BINDING_DEFAULT);
- adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(tasklist->thumbnail_size_spin));
- gtk_adjustment_set_lower (adjustment, 0);
- gtk_adjustment_set_upper (adjustment, 999);
- gtk_adjustment_set_step_increment (adjustment, 1);
#else
- gtk_widget_hide(WID("window_thumbnails"));
+ gtk_widget_hide(WID("window_thumbnail_box"));
#endif
- tasklist->minimized_windows_label = WID("minimized_windows_label");
tasklist->move_minimized_radio = WID("move_minimized_radio");
tasklist->change_workspace_radio = WID("change_workspace_radio");
+ tasklist->mouse_scroll_check = WID("mouse_scroll_check");
+ tasklist->middle_click_close_check = WID("middle_click_close_check");
+ tasklist->minimized_windows_box = WID("minimized_windows_box");
+ tasklist->window_grouping_box = WID("window_grouping_box");
+ tasklist->window_list_content_box = WID("window_list_content_box");
setup_sensitivity(tasklist, builder, "move_minimized_radio", "change_workspace_radio", NULL, "move-unminimized-windows" /* key */);
@@ -916,26 +1181,62 @@ static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist)
g_object_set_data(G_OBJECT(tasklist->auto_group_radio), "group_value", "auto");
g_object_set_data(G_OBJECT(tasklist->always_group_radio), "group_value", "always");
- g_signal_connect(G_OBJECT(tasklist->never_group_radio), "toggled", (GCallback) group_windows_toggled, tasklist);
- g_signal_connect(G_OBJECT(tasklist->auto_group_radio), "toggled", (GCallback) group_windows_toggled, tasklist);
- g_signal_connect(G_OBJECT(tasklist->always_group_radio), "toggled", (GCallback) group_windows_toggled, tasklist);
+ g_signal_connect (tasklist->never_group_radio, "toggled",
+ (GCallback) group_windows_toggled,
+ tasklist);
+ g_signal_connect (tasklist->auto_group_radio, "toggled",
+ (GCallback) group_windows_toggled,
+ tasklist);
+ g_signal_connect (tasklist->always_group_radio, "toggled",
+ (GCallback) group_windows_toggled,
+ tasklist);
+
+ /* Mouse Scroll: */
+ g_settings_bind (tasklist->settings,
+ "scroll-enabled",
+ tasklist->mouse_scroll_check,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ /* Middle mouse click to close window: */
+ g_settings_bind (tasklist->settings,
+ "middle-click-close",
+ tasklist->middle_click_close_check,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
#ifdef HAVE_WINDOW_PREVIEWS
/* change thumbnail size: */
tasklist_update_thumbnail_size_spin(tasklist);
- g_signal_connect(G_OBJECT(tasklist->thumbnail_size_spin), "value-changed", (GCallback) thumbnail_size_spin_changed, tasklist);
+ g_signal_connect (tasklist->thumbnail_size_spin, "value-changed",
+ (GCallback) thumbnail_size_spin_changed,
+ tasklist);
#endif
/* move window when unminimizing: */
tasklist_update_unminimization_radio(tasklist);
- g_signal_connect(G_OBJECT(tasklist->move_minimized_radio), "toggled", (GCallback) move_minimized_toggled, tasklist);
+ g_signal_connect (tasklist->move_minimized_radio, "toggled",
+ (GCallback) move_minimized_toggled,
+ tasklist);
/* Tasklist content: */
tasklist_properties_update_content_radio (tasklist);
- g_signal_connect(G_OBJECT(tasklist->show_all_radio), "toggled", (GCallback) display_all_workspaces_toggled, tasklist);
-
- g_signal_connect_swapped(WID("done_button"), "clicked", (GCallback) gtk_widget_hide, tasklist->properties_dialog);
- g_signal_connect(tasklist->properties_dialog, "response", G_CALLBACK(response_cb), tasklist);
+ g_signal_connect (tasklist->show_all_radio, "toggled",
+ (GCallback) display_all_workspaces_toggled,
+ tasklist);
+
+ g_signal_connect_swapped (WID ("done_button"), "clicked",
+ (GCallback) gtk_widget_hide,
+ tasklist->properties_dialog);
+ g_signal_connect (tasklist->properties_dialog, "response",
+ G_CALLBACK (response_cb),
+ tasklist);
+
+#ifdef HAVE_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
+ setup_dialog_wayland(tasklist);
+ }
+#endif /* HAVE_WAYLAND */
}
static void display_properties_dialog(GtkAction* action, TasklistData* tasklist)