on xenial help sign in
merge ~mzanetti/unity8/fix-alt-tab as prereq
455dd39Michael Zanetti
qml/Panel/Panel.qml+8−8
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2016 Canonical, Ltd.
2+ * Copyright (C) 2013-2017 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -85,15 +85,15 @@ Item {
85 property bool showWindowDecorationControls: (revealControls && PanelState.decorationsVisible) ||
85 property bool showWindowDecorationControls: (revealControls && PanelState.decorationsVisible) ||
86 PanelState.decorationsAlwaysVisible
86 PanelState.decorationsAlwaysVisible
87
87
88− property bool showPointerMenu: revealControls &&
88+ property bool showPointerMenu: revealControls && enablePointerMenu &&
89 (PanelState.decorationsVisible || mode == "staged")
89 (PanelState.decorationsVisible || mode == "staged")
90
90
91− property bool enablePointerMenu: revealControls &&
92− applicationMenus.available &&
91+ property bool enablePointerMenu: applicationMenus.available &&
93 applicationMenus.model
92 applicationMenus.model
94
93
95 property bool showTouchMenu: !greeterShown &&
94 property bool showTouchMenu: !greeterShown &&
96− !showPointerMenu
95+ !showPointerMenu &&
96+ !showWindowDecorationControls
97
97
98 property bool enableTouchMenus: showTouchMenu &&
98 property bool enableTouchMenus: showTouchMenu &&
99 applicationMenus.available &&
99 applicationMenus.available &&
@@ -211,7 +211,7 @@ Item {
211 opacity: d.showPointerMenu ? 1 : 0
211 opacity: d.showPointerMenu ? 1 : 0
212 visible: opacity != 0
212 visible: opacity != 0
213 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
213 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
214− active: __applicationMenus.model && !callHint.visible
214+ active: d.showPointerMenu && !callHint.visible
215
215
216 width: parent.width - windowControlButtons.width - units.gu(2) - __indicators.barWidth
216 width: parent.width - windowControlButtons.width - units.gu(2) - __indicators.barWidth
217
217
@@ -220,7 +220,7 @@ Item {
220 sourceComponent: MenuBar {
220 sourceComponent: MenuBar {
221 id: bar
221 id: bar
222 objectName: "menuBar"
222 objectName: "menuBar"
223− anchors.left: parent.left
223+ anchors.left: parent ? parent.left : undefined
224 anchors.margins: units.gu(1)
224 anchors.margins: units.gu(1)
225 height: menuBarLoader.height
225 height: menuBarLoader.height
226 enableKeyFilter: valid && PanelState.decorationsVisible
226 enableKeyFilter: valid && PanelState.decorationsVisible
@@ -339,7 +339,7 @@ Item {
339 maximumLineCount: 1
339 maximumLineCount: 1
340 fontSize: "medium"
340 fontSize: "medium"
341 font.weight: Font.Medium
341 font.weight: Font.Medium
342− color: Theme.palette.selected.backgroundText
342+ color: theme.palette.selected.backgroundText
343 opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0
343 opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0
344 visible: opacity != 0
344 visible: opacity != 0
345 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
345 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
qml/Stage/DecoratedWindow.qml+1
@@ -38,6 +38,7 @@ FocusScope {
38 property alias maximizeButtonShown: decoration.maximizeButtonShown
38 property alias maximizeButtonShown: decoration.maximizeButtonShown
39 property alias interactive: applicationWindow.interactive
39 property alias interactive: applicationWindow.interactive
40 readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled
40 readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled
41+ property alias windowControlButtonsVisible: decoration.windowControlButtonsVisible
41
42
42 // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account.
43 // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account.
43 property bool hasDecoration: true
44 property bool hasDecoration: true
qml/Stage/Stage.qml+11−2
@@ -91,6 +91,7 @@ FocusScope {
91
91
92
92
93 onAltTabPressedChanged: {
93 onAltTabPressedChanged: {
94+ root.focus = true;
94 if (altTabPressed) {
95 if (altTabPressed) {
95 if (root.spreadEnabled) {
96 if (root.spreadEnabled) {
96 altTabDelayTimer.start();
97 altTabDelayTimer.start();
@@ -390,7 +391,7 @@ FocusScope {
390 Binding {
391 Binding {
391 target: PanelState
392 target: PanelState
392 property: "decorationsVisible"
393 property: "decorationsVisible"
393− value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus
394+ value: mode == "windowed" && priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !root.spreadShown
394 }
395 }
395
396
396 Binding {
397 Binding {
@@ -477,6 +478,7 @@ FocusScope {
477 State {
478 State {
478 name: "spread"; when: priv.goneToSpread
479 name: "spread"; when: priv.goneToSpread
479 PropertyChanges { target: floatingFlickable; enabled: true }
480 PropertyChanges { target: floatingFlickable; enabled: true }
481+ PropertyChanges { target: root; focus: true }
480 PropertyChanges { target: spreadItem; focus: true }
482 PropertyChanges { target: spreadItem; focus: true }
481 PropertyChanges { target: hoverMouseArea; enabled: true }
483 PropertyChanges { target: hoverMouseArea; enabled: true }
482 PropertyChanges { target: rightEdgeDragArea; enabled: false }
484 PropertyChanges { target: rightEdgeDragArea; enabled: false }
@@ -516,14 +518,20 @@ FocusScope {
516 State {
518 State {
517 name: "staged"; when: root.mode === "staged"
519 name: "staged"; when: root.mode === "staged"
518 PropertyChanges { target: wallpaper; visible: !priv.focusedAppDelegate || priv.focusedAppDelegate.x !== 0 }
520 PropertyChanges { target: wallpaper; visible: !priv.focusedAppDelegate || priv.focusedAppDelegate.x !== 0 }
521+ PropertyChanges { target: root; focus: true }
522+ PropertyChanges { target: appContainer; focus: true }
519 },
523 },
520 State {
524 State {
521 name: "stagedWithSideStage"; when: root.mode === "stagedWithSideStage"
525 name: "stagedWithSideStage"; when: root.mode === "stagedWithSideStage"
522 PropertyChanges { target: triGestureArea; enabled: priv.sideStageEnabled }
526 PropertyChanges { target: triGestureArea; enabled: priv.sideStageEnabled }
523 PropertyChanges { target: sideStage; visible: true }
527 PropertyChanges { target: sideStage; visible: true }
528+ PropertyChanges { target: root; focus: true }
529+ PropertyChanges { target: appContainer; focus: true }
524 },
530 },
525 State {
531 State {
526 name: "windowed"; when: root.mode === "windowed"
532 name: "windowed"; when: root.mode === "windowed"
533+ PropertyChanges { target: root; focus: true }
534+ PropertyChanges { target: appContainer; focus: true }
527 }
535 }
528 ]
536 ]
529 transitions: [
537 transitions: [
@@ -1383,6 +1391,7 @@ FocusScope {
1383 requestedHeight: appContainer.height;
1391 requestedHeight: appContainer.height;
1384 }
1392 }
1385 PropertyChanges { target: touchControls; enabled: true }
1393 PropertyChanges { target: touchControls; enabled: true }
1394+ PropertyChanges { target: decoratedWindow; windowControlButtonsVisible: false }
1386 },
1395 },
1387 State {
1396 State {
1388 name: "fullscreen"; when: appDelegate.fullscreen && !appDelegate.minimized
1397 name: "fullscreen"; when: appDelegate.fullscreen && !appDelegate.minimized
@@ -1405,7 +1414,7 @@ FocusScope {
1405 }
1414 }
1406 PropertyChanges { target: touchControls; enabled: true }
1415 PropertyChanges { target: touchControls; enabled: true }
1407 PropertyChanges { target: resizeArea; enabled: true }
1416 PropertyChanges { target: resizeArea; enabled: true }
1408− PropertyChanges { target: decoratedWindow; shadowOpacity: .3}
1417+ PropertyChanges { target: decoratedWindow; shadowOpacity: .3; windowControlButtonsVisible: true}
1409 },
1418 },
1410 State {
1419 State {
1411 name: "restored";
1420 name: "restored";
qml/Stage/WindowDecoration.qml+1
@@ -34,6 +34,7 @@ MouseArea {
34 property var menu: undefined
34 property var menu: undefined
35 property bool enableMenus: true
35 property bool enableMenus: true
36 property bool windowMoving: false
36 property bool windowMoving: false
37+ property alias windowControlButtonsVisible: buttons.visible
37
38
38 readonly property real buttonsWidth: buttons.width + row.spacing
39 readonly property real buttonsWidth: buttons.width + row.spacing
39
40
tests/qmltests/Panel/tst_Panel.qml+3−25
@@ -779,40 +779,18 @@ PanelTest {
779
779
780 var appTitle = findChild(panel, "panelTitle"); verify(appTitle);
780 var appTitle = findChild(panel, "panelTitle"); verify(appTitle);
781 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
781 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
782− var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
782+ var menuBarLoader = findChild(panel, "menuBarLoader"); verify(menuBarLoader);
783
783
784 tryCompare(appTitle, "visible", true, undefined, "App title should be visible");
784 tryCompare(appTitle, "visible", true, undefined, "App title should be visible");
785− tryCompare(appMenuBar, "visible", false, undefined, "App menu bar should not be visible");
785+ tryCompare(menuBarLoader, "visible", false, undefined, "App menu bar should not be visible");
786
786
787 mouseMove(panel, panel.width/2, panel.panelHeight);
787 mouseMove(panel, panel.width/2, panel.panelHeight);
788
788
789+ var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
789 tryCompare(appTitle, "visible", false, undefined, "App title should not be visible on mouse hover");
790 tryCompare(appTitle, "visible", false, undefined, "App title should not be visible on mouse hover");
790 tryCompare(appMenuBar, "visible", true, undefined, "App menu bar should be visible on mouse hover");
791 tryCompare(appMenuBar, "visible", true, undefined, "App menu bar should be visible on mouse hover");
791 }
792 }
792
793
793− function test_windowedApplicationMenuShowOnMouseHoverWhenDecorationsShown() {
794− PanelState.title = "Fake Title";
795− panel.mode = "windowed";
796− mouseEmulation.checked = false;
797−
798− var appTitle = findChild(panel, "panelTitle"); verify(appTitle);
799− var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
800− var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
801−
802− tryCompare(appTitle, "visible", true, undefined, "App title should be visible");
803− tryCompare(appMenuBar, "visible", false, undefined, "App menu bar should not be visible");
804−
805− mouseMove(panel, panel.width/2, panel.panelHeight);
806−
807− tryCompare(appTitle, "visible", true, undefined, "App title should still be visible on mouse hover when panel decorations are not visible");
808− tryCompare(appMenuBar, "visible", false, undefined, "App menu bar should be visible on mouse hover when panel decorations are not visible");
809−
810− PanelState.decorationsVisible = true;
811−
812− tryCompare(appTitle, "visible", false, undefined, "App title should still be visible on mouse hover when panel decorations are visible");
813− tryCompare(appMenuBar, "visible", true, undefined, "App menu bar should be visible on mouse hover when panel decorations not visible");
814− }
815−
816 function test_keyboardNavigation_data() {
794 function test_keyboardNavigation_data() {
817 return [
795 return [
818 {tag: "tab to start", doTab: false},
796 {tag: "tab to start", doTab: false},
tests/qmltests/Stage/tst_DesktopStage.qml+1−5
@@ -863,11 +863,7 @@ Item {
863 maximizeAppDelegate(appDelegate);
863 maximizeAppDelegate(appDelegate);
864
864
865 // Close the window and restart the application
865 // Close the window and restart the application
866− var closeButton = findChild(appDelegate, "closeWindowButton");
866+ appDelegate.close();
867− appDelegate = null;
868− verify(closeButton);
869− mouseClick(closeButton);
870− closeButton = null;
871 tryCompare(topSurfaceList, "count", originalWindowCount);
867 tryCompare(topSurfaceList, "count", originalWindowCount);
872 wait(100); // plus some spare room
868 wait(100); // plus some spare room
873 appDelegate = startApplication("dialer-app");
869 appDelegate = startApplication("dialer-app");
tests/qmltests/tst_Shell.qml+90
@@ -3175,6 +3175,96 @@ Rectangle {
3175 tryCompare(menuBarLoader.item, "visible", true);
3175 tryCompare(menuBarLoader.item, "visible", true);
3176 }
3176 }
3177
3177
3178+ function test_enforceFocusOnStageOnAltTab() {
3179+ loadShell("desktop");
3180+ shell.usageScenario = "desktop";
3181+ waitForRendering(shell);
3182+ swipeAwayGreeter();
3183+
3184+ var appSurfaceId = topLevelSurfaceList.nextId;
3185+ var app = ApplicationManager.startApplication("unity8-dash")
3186+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
3187+
3188+ var appDelegate = startApplication("music-app")
3189+ verify(appDelegate);
3190+ waitForRendering(shell);
3191+
3192+ var launcher = findChild(shell, "launcher");
3193+ launcher.focus = true;
3194+
3195+ var stage = findChild(shell, "stage");
3196+
3197+ var spreadItem = findChild(shell, "spreadItem");
3198+
3199+ compare(spreadItem.highlightedIndex, -1);
3200+
3201+ keyPress(Qt.Key_Alt);
3202+ keyClick(Qt.Key_Tab);
3203+
3204+ tryCompare(spreadItem, "highlightedIndex", 1);
3205+ tryCompare(stage, "focus", true);
3206+
3207+ keyClick(Qt.Key_Tab);
3208+
3209+ tryCompare(spreadItem, "highlightedIndex", 0);
3210+
3211+ keyRelease(Qt.Key_Alt);
3212+ }
3213+
3214+ function test_maximizedWindowMenuThenAltTab_data() {
3215+ return [
3216+ { tag: "show spread", showSpread: true },
3217+ { tag: "do not show spread", showSpread: false },
3218+ ];
3219+ }
3220+
3221+ function test_maximizedWindowMenuThenAltTab(data) {
3222+ loadShell("desktop");
3223+ shell.usageScenario = "desktop";
3224+ waitForRendering(shell);
3225+ swipeAwayGreeter();
3226+
3227+ var appDelegate = startApplication("gmail-webapp");
3228+ var appDelegate2 = startApplication("dialer-app");
3229+
3230+ tryCompare(appDelegate2.surface, "activeFocus", true);
3231+
3232+ var maximizeButton = findChild(appDelegate2, "maximizeWindowButton");
3233+ mouseClick(maximizeButton);
3234+ tryCompare(appDelegate2, "state", "maximized");
3235+
3236+ var panel = findChild(shell, "panel");
3237+ var panelMouse = findChild(panel, "windowControlArea");
3238+ mouseMove(panelMouse);
3239+ var panelMenu = findChild(panel, "menuBar");
3240+ var menuBarLoader = findChild(panel, "menuBarLoader");
3241+ mouseMove(panelMenu);
3242+ var panelMenuItem = findChild(panelMenu, "menuBar-item0");
3243+ tryCompare(panelMenuItem, "visible", true);
3244+ Util.waitForBehaviors(shell);
3245+ mouseClick(panelMenuItem);
3246+ var panelMenuItemItem = findChild(panelMenu, "menuBar-item0-menu-item0-actionItem");
3247+ mouseMove(panelMenuItemItem, panelMenuItemItem.width/2, panelMenuItemItem.height/2);
3248+ verify(panelMenuItemItem.activeFocus);
3249+ verify(panelMenuItem.__popup);
3250+
3251+ keyPress(Qt.Key_Alt);
3252+ keyClick(Qt.Key_Tab);
3253+ if (data.showSpread) {
3254+ tryCompare(stage, "spreadShown", true);
3255+ }
3256+ tryCompareFunction(function() { return menuBarLoader.active === false; }, true);
3257+ keyRelease(Qt.Key_Alt)
3258+
3259+ tryCompare(appDelegate.surface, "activeFocus", true);
3260+
3261+ keyPress(Qt.Key_Alt);
3262+ keyClick(Qt.Key_Tab);
3263+ keyRelease(Qt.Key_Alt)
3264+
3265+ tryCompare(appDelegate2.surface, "activeFocus", true);
3266+ }
3267+
3178 function test_maximizedWindowAndMenuInPanel() {
3268 function test_maximizedWindowAndMenuInPanel() {
3179 loadShell("desktop");
3269 loadShell("desktop");
3180 shell.usageScenario = "desktop";
3270 shell.usageScenario = "desktop";