[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
This commit is contained in:
parent
6259513b0f
commit
adbf3b1c37
@ -3,7 +3,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "shell-global-private.h"
|
#include "shell-global-private.h"
|
||||||
|
#include "shell-enum-types.h"
|
||||||
#include "shell-perf-log.h"
|
#include "shell-perf-log.h"
|
||||||
|
#include "shell-window-tracker.h"
|
||||||
#include "shell-wm.h"
|
#include "shell-wm.h"
|
||||||
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
@ -74,6 +76,7 @@ enum {
|
|||||||
PROP_SCREEN_WIDTH,
|
PROP_SCREEN_WIDTH,
|
||||||
PROP_SCREEN_HEIGHT,
|
PROP_SCREEN_HEIGHT,
|
||||||
PROP_STAGE,
|
PROP_STAGE,
|
||||||
|
PROP_STAGE_INPUT_MODE,
|
||||||
PROP_WINDOW_GROUP,
|
PROP_WINDOW_GROUP,
|
||||||
PROP_WINDOW_MANAGER,
|
PROP_WINDOW_MANAGER,
|
||||||
PROP_SETTINGS,
|
PROP_SETTINGS,
|
||||||
@ -90,8 +93,14 @@ shell_global_set_property(GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
|
ShellGlobal *global = SHELL_GLOBAL (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
|
case PROP_STAGE_INPUT_MODE:
|
||||||
|
shell_global_set_stage_input_mode (global, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -136,6 +145,9 @@ shell_global_get_property(GObject *object,
|
|||||||
case PROP_STAGE:
|
case PROP_STAGE:
|
||||||
g_value_set_object (value, mutter_plugin_get_stage (global->plugin));
|
g_value_set_object (value, mutter_plugin_get_stage (global->plugin));
|
||||||
break;
|
break;
|
||||||
|
case PROP_STAGE_INPUT_MODE:
|
||||||
|
g_value_set_enum (value, global->input_mode);
|
||||||
|
break;
|
||||||
case PROP_WINDOW_GROUP:
|
case PROP_WINDOW_GROUP:
|
||||||
g_value_set_object (value, mutter_plugin_get_window_group (global->plugin));
|
g_value_set_object (value, mutter_plugin_get_window_group (global->plugin));
|
||||||
break;
|
break;
|
||||||
@ -254,6 +266,14 @@ shell_global_class_init (ShellGlobalClass *klass)
|
|||||||
"Stage holding the desktop scene graph",
|
"Stage holding the desktop scene graph",
|
||||||
CLUTTER_TYPE_ACTOR,
|
CLUTTER_TYPE_ACTOR,
|
||||||
G_PARAM_READABLE));
|
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,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_WINDOW_GROUP,
|
PROP_WINDOW_GROUP,
|
||||||
g_param_spec_object ("window-group",
|
g_param_spec_object ("window-group",
|
||||||
@ -341,6 +361,32 @@ shell_global_get (void)
|
|||||||
return the_object;
|
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:
|
* shell_global_set_stage_input_mode:
|
||||||
* @global: the #ShellGlobal
|
* @global: the #ShellGlobal
|
||||||
@ -355,6 +401,12 @@ shell_global_get (void)
|
|||||||
* outside that region. When it is %SHELL_STAGE_INPUT_MODE_FULLSCREEN,
|
* outside that region. When it is %SHELL_STAGE_INPUT_MODE_FULLSCREEN,
|
||||||
* the stage absorbs all input.
|
* 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,
|
* Note that whenever a mutter-internal Gtk widget has a pointer grab,
|
||||||
* the shell behaves as though it was in
|
* the shell behaves as though it was in
|
||||||
* %SHELL_STAGE_INPUT_MODE_NONREACTIVE, to ensure that the widget gets
|
* %SHELL_STAGE_INPUT_MODE_NONREACTIVE, to ensure that the widget gets
|
||||||
@ -373,7 +425,14 @@ shell_global_set_stage_input_mode (ShellGlobal *global,
|
|||||||
else
|
else
|
||||||
mutter_plugin_set_stage_input_region (global->plugin, global->input_region);
|
mutter_plugin_set_stage_input_region (global->plugin, global->input_region);
|
||||||
|
|
||||||
|
if (mode == SHELL_STAGE_INPUT_MODE_FOCUSED)
|
||||||
|
shell_global_focus_stage (global);
|
||||||
|
|
||||||
|
if (mode != global->input_mode)
|
||||||
|
{
|
||||||
global->input_mode = 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)
|
MutterPlugin *plugin)
|
||||||
{
|
{
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
|
MetaScreen *screen;
|
||||||
|
MetaDisplay *display;
|
||||||
|
|
||||||
g_return_if_fail (SHELL_IS_GLOBAL (global));
|
g_return_if_fail (SHELL_IS_GLOBAL (global));
|
||||||
g_return_if_fail (global->plugin == NULL);
|
g_return_if_fail (global->plugin == NULL);
|
||||||
@ -563,6 +624,11 @@ _shell_global_set_plugin (ShellGlobal *global,
|
|||||||
"clutter.stagePaintDone",
|
"clutter.stagePaintDone",
|
||||||
"End of stage page repaint",
|
"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
|
void
|
||||||
|
@ -51,6 +51,7 @@ void shell_global_grab_dbus_service (ShellGlobal *global);
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SHELL_STAGE_INPUT_MODE_NONREACTIVE,
|
SHELL_STAGE_INPUT_MODE_NONREACTIVE,
|
||||||
SHELL_STAGE_INPUT_MODE_NORMAL,
|
SHELL_STAGE_INPUT_MODE_NORMAL,
|
||||||
|
SHELL_STAGE_INPUT_MODE_FOCUSED,
|
||||||
SHELL_STAGE_INPUT_MODE_FULLSCREEN
|
SHELL_STAGE_INPUT_MODE_FULLSCREEN
|
||||||
} ShellStageInputMode;
|
} ShellStageInputMode;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user