[gnome-shell] viewSelector: don't process key presses from capture-event
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] viewSelector: don't process key presses from capture-event
- Date: Thu, 24 Feb 2011 14:38:02 +0000 (UTC)
commit d5735496afad0f81e8124387fa0ea99fb6586732
Author: Dan Winship <danw gnome org>
Date: Wed Feb 16 13:27:05 2011 -0500
viewSelector: don't process key presses from capture-event
Rather than connecting to stage::capture-event and then trying to
guess whether or not a given key-press should be handled by us or not,
handle the end-search-on-Escape case from entry::key-press-event
(since it only makes sense when the entry is focused anyway) and the
start-search-on-printable-key case from stage::key-press-event (which
will only get the events that no other actor wanted for itself).
Similarly, do exit-overview-on-Escape and switch-panes cases from
stage::key-press-event, rather than
viewSelector.actor::key-press-event, so that they will work correctly
even if the keyboard focus is somewhere else. (Also fix a longstanding
bug in the pane-switching code, which was supposed to be disabled when
a search was active, but was checking a non-existent variable.)
https://bugzilla.gnome.org/show_bug.cgi?id=642502
js/ui/overview.js | 2 +-
js/ui/viewSelector.js | 133 +++++++++++++++++++-----------------------------
2 files changed, 54 insertions(+), 81 deletions(-)
---
diff --git a/js/ui/overview.js b/js/ui/overview.js
index d0b3aff..a862c2b 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -513,7 +513,7 @@ Overview.prototype = {
if (this._shown)
return;
// Do this manually instead of using _syncInputMode, to handle failure
- if (!Main.pushModal(this.viewSelector.actor))
+ if (!Main.pushModal(this._group))
return;
this._modal = true;
this._animateVisible();
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index 13f6847..7e5fa27 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -80,19 +80,17 @@ ViewTab.prototype = {
};
-function SearchTab(focusBase) {
- this._init(focusBase);
+function SearchTab() {
+ this._init();
}
SearchTab.prototype = {
__proto__: BaseTab.prototype,
- _init: function(focusBase) {
- this._searchActive = false;
+ _init: function() {
+ this.active = false;
this._searchPending = false;
- this._keyPressId = 0;
this._searchTimeoutId = 0;
- this._focusBase = focusBase;
this._searchSystem = new Search.SearchSystem();
this._openSearchSystem = new Search.OpenSearchSystem();
@@ -105,6 +103,7 @@ SearchTab.prototype = {
hint_text: _("Type to search..."),
track_hover: true });
this._text = this._entry.clutter_text;
+ this._text.connect('key-press-event', Lang.bind(this, this._onKeyPress));
this._inactiveIcon = new St.Icon({ style_class: 'search-entry-icon',
icon_name: 'edit-find',
@@ -142,29 +141,16 @@ SearchTab.prototype = {
this._capturedEventId = 0;
},
- show: function() {
- BaseTab.prototype.show.call(this);
-
- if (this._keyPressId == 0)
- this._keyPressId = this._text.connect('key-press-event',
- Lang.bind(this, this._onKeyPress));
- },
-
hide: function() {
BaseTab.prototype.hide.call(this);
- if (this._keyPressId > 0) {
- this._text.disconnect(this._keyPressId);
- this._keyPressId = 0;
- }
this._reset();
},
_reset: function () {
this._text.text = '';
- // Return focus to the viewSelector
- global.stage.set_key_focus(this._focusBase);
+ global.stage.set_key_focus(null);
this._text.set_cursor_visible(true);
this._text.set_selection(0, 0);
@@ -172,10 +158,7 @@ SearchTab.prototype = {
_updateCursorVisibility: function() {
let focus = global.stage.get_key_focus();
- if (focus == this._focusBase || focus == this._text)
- this._text.set_cursor_visible(true);
- else
- this._text.set_cursor_visible(false);
+ this._text.set_cursor_visible(focus == this._text);
},
_onMapped: function() {
@@ -198,19 +181,24 @@ SearchTab.prototype = {
this._searchResults.createProviderMeta(provider);
},
+ startSearch: function(event) {
+ global.stage.set_key_focus(this._text);
+ this._text.event(event, false);
+ },
+
// the entry does not show the hint
_isActivated: function() {
return this._text.text == this._entry.get_text();
},
_onTextChanged: function (se, prop) {
- let searchPreviouslyActive = this._searchActive;
- this._searchActive = this._entry.get_text() != '';
- this._searchPending = this._searchActive && !searchPreviouslyActive;
+ let searchPreviouslyActive = this.active;
+ this.active = this._entry.get_text() != '';
+ this._searchPending = this.active && !searchPreviouslyActive;
if (this._searchPending) {
this._searchResults.startingSearch();
}
- if (this._searchActive) {
+ if (this.active) {
this._entry.set_secondary_icon(this._activeIcon);
if (this._iconClickedId == 0) {
@@ -228,7 +216,7 @@ SearchTab.prototype = {
this._entry.set_secondary_icon(this._inactiveIcon);
this.emit('search-cancelled');
}
- if (!this._searchActive) {
+ if (!this.active) {
if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId);
this._searchTimeoutId = 0;
@@ -243,63 +231,35 @@ SearchTab.prototype = {
_onKeyPress: function(entry, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.Up) {
- if (!this._searchActive)
+ if (!this.active)
return true;
this._searchResults.selectUp(false);
return true;
} else if (symbol == Clutter.Down) {
- if (!this._searchActive)
+ if (!this.active)
return true;
this._searchResults.selectDown(false);
return true;
+ } else if (symbol == Clutter.Escape) {
+ if (this._isActivated()) {
+ this._reset();
+ return true;
+ }
}
+
return false;
},
_onCapturedEvent: function(actor, event) {
- let source = event.get_source();
-
- switch (event.type()) {
- case Clutter.EventType.BUTTON_PRESS:
+ if (event.type() == Clutter.EventType.BUTTON_PRESS) {
+ let source = event.get_source();
+ if (source != this._text && this._text.text == '') {
// the user clicked outside after activating the entry, but
// with no search term entered - cancel the search
- if (source != this._text && this._text.text == '')
- this._reset();
- break;
- case Clutter.EventType.KEY_PRESS:
- // If some "special" actor grabbed the focus (run
- // dialog, looking glass); we don't want to interfere
- // with that
- let focus = global.stage.get_key_focus();
- if (focus != this._focusBase && focus != this._text)
- return false;
-
- let sym = event.get_key_symbol();
-
- // If we have an active search, Escape cancels it - if we
- // haven't, the key is ignored
- if (sym == Clutter.Escape)
- if (this._isActivated()) {
- this._reset();
- return true;
- } else {
- return false;
- }
-
- // Ignore non-printable keys
- if (!Clutter.keysym_to_unicode(sym))
- return false;
-
- // Search started - move the key focus to the entry and
- // "repeat" the event
- if (!this._isActivated()) {
- global.stage.set_key_focus(this._text);
- this._text.event(event, false);
- }
-
- break;
+ this._reset();
+ }
}
return false;
@@ -323,8 +283,6 @@ ViewSelector.prototype = {
_init : function() {
this.actor = new St.BoxLayout({ name: 'viewSelector',
vertical: true });
- this.actor.connect('key-press-event',
- Lang.bind(this, this._onKeyPress));
// The tab bar is located at the top of the view selector and
// holds both "normal" tab labels and the search entry. The former
@@ -358,7 +316,7 @@ ViewSelector.prototype = {
this._tabs = [];
this._activeTab = null;
- this._searchTab = new SearchTab(this.actor);
+ this._searchTab = new SearchTab();
this._searchArea.set_child(this._searchTab.title);
this._addTab(this._searchTab);
@@ -369,10 +327,22 @@ ViewSelector.prototype = {
Main.overview.connect('item-drag-begin',
Lang.bind(this, this._switchDefaultTab));
- Main.overview.connect('showing',
- Lang.bind(this, this._switchDefaultTab));
- Main.overview.connect('hiding',
- Lang.bind(this, this._switchDefaultTab));
+
+ this._stageKeyPressId = 0;
+ Main.overview.connect('showing', Lang.bind(this,
+ function () {
+ this._switchDefaultTab();
+ this._stageKeyPressId = global.stage.connect('key-press-event',
+ Lang.bind(this, this._onStageKeyPress));
+ }));
+ Main.overview.connect('hiding', Lang.bind(this,
+ function () {
+ this._switchDefaultTab();
+ if (this._stageKeyPressId != 0) {
+ global.stage.disconnect(this._stageKeyPressId);
+ this._stageKeyPressId = 0;
+ }
+ }));
// Public constraints which may be used to tie actors' height or
// vertical position to the current tab's content; as the content's
@@ -527,22 +497,25 @@ ViewSelector.prototype = {
}));
},
- _onKeyPress: function(actor, event) {
+ _onStageKeyPress: function(actor, event) {
let modifiers = Shell.get_event_state(event);
let symbol = event.get_key_symbol();
+
if (symbol == Clutter.Escape) {
Main.overview.hide();
return true;
} else if (modifiers & Clutter.ModifierType.CONTROL_MASK) {
if (symbol == Clutter.Page_Up) {
- if (!this._searchActive)
+ if (!this._searchTab.active)
this._prevTab();
return true;
} else if (symbol == Clutter.Page_Down) {
- if (!this._searchActive)
+ if (!this._searchTab.active)
this._nextTab();
return true;
}
+ } else if (Clutter.keysym_to_unicode(symbol)) {
+ this._searchTab.startSearch(event);
}
return false;
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]