[mutter] wayland: manually activate/deactivate stage when taking/dropping grab
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland: manually activate/deactivate stage when taking/dropping grab
- Date: Sat, 28 Mar 2015 15:20:58 +0000 (UTC)
commit 9f17c05a156f9b0d21a1534d1da59d136457bf56
Author: Ray Strode <rstrode redhat com>
Date: Tue Mar 24 12:40:10 2015 -0400
wayland: manually activate/deactivate stage when taking/dropping grab
clutter currently never emits activated or deactivated signals on
the stage object when using the EGL backend. Since the stage never
gets activated, accessibility tools, like orca, don't work.
This commit makes mutter take on the responsibility, by tracking
when the stage gains/loses focus, and then synthesizing stage
CLUTTER_STAGE_STATE_ACTIVATED state events.
A limitation of this approach is that clutter's own notion of
the stage activeness won't reflect mutter's notion of the
stage activeness. This isn't a problem, in practice, and can
be addressed in the medium-term after making changes to
clutter.
https://bugzilla.gnome.org/show_bug.cgi?id=746670
src/backends/meta-stage.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
src/backends/meta-stage.h | 3 ++
src/core/display.c | 4 +++
3 files changed, 73 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index e304441..37f1771 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -41,6 +41,7 @@ typedef struct {
struct _MetaStagePrivate {
MetaOverlay cursor_overlay;
+ gboolean is_active;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
@@ -127,14 +128,40 @@ meta_stage_paint (ClutterActor *actor)
}
static void
+meta_stage_activate (ClutterStage *actor)
+{
+ MetaStage *stage = META_STAGE (actor);
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+
+ CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor);
+
+ priv->is_active = TRUE;
+}
+
+static void
+meta_stage_deactivate (ClutterStage *actor)
+{
+ MetaStage *stage = META_STAGE (actor);
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+
+ CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor);
+
+ priv->is_active = FALSE;
+}
+
+static void
meta_stage_class_init (MetaStageClass *klass)
{
+ ClutterStageClass *stage_class = (ClutterStageClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint;
+
+ stage_class->activate = meta_stage_activate;
+ stage_class->deactivate = meta_stage_deactivate;
}
static void
@@ -195,3 +222,42 @@ meta_stage_set_cursor (MetaStage *stage,
meta_overlay_set (&priv->cursor_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
}
+
+void
+meta_stage_set_active (MetaStage *stage,
+ gboolean is_active)
+{
+ MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+ ClutterEvent event = { 0 };
+
+ /* Used by the native backend to inform accessibility technologies
+ * about when the stage loses and gains input focus.
+ *
+ * For the X11 backend, clutter transparently takes care of this
+ * for us.
+ */
+
+ if (priv->is_active == is_active)
+ return;
+
+ clutter_event_set_stage (&event, CLUTTER_STAGE (stage));
+ event.stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
+
+ if (is_active)
+ event.stage_state.new_state = CLUTTER_STAGE_STATE_ACTIVATED;
+
+ /* Emitting this StageState event will result in the stage getting
+ * activated or deactivated (with the activated or deactivated signal
+ * getting emitted from the stage)
+ *
+ * FIXME: This won't update ClutterStage's own notion of its
+ * activeness. For that we would need to somehow trigger a
+ * _clutter_stage_update_state call, which will probably
+ * require new API in clutter. In practice, nothing relies
+ * on the ClutterStage's own notion of activeness when using
+ * the EGL backend.
+ *
+ * See http://bugzilla.gnome.org/746670
+ */
+ clutter_stage_event (CLUTTER_STAGE (stage), &event);
+}
diff --git a/src/backends/meta-stage.h b/src/backends/meta-stage.h
index 742d14f..262d68f 100644
--- a/src/backends/meta-stage.h
+++ b/src/backends/meta-stage.h
@@ -54,6 +54,9 @@ ClutterActor *meta_stage_new (void);
void meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
+
+void meta_stage_set_active (MetaStage *stage,
+ gboolean is_active);
G_END_DECLS
#endif /* META_STAGE_H */
diff --git a/src/core/display.c b/src/core/display.c
index a99c7f6..53cec6f 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -52,6 +52,7 @@
#include <meta/meta-backend.h>
#include "backends/native/meta-backend-native.h"
#include "backends/x11/meta-backend-x11.h"
+#include "backends/meta-stage.h"
#include <clutter/x11/clutter-x11.h>
#ifdef HAVE_RANDR
@@ -1411,6 +1412,8 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
#ifdef HAVE_WAYLAND
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWindow *focus_window = NULL;
+ MetaBackend *backend = meta_get_backend ();
+ MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
if (!meta_display_windows_are_interactable (display))
focus_window = NULL;
@@ -1421,6 +1424,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
else
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland
surface");
+ meta_stage_set_active (stage, focus_window == NULL);
meta_wayland_compositor_set_input_focus (compositor, focus_window);
meta_wayland_seat_repick (compositor->seat);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]