gnome-shell r83 - in trunk: js/ui src
- From: otaylor svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-shell r83 - in trunk: js/ui src
- Date: Mon, 24 Nov 2008 19:07:18 +0000 (UTC)
Author: otaylor
Date: Mon Nov 24 19:07:18 2008
New Revision: 83
URL: http://svn.gnome.org/viewvc/gnome-shell?rev=83&view=rev
Log:
Add a concept of "going modal" by grabbing the keyboard
shell-global.[ch]: Replace shell_global_focus_stage()
with shell_global_grab_keyboard()/shell_global_ungrab_keyboard()
main.js: Add startModal()/endModal() functions to go modal and
undo that.
run_dialog.js overlay.js main.js: Use startModal() for the overlay
and for the run dialog.
http://bugzilla.gnome.org/show_bug.cgi?id=561880
Modified:
trunk/js/ui/main.js
trunk/js/ui/overlay.js
trunk/js/ui/run_dialog.js
trunk/src/shell-global.c
trunk/src/shell-global.h
Modified: trunk/js/ui/main.js
==============================================================================
--- trunk/js/ui/main.js (original)
+++ trunk/js/ui/main.js Mon Nov 24 19:07:18 2008
@@ -103,13 +103,14 @@
// Make sure not more than one run dialog is shown.
if (!run_dialog) {
run_dialog = new RunDialog.RunDialog();
- let handler = function() {
+ let end_handler = function() {
run_dialog.destroy();
run_dialog = null;
};
- run_dialog.connect('run', handler);
- run_dialog.connect('cancel', handler);
- run_dialog.show();
+ run_dialog.connect('run', end_handler);
+ run_dialog.connect('cancel', end_handler);
+ if (!run_dialog.show())
+ end_handler();
}
});
@@ -120,17 +121,33 @@
wm = new WindowManager.WindowManager();
}
-function show_overlay() {
+// 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() {
let global = Shell.global_get();
- overlay.show();
+ if (!global.grab_keyboard())
+ return false;
+
global.set_stage_input_area(0, 0, global.screen_width, global.screen_height);
+
+ return true;
}
-function hide_overlay() {
+function endModal() {
let global = Shell.global_get();
- overlay.hide();
- panel.overlayHidden();
+ global.ungrab_keyboard();
global.set_stage_input_area(0, 0, global.screen_width, Panel.PANEL_HEIGHT);
}
+
+function show_overlay() {
+ if (startModal())
+ overlay.show();
+}
+
+function hide_overlay() {
+ overlay.hide();
+ endModal();
+}
Modified: trunk/js/ui/overlay.js
==============================================================================
--- trunk/js/ui/overlay.js (original)
+++ trunk/js/ui/overlay.js Mon Nov 24 19:07:18 2008
@@ -178,8 +178,6 @@
let global = Shell.global_get();
- global.focus_stage();
-
let windows = global.get_windows();
let desktopWindow = null;
Modified: trunk/js/ui/run_dialog.js
==============================================================================
--- trunk/js/ui/run_dialog.js (original)
+++ trunk/js/ui/run_dialog.js Mon Nov 24 19:07:18 2008
@@ -26,8 +26,9 @@
_init : function() {
let global = Shell.global_get();
- // All actors are inside _group.
- this._group = new Clutter.Group();
+ // All actors are inside _group. We create it initially
+ // hidden then show it in show()
+ this._group = new Clutter.Group({ visible: false });
global.stage.add_actor(this._group);
this._overlay = new Clutter.Rectangle({ color: OVERLAY_COLOR,
@@ -74,19 +75,6 @@
return false;
});
- // TODO: Detect escape key and make it cancel the operation.
- // Use me.on_cancel() if it exists. Something like this:
- // this._entry.connect('key-press-event', function(o, e) {
- // if (the pressed key is the escape key) {
- // me.hide();
- // me.emit('cancel');
- // return false;
- // } else
- // return true;
- // });
-
- global.focus_stage();
- global.stage.set_key_focus(this._entry);
},
_run : function(command) {
@@ -104,14 +92,41 @@
},
show : function() {
+ if (this._group.visible) // Already shown
+ return false;
+
+ if (!Main.startModal())
+ return false;
+
this._group.show_all();
+
+ // TODO: Detect escape key and make it cancel the operation.
+ // Use me.on_cancel() if it exists. Something like this:
+ // this._entry.connect('key-press-event', function(o, e) {
+ // if (the pressed key is the escape key) {
+ // me.hide();
+ // me.emit('cancel');
+ // return false;
+ // } else
+ // return true;
+ // });
+
+ let global = Shell.global_get();
+ global.stage.set_key_focus(this._entry);
+
+ return true;
},
hide : function() {
- this._group.hide();
+ if (!this._group.visible)
+ return;
+
+ this._group.hide();
+ Main.endModal();
},
destroy : function(){
+ this.hide();
this._group.destroy();
}
};
Modified: trunk/src/shell-global.c
==============================================================================
--- trunk/src/shell-global.c (original)
+++ trunk/src/shell-global.c Mon Nov 24 19:07:18 2008
@@ -11,6 +11,7 @@
MutterPlugin *plugin;
ShellWM *wm;
+ gboolean keyboard_grabbed;
};
enum {
@@ -273,19 +274,64 @@
}
/**
- * shell_global_focus_stage:
+ * shell_global_grab_keyboard:
+ * @global: a #ShellGlobal
*
- * Set the keyboard focus to the Clutter stage window. This function
- * is best used in combination with some sort of visual notification
- * that the shell has taken over input.
+ * 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.
*/
-void
-shell_global_focus_stage (ShellGlobal *global)
+gboolean
+shell_global_grab_keyboard (ShellGlobal *global)
{
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);
- XSetInputFocus (xdisplay, stagewin, RevertToParent, CurrentTime);
+
+ /* 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;
+}
+
+/**
+ * shell_global_ungrab_keyboard:
+ * @global: a #ShellGlobal
+ *
+ * Undoes the effect of shell_global_grab_keyboard
+ */
+void
+shell_global_ungrab_keyboard (ShellGlobal *global)
+{
+ 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;
}
Modified: trunk/src/shell-global.h
==============================================================================
--- trunk/src/shell-global.h (original)
+++ trunk/src/shell-global.h Mon Nov 24 19:07:18 2008
@@ -49,7 +49,8 @@
MetaScreen * shell_global_get_screen (ShellGlobal *global);
-void shell_global_focus_stage (ShellGlobal *global);
+gboolean shell_global_grab_keyboard (ShellGlobal *global);
+void shell_global_ungrab_keyboard (ShellGlobal *global);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]