diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js index 482fb3068..67f00ba34 100644 --- a/js/ui/keyboard.js +++ b/js/ui/keyboard.js @@ -251,7 +251,7 @@ const Keyboard = new Lang.Class({ this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged)); if (show) - this.show(); + this.show(Main.layoutManager.focusIndex); else this._createSource(); }, @@ -375,7 +375,7 @@ const Keyboard = new Lang.Class({ if (!this._enableKeyboard) return; - let monitor = Main.layoutManager.bottomMonitor; + let monitor = Main.layoutManager.keyboardMonitor; let maxHeight = monitor.height / 3; this.actor.width = monitor.width; @@ -462,9 +462,9 @@ const Keyboard = new Lang.Class({ actor._extended_keys || actor.extended_key; }, - show: function () { + show: function (monitor) { + Main.layoutManager.keyboardIndex = monitor; this._redraw(); - Main.layoutManager.showKeyboard(); this._destroySource(); }, @@ -512,7 +512,7 @@ const Keyboard = new Lang.Class({ if (timestamp != Clutter.CURRENT_TIME) this._timestamp = timestamp; - this.show(); + this.show(Main.layoutManager.focusIndex); }, Hide: function(timestamp) { @@ -566,6 +566,7 @@ const KeyboardSource = new Lang.Class({ }, open: function() { - this._keyboard.show(); + // Show the OSK below the message tray + this._keyboard.show(Main.layoutManager.bottomIndex); } }); diff --git a/js/ui/layout.js b/js/ui/layout.js index 0b3aa56f0..a84a9b02f 100644 --- a/js/ui/layout.js +++ b/js/ui/layout.js @@ -103,6 +103,7 @@ const LayoutManager = new Lang.Class({ this.monitors = []; this.primaryMonitor = null; this.primaryIndex = -1; + this._keyboardIndex = -1; this._hotCorners = []; this._background = null; 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_size(this.primaryMonitor.width, -1); - this.keyboardBox.set_position(this.bottomMonitor.x, - this.bottomMonitor.y + this.bottomMonitor.height); - this.keyboardBox.set_size(this.bottomMonitor.width, -1); + if (this.keyboardIndex < 0) + this.keyboardIndex = this.primaryIndex; this.trayBox.set_position(this.bottomMonitor.x, this.bottomMonitor.y + this.bottomMonitor.height); @@ -305,6 +305,42 @@ const LayoutManager = new Lang.Class({ 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() { this.panelBox.anchor_y = this.panelBox.height; @@ -363,11 +399,14 @@ const LayoutManager = new Lang.Class({ onComplete: this._showKeyboardComplete, onCompleteScope: this }); - Tweener.addTween(this.trayBox, - { anchor_y: this.keyboardBox.height, - time: KEYBOARD_ANIMATION_TIME, - transition: 'easeOutQuad' - }); + + if (this.keyboardIndex == this.bottomIndex) { + Tweener.addTween(this.trayBox, + { anchor_y: this.keyboardBox.height, + time: KEYBOARD_ANIMATION_TIME, + transition: 'easeOutQuad' + }); + } 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.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, onCompleteScope: this }); - Tweener.addTween(this.trayBox, - { anchor_y: 0, - time: immediate ? 0 : KEYBOARD_ANIMATION_TIME, - transition: 'easeOutQuad' - }); + + if (this.keyboardIndex == this.bottomIndex) { + Tweener.addTween(this.trayBox, + { anchor_y: 0, + time: immediate ? 0 : KEYBOARD_ANIMATION_TIME, + transition: 'easeOutQuad' + }); + } this.emit('keyboard-visible-changed', false); }, @@ -463,7 +506,7 @@ const LayoutManager = new Lang.Class({ }, findMonitorForActor: function(actor) { - return this._chrome.findMonitorForActor(actor); + return this.monitors[this._chrome.findIndexForActor(actor)]; } }); Signals.addSignalMethods(LayoutManager.prototype); @@ -812,6 +855,7 @@ const Chrome = new Lang.Class({ _relayout: function() { this._monitors = this._layoutManager.monitors; + this._primaryIndex = this._layoutManager.primaryIndex; this._primaryMonitor = this._layoutManager.primaryMonitor; this._updateFullscreen(); @@ -827,32 +871,47 @@ const Chrome = new Lang.Class({ let monitor = this._monitors[i]; if (cx >= monitor.x && cx < monitor.x + monitor.width && 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 for (let i = 0; i < this._monitors.length; i++) { let monitor = this._monitors[i]; if (x + w > monitor.x && x < monitor.x + monitor.width && y + h > monitor.y && y < monitor.y + monitor.height) - return monitor; + return i; } // otherwise on no monitor - return null; + return -1; }, - _findMonitorForWindow: function(window) { - return this._findMonitorForRect(window.x, window.y, window.width, window.height); + findIndexForWindow: function(window) { + 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 // 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 [w, h] = actor.get_transformed_size(); - let monitor = this._findMonitorForRect(x, y, w, h); - if (monitor) - return monitor; - return this._primaryMonitor; // Not on any monitor, pretend its on the primary + let i = this._findMonitorForRect(x, y, w, h); + if (i >= 0) + return i; + 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() { @@ -900,7 +959,7 @@ const Chrome = new Lang.Class({ continue; if (layer == Meta.StackLayer.FULLSCREEN) { - let monitor = this._findMonitorForWindow(window); + let monitor = this.findMonitorForWindow(window); if (monitor) monitor.inFullscreen = true; } @@ -917,7 +976,7 @@ const Chrome = new Lang.Class({ } // Or whether it is monitor sized - let monitor = this._findMonitorForWindow(window); + let monitor = this.findMonitorForWindow(window); if (monitor && window.x <= monitor.x && window.x + window.width >= monitor.x + monitor.width && diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index fa1ea31d0..483b71dc4 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -1471,6 +1471,7 @@ const MessageTray = new Lang.Class({ this._pointerInTray = false; this._pointerInKeyboard = false; this._keyboardVisible = false; + this._keyboardUnderMessageTray = false; this._summaryState = State.HIDDEN; this._pointerInSummary = false; this._notificationClosed = false; @@ -1924,12 +1925,15 @@ const MessageTray = new Lang.Class({ }, _onKeyboardVisibleChanged: function(layoutManager, keyboardVisible) { - if (this._keyboardVisible == keyboardVisible) + let keyboardUnderMessageTray = layoutManager.keyboardIndex == layoutManager.bottomIndex; + if (this._keyboardVisible == keyboardVisible && + this._keyboardUnderMesssageTray == keyboardUnderMessageTray) return; this._keyboardVisible = keyboardVisible; + this._keyboardUnderMessageTray = keyboardUnderMessageTray; - if (keyboardVisible) + if (keyboardVisible && keyboardUnderMessageTray) this.actor.add_style_pseudo_class('keyboard'); else this.actor.remove_style_pseudo_class('keyboard'); @@ -2086,12 +2090,12 @@ const MessageTray = new Lang.Class({ this._desktopCloneState == State.SHOWN); let desktopCloneShouldBeVisible = (trayShouldBeVisible && !this._overviewVisible && - !this._keyboardVisible); + (!this._keyboardVisible || !this._keyboardUnderMessageTray)); if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) { this._showDesktopClone(); } else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) { - this._hideDesktopClone (this._keyboardVisible); + this._hideDesktopClone (this._keyboardVisible && this._keyboardUnderMessageTray); } },