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.c137
1 files changed, 83 insertions, 54 deletions
diff --git a/applets/wncklet/window-list.c b/applets/wncklet/window-list.c
index dd18fc72..dd065466 100644
--- a/applets/wncklet/window-list.c
+++ b/applets/wncklet/window-list.c
@@ -73,6 +73,7 @@ typedef struct {
/* Properties: */
GtkWidget* properties_dialog;
+ GtkWidget* wayland_info_label;
GtkWidget* show_current_radio;
GtkWidget* show_all_radio;
#ifdef HAVE_WINDOW_PREVIEWS
@@ -119,10 +120,17 @@ static void tasklist_update(TasklistData* 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;
+ 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);
@@ -236,71 +244,87 @@ static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBac
#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;
+ GdkWindow *window_wrapper = NULL;
+ 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)
- return NULL;
+ if ((window = gdk_x11_window_lookup_for_display (gdk_display_get_default (), win)) == NULL)
+ {
+ if ((window = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), win)) == NULL)
+ {
+ return NULL;
+ }
+ else
+ {
+ window_wrapper = window;
+ }
+ }
+ else
+ {
+ g_object_ref (window);
+ }
- 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 */
- if (gdk_pixbuf_get_byte_length (screenshot) == 0)
- {
- 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);
+ 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 (window_wrapper)
+ g_object_unref (window_wrapper);
+ g_object_unref (window);
return thumbnail;
}
#define PREVIEW_PADDING 5
-static void preview_window_reposition (TasklistData *tasklist, GdkPixbuf *thumbnail)
+static void
+preview_window_reposition (TasklistData *tasklist,
+ cairo_surface_t *thumbnail,
+ int width,
+ int height,
+ int scale)
{
GdkMonitor *monitor;
GdkRectangle monitor_geom;
int x_pos, y_pos;
- int width, height;
-
- 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);
@@ -314,13 +338,13 @@ static void preview_window_reposition (TasklistData *tasklist, GdkPixbuf *thumbn
switch (mate_panel_applet_get_orient (MATE_PANEL_APPLET (tasklist->applet)))
{
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/scale + 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/scale + tasklist->size) - PREVIEW_PADDING;
break;
case MATE_PANEL_APPLET_ORIENT_DOWN:
default:
@@ -331,21 +355,24 @@ static void preview_window_reposition (TasklistData *tasklist, GdkPixbuf *thumbn
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)
{
@@ -373,7 +400,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;
@@ -382,13 +409,14 @@ 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 (tasklist, thumbnail, thumbnail_width, thumbnail_height, 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 (G_OBJECT (tasklist->preview), "draw", G_CALLBACK (preview_window_draw), thumbnail, (GClosureNotify) G_CALLBACK (cairo_surface_destroy), 0);
return FALSE;
}
@@ -787,8 +815,6 @@ gboolean window_list_applet_fill(MatePanelApplet* applet)
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);
- mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(tasklist->applet), GTK_WIDGET(tasklist->applet));
-
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);
@@ -889,7 +915,7 @@ 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,
@@ -959,6 +985,8 @@ 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);
@@ -976,6 +1004,7 @@ static void setup_dialog(GtkBuilder* builder, TasklistData* tasklist)
GtkAdjustment *adjustment;
#endif /* HAVE_WINDOW_PREVIEWS */
+ tasklist->wayland_info_label = WID("wayland_info_label");
tasklist->show_current_radio = WID("show_current_radio");
tasklist->show_all_radio = WID("show_all_radio");