workspace: Implement key navigation on the workspaces page
Simply use St's existing key navigation system by making all the window clones StWidgets, and making the WorkspacesView a focus group. Since the workspace view is effectively "fake", we need to add a focus delegator so that when key focus is assigned to the fake workspaces page, we can keynav inside it properly. https://bugzilla.gnome.org/show_bug.cgi?id=644306
This commit is contained in:
parent
a7aba1d585
commit
47a20756b9
@ -63,7 +63,8 @@ const WindowClone = new Lang.Class({
|
|||||||
// the invisible border; this is inconvenient; rather than trying
|
// the invisible border; this is inconvenient; rather than trying
|
||||||
// to compensate all over the place we insert a ClutterActor into
|
// to compensate all over the place we insert a ClutterActor into
|
||||||
// the hierarchy that is sized to only the visible portion.
|
// the hierarchy that is sized to only the visible portion.
|
||||||
this.actor = new Clutter.Actor({ reactive: true,
|
this.actor = new St.Widget({ reactive: true,
|
||||||
|
can_focus: true,
|
||||||
x: this.origX,
|
x: this.origX,
|
||||||
y: this.origY,
|
y: this.origY,
|
||||||
width: outerRect.width,
|
width: outerRect.width,
|
||||||
@ -85,10 +86,9 @@ const WindowClone = new Lang.Class({
|
|||||||
let clickAction = new Clutter.ClickAction();
|
let clickAction = new Clutter.ClickAction();
|
||||||
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
|
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
|
clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
|
||||||
|
|
||||||
this.actor.add_action(clickAction);
|
this.actor.add_action(clickAction);
|
||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
|
||||||
|
|
||||||
this._draggable = DND.makeDraggable(this.actor,
|
this._draggable = DND.makeDraggable(this.actor,
|
||||||
{ restoreOnSuccess: true,
|
{ restoreOnSuccess: true,
|
||||||
@ -197,11 +197,26 @@ const WindowClone = new Lang.Class({
|
|||||||
this.disconnectAll();
|
this.disconnectAll();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function(action, actor) {
|
_activate: function() {
|
||||||
this._selected = true;
|
this._selected = true;
|
||||||
this.emit('selected', global.get_current_time());
|
this.emit('selected', global.get_current_time());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onKeyPress: function(actor, event) {
|
||||||
|
let symbol = event.get_key_symbol();
|
||||||
|
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
|
||||||
|
if (isEnter) {
|
||||||
|
this._activate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClicked: function(action, actor) {
|
||||||
|
this._activate();
|
||||||
|
},
|
||||||
|
|
||||||
_onLongPress: function(action, actor, state) {
|
_onLongPress: function(action, actor, state) {
|
||||||
// Take advantage of the Clutter policy to consider
|
// Take advantage of the Clutter policy to consider
|
||||||
// a long-press canceled when the pointer movement
|
// a long-press canceled when the pointer movement
|
||||||
@ -301,6 +316,10 @@ const WindowOverlay = new Lang.Class({
|
|||||||
Lang.bind(this, this._onEnter));
|
Lang.bind(this, this._onEnter));
|
||||||
windowClone.actor.connect('leave-event',
|
windowClone.actor.connect('leave-event',
|
||||||
Lang.bind(this, this._onLeave));
|
Lang.bind(this, this._onLeave));
|
||||||
|
windowClone.actor.connect('key-focus-in',
|
||||||
|
Lang.bind(this, this._onEnter));
|
||||||
|
windowClone.actor.connect('key-focus-out',
|
||||||
|
Lang.bind(this, this._onLeave));
|
||||||
|
|
||||||
this._windowAddedId = 0;
|
this._windowAddedId = 0;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ const WorkspacesViewBase = new Lang.Class({
|
|||||||
this.actor = new St.Widget({ style_class: 'workspaces-view',
|
this.actor = new St.Widget({ style_class: 'workspaces-view',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
global.focus_manager.add_group(this.actor);
|
||||||
|
|
||||||
// The actor itself isn't a drop target, so we don't want to pick on its area
|
// The actor itself isn't a drop target, so we don't want to pick on its area
|
||||||
this.actor.set_size(0, 0);
|
this.actor.set_size(0, 0);
|
||||||
@ -371,11 +372,21 @@ const ExtraWorkspaceView = new Lang.Class({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DelegateFocusNavigator = new Lang.Class({
|
||||||
|
Name: 'DelegateFocusNavigator',
|
||||||
|
Extends: St.Widget,
|
||||||
|
|
||||||
|
vfunc_navigate_focus: function(from, direction) {
|
||||||
|
return this._delegate.navigateFocus(from, direction);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const WorkspacesDisplay = new Lang.Class({
|
const WorkspacesDisplay = new Lang.Class({
|
||||||
Name: 'WorkspacesDisplay',
|
Name: 'WorkspacesDisplay',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new St.Widget({ clip_to_allocation: true });
|
this.actor = new DelegateFocusNavigator({ clip_to_allocation: true });
|
||||||
|
this.actor._delegate = this;
|
||||||
this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesActualGeometry));
|
this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesActualGeometry));
|
||||||
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
||||||
|
|
||||||
@ -437,6 +448,10 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
navigateFocus: function(from, direction) {
|
||||||
|
return this._getPrimaryView().actor.navigate_focus(from, direction, false);
|
||||||
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
this._updateWorkspacesViews();
|
this._updateWorkspacesViews();
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
|
Loading…
Reference in New Issue
Block a user