diff options
Diffstat (limited to 'applets/wncklet/window-list.c')
-rw-r--r-- | applets/wncklet/window-list.c | 137 |
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"); |