Use new plugin-modality functionality in Mutter
We now have functionality in Mutter to grab the keyboard on behalf of a plugin. This avoids interactions with the key handling code in Mutter that could leave the user with an inconsistent state and no way to get out of it. src/shell-global.[ch]: Change shell_global_grab_keyboard() and shell_global_grab_keyboard() to shell_global_begin_modal() shell_global_end_modal() and call mutter_plugin_begin_modal() mutter_plugin_end_modal() rather than directly grabbing the keyboard. main.js: Call global.begin_modal/end_modal from Main.startModal() and Main.endModal() altTab.js; Remove call to Main.startModal() - we're letting Mutter handle modality for Alt-Tab. main.js lookingGlass.js overview.js runDialog.js: Rename Main.startModal() to Main.beginModal() for consistency with naming in mutter and ShellGlobal. http://bugzilla.gnome.org/show_bug.cgi?id=590686
This commit is contained in:
parent
af9ab5dbb6
commit
799f56fe87
@ -144,8 +144,6 @@ AltTabPopup.prototype = {
|
|||||||
show : function(initialSelection) {
|
show : function(initialSelection) {
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
|
|
||||||
Main.startModal();
|
|
||||||
|
|
||||||
global.window_group.add_actor(this._overlay);
|
global.window_group.add_actor(this._overlay);
|
||||||
this._overlay.raise_top();
|
this._overlay.raise_top();
|
||||||
this._overlay.show();
|
this._overlay.show();
|
||||||
@ -164,8 +162,6 @@ AltTabPopup.prototype = {
|
|||||||
destroy : function() {
|
destroy : function() {
|
||||||
this.actor.destroy();
|
this.actor.destroy();
|
||||||
this._overlay.destroy();
|
this._overlay.destroy();
|
||||||
|
|
||||||
Main.endModal();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
select : function(n) {
|
select : function(n) {
|
||||||
|
@ -555,7 +555,7 @@ LookingGlass.prototype = {
|
|||||||
|
|
||||||
Tweener.removeTweens(this.actor);
|
Tweener.removeTweens(this.actor);
|
||||||
|
|
||||||
if (!Main.startModal())
|
if (!Main.beginModal())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
|
@ -137,10 +137,11 @@ function _removeUnusedWorkspaces() {
|
|||||||
// Used to go into a mode where all keyboard and mouse input goes to
|
// Used to go into a mode where all keyboard and mouse input goes to
|
||||||
// the stage. Returns true if we successfully grabbed the keyboard and
|
// the stage. Returns true if we successfully grabbed the keyboard and
|
||||||
// went modal, false otherwise
|
// went modal, false otherwise
|
||||||
function startModal() {
|
function beginModal() {
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
|
let timestamp = global.screen.get_display().get_current_time();
|
||||||
|
|
||||||
if (!global.grab_keyboard())
|
if (!global.begin_modal(timestamp))
|
||||||
return false;
|
return false;
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||||
|
|
||||||
@ -151,8 +152,9 @@ function startModal() {
|
|||||||
|
|
||||||
function endModal() {
|
function endModal() {
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
|
let timestamp = global.screen.get_display().get_current_time();
|
||||||
|
|
||||||
global.ungrab_keyboard();
|
global.end_modal(timestamp);
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
||||||
inModal = false;
|
inModal = false;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ Overview.prototype = {
|
|||||||
show : function() {
|
show : function() {
|
||||||
if (this.visible)
|
if (this.visible)
|
||||||
return;
|
return;
|
||||||
if (!Main.startModal())
|
if (!Main.beginModal())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
|
@ -124,7 +124,7 @@ RunDialog.prototype = {
|
|||||||
if (this._isOpen) // Already shown
|
if (this._isOpen) // Already shown
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Main.startModal())
|
if (!Main.beginModal())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._isOpen = true;
|
this._isOpen = true;
|
||||||
|
@ -40,7 +40,6 @@ struct _ShellGlobal {
|
|||||||
|
|
||||||
MutterPlugin *plugin;
|
MutterPlugin *plugin;
|
||||||
ShellWM *wm;
|
ShellWM *wm;
|
||||||
gboolean keyboard_grabbed;
|
|
||||||
const char *imagedir;
|
const char *imagedir;
|
||||||
const char *configdir;
|
const char *configdir;
|
||||||
|
|
||||||
@ -475,66 +474,42 @@ _shell_global_set_plugin (ShellGlobal *global,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_global_grab_keyboard:
|
* shell_global_begin_modal:
|
||||||
* @global: a #ShellGlobal
|
* @global: a #ShellGlobal
|
||||||
*
|
*
|
||||||
* Grab the keyboard to the stage window. The stage will receive
|
* Grabs the keyboard and mouse to the stage window. The stage will
|
||||||
* all keyboard events until shell_global_ungrab_keyboard() is called.
|
* receive all keyboard and mouse events until shell_global_end_modal()
|
||||||
* This is appropriate to do when the desktop goes into a special
|
* is called. This is used to implement "modes" for the shell, such as the
|
||||||
* mode where no normal global key shortcuts or application keyboard
|
* overview mode or the "looking glass" debug overlay, that block
|
||||||
* processing should happen.
|
* application and normal key shortcuts.
|
||||||
|
*
|
||||||
|
* Returns value: %TRUE if we succesfully entered the mode. %FALSE if we couldn't
|
||||||
|
* enter the mode. Failure may occur because an application has the pointer
|
||||||
|
* or keyboard grabbed, because Mutter is in a mode itself like moving a
|
||||||
|
* window or alt-Tab window selection, or because shell_global_begin_modal()
|
||||||
|
* was previouly called.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
shell_global_grab_keyboard (ShellGlobal *global)
|
shell_global_begin_modal (ShellGlobal *global,
|
||||||
|
guint32 timestamp)
|
||||||
{
|
{
|
||||||
MetaScreen *screen = mutter_plugin_get_screen (global->plugin);
|
|
||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
|
||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
|
||||||
ClutterStage *stage = CLUTTER_STAGE (mutter_plugin_get_stage (global->plugin));
|
ClutterStage *stage = CLUTTER_STAGE (mutter_plugin_get_stage (global->plugin));
|
||||||
Window stagewin = clutter_x11_get_stage_window (stage);
|
Window stagewin = clutter_x11_get_stage_window (stage);
|
||||||
|
|
||||||
/* FIXME: we need to coordinate with the rest of Metacity or we
|
return mutter_plugin_begin_modal (global->plugin, stagewin, None, 0, timestamp);
|
||||||
* may grab the keyboard away from other portions of Metacity
|
|
||||||
* and leave Metacity in a confused state. An X client is allowed
|
|
||||||
* to overgrab itself, though not allowed to grab they keyboard
|
|
||||||
* away from another applications.
|
|
||||||
*/
|
|
||||||
if (global->keyboard_grabbed)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (XGrabKeyboard (xdisplay, stagewin,
|
|
||||||
False, /* owner_events - steal events from the rest of metacity */
|
|
||||||
GrabModeAsync, GrabModeAsync,
|
|
||||||
CurrentTime) != Success)
|
|
||||||
return FALSE; /* probably AlreadyGrabbed, some other app has a keyboard grab */
|
|
||||||
|
|
||||||
global->keyboard_grabbed = TRUE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_global_ungrab_keyboard:
|
* shell_global_end_modal:
|
||||||
* @global: a #ShellGlobal
|
* @global: a #ShellGlobal
|
||||||
*
|
*
|
||||||
* Undoes the effect of shell_global_grab_keyboard
|
* Undoes the effect of shell_global_begin_modal().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
shell_global_ungrab_keyboard (ShellGlobal *global)
|
shell_global_end_modal (ShellGlobal *global,
|
||||||
|
guint32 timestamp)
|
||||||
{
|
{
|
||||||
MetaScreen *screen;
|
mutter_plugin_end_modal (global->plugin, timestamp);
|
||||||
MetaDisplay *display;
|
|
||||||
Display *xdisplay;
|
|
||||||
|
|
||||||
g_return_if_fail (global->keyboard_grabbed);
|
|
||||||
|
|
||||||
screen = mutter_plugin_get_screen (global->plugin);
|
|
||||||
display = meta_screen_get_display (screen);
|
|
||||||
xdisplay = meta_display_get_xdisplay (display);
|
|
||||||
|
|
||||||
XUngrabKeyboard (xdisplay, CurrentTime);
|
|
||||||
|
|
||||||
global->keyboard_grabbed = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
|
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
|
||||||
|
@ -64,8 +64,10 @@ GList *shell_global_get_windows (ShellGlobal *global);
|
|||||||
void _shell_global_set_plugin (ShellGlobal *global,
|
void _shell_global_set_plugin (ShellGlobal *global,
|
||||||
MutterPlugin *plugin);
|
MutterPlugin *plugin);
|
||||||
|
|
||||||
gboolean shell_global_grab_keyboard (ShellGlobal *global);
|
gboolean shell_global_begin_modal (ShellGlobal *global,
|
||||||
void shell_global_ungrab_keyboard (ShellGlobal *global);
|
guint32 timestamp);
|
||||||
|
void shell_global_end_modal (ShellGlobal *global,
|
||||||
|
guint32 timestamp);
|
||||||
|
|
||||||
void shell_global_reexec_self (ShellGlobal *global);
|
void shell_global_reexec_self (ShellGlobal *global);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user