[gnome-shell] [ShellGlobal] add SHELL_STAGE_INPUT_MODE_FOCUSED



commit adbf3b1c375fa8dfb279ff19ce8953ecf698943b
Author: Dan Winship <danw gnome org>
Date:   Fri Jul 2 13:36:13 2010 -0400

    [ShellGlobal] add SHELL_STAGE_INPUT_MODE_FOCUSED
    
    Add SHELL_STAGE_INPUT_MODE_FOCUSED, to move the keyboard focus to the
    shell without grabbing the keyboard or mouse, and make
    stage_input_mode into a GObject property so that (among other things),
    callers can tell when MODE_FOCUSED reverts back to MODE_NORMAL.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=623429

 src/shell-global.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/shell-global.h |    1 +
 2 files changed, 68 insertions(+), 1 deletions(-)
---
diff --git a/src/shell-global.c b/src/shell-global.c
index 94b57c5..f2f2d08 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -3,7 +3,9 @@
 #include "config.h"
 
 #include "shell-global-private.h"
+#include "shell-enum-types.h"
 #include "shell-perf-log.h"
+#include "shell-window-tracker.h"
 #include "shell-wm.h"
 
 #include "display.h"
@@ -74,6 +76,7 @@ enum {
   PROP_SCREEN_WIDTH,
   PROP_SCREEN_HEIGHT,
   PROP_STAGE,
+  PROP_STAGE_INPUT_MODE,
   PROP_WINDOW_GROUP,
   PROP_WINDOW_MANAGER,
   PROP_SETTINGS,
@@ -90,8 +93,14 @@ shell_global_set_property(GObject         *object,
                           const GValue    *value,
                           GParamSpec      *pspec)
 {
+  ShellGlobal *global = SHELL_GLOBAL (object);
+
   switch (prop_id)
     {
+    case PROP_STAGE_INPUT_MODE:
+      shell_global_set_stage_input_mode (global, g_value_get_enum (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -136,6 +145,9 @@ shell_global_get_property(GObject         *object,
     case PROP_STAGE:
       g_value_set_object (value, mutter_plugin_get_stage (global->plugin));
       break;
+    case PROP_STAGE_INPUT_MODE:
+      g_value_set_enum (value, global->input_mode);
+      break;
     case PROP_WINDOW_GROUP:
       g_value_set_object (value, mutter_plugin_get_window_group (global->plugin));
       break;
@@ -255,6 +267,14 @@ shell_global_class_init (ShellGlobalClass *klass)
                                                         CLUTTER_TYPE_ACTOR,
                                                         G_PARAM_READABLE));
   g_object_class_install_property (gobject_class,
+                                   PROP_STAGE_INPUT_MODE,
+                                   g_param_spec_enum ("stage-input-mode",
+                                                      "Stage input mode",
+                                                      "The stage input mode",
+                                                      SHELL_TYPE_STAGE_INPUT_MODE,
+                                                      SHELL_STAGE_INPUT_MODE_NORMAL,
+                                                      G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
                                    PROP_WINDOW_GROUP,
                                    g_param_spec_object ("window-group",
                                                         "Window Group",
@@ -341,6 +361,32 @@ shell_global_get (void)
   return the_object;
 }
 
+static void
+focus_window_changed (MetaDisplay *display,
+                      GParamSpec  *param,
+                      gpointer     user_data)
+{
+  ShellGlobal *global = user_data;
+
+  if (global->input_mode == SHELL_STAGE_INPUT_MODE_FOCUSED &&
+      meta_display_get_focus_window (display) != NULL)
+    shell_global_set_stage_input_mode (global, SHELL_STAGE_INPUT_MODE_NORMAL);
+}
+
+static void
+shell_global_focus_stage (ShellGlobal *global)
+{
+  Display *xdpy;
+  ClutterActor *stage;
+  Window xstage;
+
+  stage = mutter_plugin_get_stage (global->plugin);
+  xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+  xdpy = mutter_plugin_get_xdisplay (global->plugin);
+  XSetInputFocus (xdpy, xstage, RevertToPointerRoot,
+                  shell_global_get_current_time (global));
+}
+
 /**
  * shell_global_set_stage_input_mode:
  * @global: the #ShellGlobal
@@ -355,6 +401,12 @@ shell_global_get (void)
  * outside that region. When it is %SHELL_STAGE_INPUT_MODE_FULLSCREEN,
  * the stage absorbs all input.
  *
+ * When the input mode is %SHELL_STAGE_INPUT_MODE_FOCUSED, the pointer
+ * is handled as with %SHELL_STAGE_INPUT_MODE_NORMAL, but additionally
+ * the stage window has the keyboard focus. If the stage loses the
+ * focus (eg, because the user clicked into a window) the input mode
+ * will revert to %SHELL_STAGE_INPUT_MODE_NORMAL.
+ *
  * Note that whenever a mutter-internal Gtk widget has a pointer grab,
  * the shell behaves as though it was in
  * %SHELL_STAGE_INPUT_MODE_NONREACTIVE, to ensure that the widget gets
@@ -373,7 +425,14 @@ shell_global_set_stage_input_mode (ShellGlobal         *global,
   else
     mutter_plugin_set_stage_input_region (global->plugin, global->input_region);
 
-  global->input_mode = mode;
+  if (mode == SHELL_STAGE_INPUT_MODE_FOCUSED)
+    shell_global_focus_stage (global);
+
+  if (mode != global->input_mode)
+    {
+      global->input_mode = mode;
+      g_object_notify (G_OBJECT (global), "stage-input-mode");
+    }
 }
 
 /**
@@ -535,6 +594,8 @@ _shell_global_set_plugin (ShellGlobal  *global,
                           MutterPlugin *plugin)
 {
   ClutterActor *stage;
+  MetaScreen *screen;
+  MetaDisplay *display;
 
   g_return_if_fail (SHELL_IS_GLOBAL (global));
   g_return_if_fail (global->plugin == NULL);
@@ -563,6 +624,11 @@ _shell_global_set_plugin (ShellGlobal  *global,
                                "clutter.stagePaintDone",
                                "End of stage page repaint",
                                "");
+
+  screen = mutter_plugin_get_screen (global->plugin);
+  display = meta_screen_get_display (screen);
+  g_signal_connect (display, "notify::focus-window",
+                    G_CALLBACK (focus_window_changed), global);
 }
 
 void
diff --git a/src/shell-global.h b/src/shell-global.h
index 1dd0be8..db3243e 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -51,6 +51,7 @@ void shell_global_grab_dbus_service (ShellGlobal *global);
 typedef enum {
   SHELL_STAGE_INPUT_MODE_NONREACTIVE,
   SHELL_STAGE_INPUT_MODE_NORMAL,
+  SHELL_STAGE_INPUT_MODE_FOCUSED,
   SHELL_STAGE_INPUT_MODE_FULLSCREEN
 } ShellStageInputMode;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]