Bug#1101701: marco: lag of orca when using alt + tab when certain applications are launched
Package: marco
Version: 1.26.2-4.1
Severity: important
Tags: a11y patch upstream
Dear Maintainer,
with orca running, slowdowns have been observed when using the alt + tab
shortcut when QT applications are launched.
after investigation by orca (1), it has been shown that the bug
originated from
marco. the attached patch corrects the problem.
(1): https://gitlab.gnome.org/GNOME/orca/-/issues/430
pr upstr eam: https://github.com/mate-desktop/marco/pull/773
thanks !
-- System Information:
Debian Release: trixie/sid
APT prefers testing
APT policy: (500, 'testing'), (50, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 6.12.20-amd64 (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_FORCED_RMMOD, TAINT_OOT_MODULE,
TAINT_UNSIGNED_MODULE
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE
not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages marco depends on:
ii libc6 2.41-6
ii libcairo2 1.18.4-1+b1
ii libgdk-pixbuf-2.0-0 2.42.12+dfsg-2
ii libglib2.0-0t64 [libglib2.0-0] 2.84.0-2
ii libgtk-3-0t64 [libgtk-3-0] 3.24.49-2
ii libmarco-private2 1.26.2-4.1
ii libpango-1.0-0 1.56.3-1
ii libx11-6 2:1.8.12-1
ii marco-common 1.26.2-4.1
ii mate-desktop-common 1.26.2-1.2
ii zenity 4.1.90-1
marco recommends no packages.
marco suggests no packages.
-- no debconf information
diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c
index abd37b6d..892de65b 100644
--- a/src/ui/tabpopup.c
+++ b/src/ui/tabpopup.c
@@ -36,6 +36,7 @@
#include "../core/frame-private.h"
#include "draw-workspace.h"
#include <gtk/gtk.h>
+#include <gtk/gtk-a11y.h>
#include <gdk/gdkx.h>
#include <math.h>
@@ -70,6 +71,14 @@ struct _MetaTabPopup
gint border;
};
+typedef GtkWindowAccessibleClass MetaTabPopupWindowAccessibleClass;
+typedef GtkWindowAccessible MetaTabPopupWindowAccessible;
+typedef GtkWindowClass MetaTabPopupWindowClass;
+typedef GtkWindow MetaTabPopupWindow;
+
+static GType meta_tab_popup_window_get_type (void);
+static GType meta_tab_popup_window_accessible_get_type (void);
+
static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf, cairo_surface_t *win_surface);
static void select_image (GtkWidget *widget);
static void unselect_image (GtkWidget *widget);
@@ -79,6 +88,65 @@ static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace,
static void select_workspace (GtkWidget *widget);
static void unselect_workspace (GtkWidget *widget);
+G_DEFINE_TYPE (MetaTabPopupWindowAccessible, meta_tab_popup_window_accessible, GTK_TYPE_WINDOW_ACCESSIBLE)
+G_DEFINE_TYPE (MetaTabPopupWindow, meta_tab_popup_window, GTK_TYPE_WINDOW)
+
+/*--- Accessible implementation for the popup window to report itself as active
+ * when a switch is in progress. We need special handling because the
+ * actual interaction is done through key grabs, and thus GTK doesn't see
+ * the switcher window as active, but that confuses some ATs that are
+ * looking for the active window and find nothing. ---*/
+static AtkStateSet *
+meta_tab_popup_window_accessible_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ state_set = ATK_OBJECT_CLASS (meta_tab_popup_window_accessible_parent_class)->ref_state_set (accessible);
+
+ if (gtk_widget_get_visible (widget))
+ atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
+
+ return state_set;
+}
+
+static void
+meta_tab_popup_window_accessible_class_init (MetaTabPopupWindowAccessibleClass *cls)
+{
+ AtkObjectClass *atk_cls = ATK_OBJECT_CLASS (cls);
+
+ atk_cls->ref_state_set = meta_tab_popup_window_accessible_ref_state_set;
+}
+
+static void
+meta_tab_popup_window_accessible_init (MetaTabPopupWindowAccessible *self)
+{
+}
+
+/*--- Custom GtkWindow subclass, mainly to be able to have our own accessible
+ * implementation overrides ---*/
+static void
+meta_tab_popup_window_class_init (MetaTabPopupWindowClass *cls)
+{
+ gtk_widget_class_set_accessible_type (GTK_WIDGET_CLASS (cls), meta_tab_popup_window_accessible_get_type ());
+}
+
+static void
+meta_tab_popup_window_init (MetaTabPopupWindow *self)
+{
+}
+
+/* Creates a MetaTabPopupWindow instance with the required defaults */
+static GtkWidget *
+meta_tab_popup_window_new (void)
+{
+ return g_object_new (meta_tab_popup_window_get_type (), "type", GTK_WINDOW_POPUP, NULL);
+}
+
static gboolean
outline_window_draw (GtkWidget *widget,
cairo_t *cr,
@@ -285,7 +353,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
else
popup->outline_window = NULL;
- popup->window = gtk_window_new (GTK_WINDOW_POPUP);
+ popup->window = meta_tab_popup_window_new ();
gtk_window_set_screen (GTK_WINDOW (popup->window), screen);
gtk_window_set_position (GTK_WINDOW (popup->window), GTK_WIN_POS_CENTER_ALWAYS);
@@ -340,13 +408,6 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
popup->label = gtk_label_new ("");
- /* Set the accessible role of the label to a status bar so it
- * will emit name changed events that can be used by screen
- * readers.
- */
- obj = gtk_widget_get_accessible (popup->label);
- atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
-
gtk_widget_set_margin_start (popup->label, 16);
gtk_widget_set_margin_end (popup->label, 16);
gtk_widget_set_margin_top (popup->label, 0);
@@ -421,6 +482,15 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
/* Make it so that we ellipsize if the text is too long */
gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
+ /* Set the accessible role of the label to a status bar so it
+ * will emit name changed events that can be used by screen
+ * readers.
+ * We do this *after* messing with the label content for computing the size
+ * not to send a change even for each entry at start.
+ */
+ obj = gtk_widget_get_accessible (popup->label);
+ atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
+
int default_window_width = 0; /* 0 == small as possible, truncate label */
if (expand_for_titles && top <= 1 && left < width)
Reply to: