Layout: show the OSK on the monitor where the focused window lives
In multimonitor scenarios, it makes sense to show the OSK close to the window that will actually receive keystrokes. https://bugzilla.gnome.org/show_bug.cgi?id=685856
This commit is contained in:
parent
00201f7e6c
commit
8a7c0313f6
@ -251,7 +251,7 @@ const Keyboard = new Lang.Class({
|
|||||||
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
|
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
|
||||||
|
|
||||||
if (show)
|
if (show)
|
||||||
this.show();
|
this.show(Main.layoutManager.focusIndex);
|
||||||
else
|
else
|
||||||
this._createSource();
|
this._createSource();
|
||||||
},
|
},
|
||||||
@ -375,7 +375,7 @@ const Keyboard = new Lang.Class({
|
|||||||
if (!this._enableKeyboard)
|
if (!this._enableKeyboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let monitor = Main.layoutManager.bottomMonitor;
|
let monitor = Main.layoutManager.keyboardMonitor;
|
||||||
let maxHeight = monitor.height / 3;
|
let maxHeight = monitor.height / 3;
|
||||||
this.actor.width = monitor.width;
|
this.actor.width = monitor.width;
|
||||||
|
|
||||||
@ -462,9 +462,9 @@ const Keyboard = new Lang.Class({
|
|||||||
actor._extended_keys || actor.extended_key;
|
actor._extended_keys || actor.extended_key;
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function () {
|
show: function (monitor) {
|
||||||
|
Main.layoutManager.keyboardIndex = monitor;
|
||||||
this._redraw();
|
this._redraw();
|
||||||
|
|
||||||
Main.layoutManager.showKeyboard();
|
Main.layoutManager.showKeyboard();
|
||||||
this._destroySource();
|
this._destroySource();
|
||||||
},
|
},
|
||||||
@ -512,7 +512,7 @@ const Keyboard = new Lang.Class({
|
|||||||
|
|
||||||
if (timestamp != Clutter.CURRENT_TIME)
|
if (timestamp != Clutter.CURRENT_TIME)
|
||||||
this._timestamp = timestamp;
|
this._timestamp = timestamp;
|
||||||
this.show();
|
this.show(Main.layoutManager.focusIndex);
|
||||||
},
|
},
|
||||||
|
|
||||||
Hide: function(timestamp) {
|
Hide: function(timestamp) {
|
||||||
@ -566,6 +566,7 @@ const KeyboardSource = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
this._keyboard.show();
|
// Show the OSK below the message tray
|
||||||
|
this._keyboard.show(Main.layoutManager.bottomIndex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
113
js/ui/layout.js
113
js/ui/layout.js
@ -103,6 +103,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
this.monitors = [];
|
this.monitors = [];
|
||||||
this.primaryMonitor = null;
|
this.primaryMonitor = null;
|
||||||
this.primaryIndex = -1;
|
this.primaryIndex = -1;
|
||||||
|
this._keyboardIndex = -1;
|
||||||
this._hotCorners = [];
|
this._hotCorners = [];
|
||||||
this._background = null;
|
this._background = null;
|
||||||
this._leftPanelBarrier = 0;
|
this._leftPanelBarrier = 0;
|
||||||
@ -240,9 +241,8 @@ const LayoutManager = new Lang.Class({
|
|||||||
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
|
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
|
||||||
this.panelBox.set_size(this.primaryMonitor.width, -1);
|
this.panelBox.set_size(this.primaryMonitor.width, -1);
|
||||||
|
|
||||||
this.keyboardBox.set_position(this.bottomMonitor.x,
|
if (this.keyboardIndex < 0)
|
||||||
this.bottomMonitor.y + this.bottomMonitor.height);
|
this.keyboardIndex = this.primaryIndex;
|
||||||
this.keyboardBox.set_size(this.bottomMonitor.width, -1);
|
|
||||||
|
|
||||||
this.trayBox.set_position(this.bottomMonitor.x,
|
this.trayBox.set_position(this.bottomMonitor.x,
|
||||||
this.bottomMonitor.y + this.bottomMonitor.height);
|
this.bottomMonitor.y + this.bottomMonitor.height);
|
||||||
@ -305,6 +305,42 @@ const LayoutManager = new Lang.Class({
|
|||||||
return this.monitors[index];
|
return this.monitors[index];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get keyboardMonitor() {
|
||||||
|
return this.monitors[this.keyboardIndex];
|
||||||
|
},
|
||||||
|
|
||||||
|
get focusIndex() {
|
||||||
|
let i = Main.layoutManager.primaryIndex;
|
||||||
|
|
||||||
|
if (global.stage_input_mode == Shell.StageInputMode.FOCUSED ||
|
||||||
|
global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) {
|
||||||
|
let focusActor = global.stage.key_focus;
|
||||||
|
if (focusActor)
|
||||||
|
i = this._chrome.findIndexForActor(focusActor);
|
||||||
|
} else {
|
||||||
|
let focusWindow = global.display.focus_window;
|
||||||
|
if (focusWindow)
|
||||||
|
i = this._chrome.findIndexForWindow(focusWindow.get_compositor_private());
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
},
|
||||||
|
|
||||||
|
get focusMonitor() {
|
||||||
|
return this.monitors[this.focusIndex];
|
||||||
|
},
|
||||||
|
|
||||||
|
set keyboardIndex(v) {
|
||||||
|
this._keyboardIndex = v;
|
||||||
|
this.keyboardBox.set_position(this.keyboardMonitor.x,
|
||||||
|
this.keyboardMonitor.y + this.keyboardMonitor.height);
|
||||||
|
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
|
||||||
|
},
|
||||||
|
|
||||||
|
get keyboardIndex() {
|
||||||
|
return this._keyboardIndex;
|
||||||
|
},
|
||||||
|
|
||||||
_startupAnimation: function() {
|
_startupAnimation: function() {
|
||||||
this.panelBox.anchor_y = this.panelBox.height;
|
this.panelBox.anchor_y = this.panelBox.height;
|
||||||
|
|
||||||
@ -363,11 +399,14 @@ const LayoutManager = new Lang.Class({
|
|||||||
onComplete: this._showKeyboardComplete,
|
onComplete: this._showKeyboardComplete,
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
Tweener.addTween(this.trayBox,
|
|
||||||
{ anchor_y: this.keyboardBox.height,
|
if (this.keyboardIndex == this.bottomIndex) {
|
||||||
time: KEYBOARD_ANIMATION_TIME,
|
Tweener.addTween(this.trayBox,
|
||||||
transition: 'easeOutQuad'
|
{ anchor_y: this.keyboardBox.height,
|
||||||
});
|
time: KEYBOARD_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.emit('keyboard-visible-changed', true);
|
this.emit('keyboard-visible-changed', true);
|
||||||
},
|
},
|
||||||
@ -379,7 +418,8 @@ const LayoutManager = new Lang.Class({
|
|||||||
|
|
||||||
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
|
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
|
||||||
this.keyboardBox.anchor_y = this.keyboardBox.height;
|
this.keyboardBox.anchor_y = this.keyboardBox.height;
|
||||||
this.trayBox.anchor_y = this.keyboardBox.height;
|
if (this.keyboardIndex == this.bottomIndex)
|
||||||
|
this.trayBox.anchor_y = this.keyboardBox.height;
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -395,11 +435,14 @@ const LayoutManager = new Lang.Class({
|
|||||||
onComplete: this._hideKeyboardComplete,
|
onComplete: this._hideKeyboardComplete,
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
Tweener.addTween(this.trayBox,
|
|
||||||
{ anchor_y: 0,
|
if (this.keyboardIndex == this.bottomIndex) {
|
||||||
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
Tweener.addTween(this.trayBox,
|
||||||
transition: 'easeOutQuad'
|
{ anchor_y: 0,
|
||||||
});
|
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.emit('keyboard-visible-changed', false);
|
this.emit('keyboard-visible-changed', false);
|
||||||
},
|
},
|
||||||
@ -463,7 +506,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
findMonitorForActor: function(actor) {
|
findMonitorForActor: function(actor) {
|
||||||
return this._chrome.findMonitorForActor(actor);
|
return this.monitors[this._chrome.findIndexForActor(actor)];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(LayoutManager.prototype);
|
Signals.addSignalMethods(LayoutManager.prototype);
|
||||||
@ -812,6 +855,7 @@ const Chrome = new Lang.Class({
|
|||||||
|
|
||||||
_relayout: function() {
|
_relayout: function() {
|
||||||
this._monitors = this._layoutManager.monitors;
|
this._monitors = this._layoutManager.monitors;
|
||||||
|
this._primaryIndex = this._layoutManager.primaryIndex;
|
||||||
this._primaryMonitor = this._layoutManager.primaryMonitor;
|
this._primaryMonitor = this._layoutManager.primaryMonitor;
|
||||||
|
|
||||||
this._updateFullscreen();
|
this._updateFullscreen();
|
||||||
@ -827,32 +871,47 @@ const Chrome = new Lang.Class({
|
|||||||
let monitor = this._monitors[i];
|
let monitor = this._monitors[i];
|
||||||
if (cx >= monitor.x && cx < monitor.x + monitor.width &&
|
if (cx >= monitor.x && cx < monitor.x + monitor.width &&
|
||||||
cy >= monitor.y && cy < monitor.y + monitor.height)
|
cy >= monitor.y && cy < monitor.y + monitor.height)
|
||||||
return monitor;
|
return i;
|
||||||
}
|
}
|
||||||
// If the center is not on a monitor, return the first overlapping monitor
|
// If the center is not on a monitor, return the first overlapping monitor
|
||||||
for (let i = 0; i < this._monitors.length; i++) {
|
for (let i = 0; i < this._monitors.length; i++) {
|
||||||
let monitor = this._monitors[i];
|
let monitor = this._monitors[i];
|
||||||
if (x + w > monitor.x && x < monitor.x + monitor.width &&
|
if (x + w > monitor.x && x < monitor.x + monitor.width &&
|
||||||
y + h > monitor.y && y < monitor.y + monitor.height)
|
y + h > monitor.y && y < monitor.y + monitor.height)
|
||||||
return monitor;
|
return i;
|
||||||
}
|
}
|
||||||
// otherwise on no monitor
|
// otherwise on no monitor
|
||||||
return null;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_findMonitorForWindow: function(window) {
|
findIndexForWindow: function(window) {
|
||||||
return this._findMonitorForRect(window.x, window.y, window.width, window.height);
|
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
|
||||||
|
if (i >= 0)
|
||||||
|
return i;
|
||||||
|
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
||||||
},
|
},
|
||||||
|
|
||||||
// This call guarantees that we return some monitor to simplify usage of it
|
// This call guarantees that we return some monitor to simplify usage of it
|
||||||
// In practice all tracked actors should be visible on some monitor anyway
|
// In practice all tracked actors should be visible on some monitor anyway
|
||||||
findMonitorForActor: function(actor) {
|
findIndexForActor: function(actor) {
|
||||||
let [x, y] = actor.get_transformed_position();
|
let [x, y] = actor.get_transformed_position();
|
||||||
let [w, h] = actor.get_transformed_size();
|
let [w, h] = actor.get_transformed_size();
|
||||||
let monitor = this._findMonitorForRect(x, y, w, h);
|
let i = this._findMonitorForRect(x, y, w, h);
|
||||||
if (monitor)
|
if (i >= 0)
|
||||||
return monitor;
|
return i;
|
||||||
return this._primaryMonitor; // Not on any monitor, pretend its on the primary
|
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
||||||
|
},
|
||||||
|
|
||||||
|
findMonitorForWindow: function(window) {
|
||||||
|
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
|
||||||
|
if (i >= 0)
|
||||||
|
return this._monitors[i];
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
findMonitorForActor: function(actor) {
|
||||||
|
return this._monitors[this.findIndexForActor(actor)];
|
||||||
},
|
},
|
||||||
|
|
||||||
_queueUpdateRegions: function() {
|
_queueUpdateRegions: function() {
|
||||||
@ -900,7 +959,7 @@ const Chrome = new Lang.Class({
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (layer == Meta.StackLayer.FULLSCREEN) {
|
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||||
let monitor = this._findMonitorForWindow(window);
|
let monitor = this.findMonitorForWindow(window);
|
||||||
if (monitor)
|
if (monitor)
|
||||||
monitor.inFullscreen = true;
|
monitor.inFullscreen = true;
|
||||||
}
|
}
|
||||||
@ -917,7 +976,7 @@ const Chrome = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Or whether it is monitor sized
|
// Or whether it is monitor sized
|
||||||
let monitor = this._findMonitorForWindow(window);
|
let monitor = this.findMonitorForWindow(window);
|
||||||
if (monitor &&
|
if (monitor &&
|
||||||
window.x <= monitor.x &&
|
window.x <= monitor.x &&
|
||||||
window.x + window.width >= monitor.x + monitor.width &&
|
window.x + window.width >= monitor.x + monitor.width &&
|
||||||
|
@ -1471,6 +1471,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
this._pointerInKeyboard = false;
|
this._pointerInKeyboard = false;
|
||||||
this._keyboardVisible = false;
|
this._keyboardVisible = false;
|
||||||
|
this._keyboardUnderMessageTray = false;
|
||||||
this._summaryState = State.HIDDEN;
|
this._summaryState = State.HIDDEN;
|
||||||
this._pointerInSummary = false;
|
this._pointerInSummary = false;
|
||||||
this._notificationClosed = false;
|
this._notificationClosed = false;
|
||||||
@ -1924,12 +1925,15 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onKeyboardVisibleChanged: function(layoutManager, keyboardVisible) {
|
_onKeyboardVisibleChanged: function(layoutManager, keyboardVisible) {
|
||||||
if (this._keyboardVisible == keyboardVisible)
|
let keyboardUnderMessageTray = layoutManager.keyboardIndex == layoutManager.bottomIndex;
|
||||||
|
if (this._keyboardVisible == keyboardVisible &&
|
||||||
|
this._keyboardUnderMesssageTray == keyboardUnderMessageTray)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._keyboardVisible = keyboardVisible;
|
this._keyboardVisible = keyboardVisible;
|
||||||
|
this._keyboardUnderMessageTray = keyboardUnderMessageTray;
|
||||||
|
|
||||||
if (keyboardVisible)
|
if (keyboardVisible && keyboardUnderMessageTray)
|
||||||
this.actor.add_style_pseudo_class('keyboard');
|
this.actor.add_style_pseudo_class('keyboard');
|
||||||
else
|
else
|
||||||
this.actor.remove_style_pseudo_class('keyboard');
|
this.actor.remove_style_pseudo_class('keyboard');
|
||||||
@ -2086,12 +2090,12 @@ const MessageTray = new Lang.Class({
|
|||||||
this._desktopCloneState == State.SHOWN);
|
this._desktopCloneState == State.SHOWN);
|
||||||
let desktopCloneShouldBeVisible = (trayShouldBeVisible &&
|
let desktopCloneShouldBeVisible = (trayShouldBeVisible &&
|
||||||
!this._overviewVisible &&
|
!this._overviewVisible &&
|
||||||
!this._keyboardVisible);
|
(!this._keyboardVisible || !this._keyboardUnderMessageTray));
|
||||||
|
|
||||||
if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) {
|
if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) {
|
||||||
this._showDesktopClone();
|
this._showDesktopClone();
|
||||||
} else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) {
|
} else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) {
|
||||||
this._hideDesktopClone (this._keyboardVisible);
|
this._hideDesktopClone (this._keyboardVisible && this._keyboardUnderMessageTray);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user