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) {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
Main.startModal();
|
||||
|
||||
global.window_group.add_actor(this._overlay);
|
||||
this._overlay.raise_top();
|
||||
this._overlay.show();
|
||||
@ -164,8 +162,6 @@ AltTabPopup.prototype = {
|
||||
destroy : function() {
|
||||
this.actor.destroy();
|
||||
this._overlay.destroy();
|
||||
|
||||
Main.endModal();
|
||||
},
|
||||
|
||||
select : function(n) {
|
||||
|
@ -555,7 +555,7 @@ LookingGlass.prototype = {
|
||||
|
||||
Tweener.removeTweens(this.actor);
|
||||
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
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
|
||||
// the stage. Returns true if we successfully grabbed the keyboard and
|
||||
// went modal, false otherwise
|
||||
function startModal() {
|
||||
function beginModal() {
|
||||
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;
|
||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||
|
||||
@ -151,8 +152,9 @@ function startModal() {
|
||||
|
||||
function endModal() {
|
||||
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);
|
||||
inModal = false;
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ Overview.prototype = {
|
||||
show : function() {
|
||||
if (this.visible)
|
||||
return;
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
this.visible = true;
|
||||
|
@ -124,7 +124,7 @@ RunDialog.prototype = {
|
||||
if (this._isOpen) // Already shown
|
||||
return;
|
||||
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
this._isOpen = true;
|
||||
|
@ -40,7 +40,6 @@ struct _ShellGlobal {
|
||||
|
||||
MutterPlugin *plugin;
|
||||
ShellWM *wm;
|
||||
gboolean keyboard_grabbed;
|
||||
const char *imagedir;
|
||||
const char *configdir;
|
||||
|
||||
@ -475,66 +474,42 @@ _shell_global_set_plugin (ShellGlobal *global,
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_grab_keyboard:
|
||||
* shell_global_begin_modal:
|
||||
* @global: a #ShellGlobal
|
||||
*
|
||||
* Grab the keyboard to the stage window. The stage will receive
|
||||
* all keyboard events until shell_global_ungrab_keyboard() is called.
|
||||
* This is appropriate to do when the desktop goes into a special
|
||||
* mode where no normal global key shortcuts or application keyboard
|
||||
* processing should happen.
|
||||
* Grabs the keyboard and mouse to the stage window. The stage will
|
||||
* receive all keyboard and mouse events until shell_global_end_modal()
|
||||
* is called. This is used to implement "modes" for the shell, such as the
|
||||
* overview mode or the "looking glass" debug overlay, that block
|
||||
* 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
|
||||
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));
|
||||
Window stagewin = clutter_x11_get_stage_window (stage);
|
||||
|
||||
/* FIXME: we need to coordinate with the rest of Metacity or we
|
||||
* 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;
|
||||
return mutter_plugin_begin_modal (global->plugin, stagewin, None, 0, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_ungrab_keyboard:
|
||||
* shell_global_end_modal:
|
||||
* @global: a #ShellGlobal
|
||||
*
|
||||
* Undoes the effect of shell_global_grab_keyboard
|
||||
* Undoes the effect of shell_global_begin_modal().
|
||||
*/
|
||||
void
|
||||
shell_global_ungrab_keyboard (ShellGlobal *global)
|
||||
shell_global_end_modal (ShellGlobal *global,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
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;
|
||||
mutter_plugin_end_modal (global->plugin, timestamp);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
MutterPlugin *plugin);
|
||||
|
||||
gboolean shell_global_grab_keyboard (ShellGlobal *global);
|
||||
void shell_global_ungrab_keyboard (ShellGlobal *global);
|
||||
gboolean shell_global_begin_modal (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
void shell_global_end_modal (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
|
||||
void shell_global_reexec_self (ShellGlobal *global);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user