on xenial help sign in
Application-level focus requests
62ef20cDaniel d'Andrada
qml/Stages/DesktopStage.qml+16−3
@@ -284,13 +284,26 @@ AbstractStage {
284
284
285 readonly property var surface: model.surface
285 readonly property var surface: model.surface
286
286
287+ function claimFocus() {
288+ if (spread.state == "altTab") {
289+ spread.cancel();
290+ }
291+ appDelegate.restore();
292+ }
287 Connections {
293 Connections {
288 target: model.surface
294 target: model.surface
295+ onFocusRequested: claimFocus();
296+ }
297+ Connections {
298+ target: model.application
289 onFocusRequested: {
299 onFocusRequested: {
290− if (spread.state == "altTab") {
300+ if (!model.surface) {
291− spread.cancel();
301+ // when an app has no surfaces, we assume there's only one entry representing it,
302+ // this delegate.
303+ claimFocus();
304+ } else {
305+ // if the application has surfaces, focus request should be at surface-level.
292 }
306 }
293− appDelegate.restore();
294 }
307 }
295 }
308 }
296
309
qml/Stages/PhoneStage.qml+16−3
@@ -531,13 +531,26 @@ AbstractStage {
531 }
531 }
532 }
532 }
533 }
533 }
534+ function claimFocus() {
535+ if (spreadView.phase > 0) {
536+ spreadView.snapTo(model.index);
537+ } else {
538+ appDelegate.focus = true;
539+ }
540+ }
534 Connections {
541 Connections {
535 target: model.surface
542 target: model.surface
543+ onFocusRequested: claimFocus()
544+ }
545+ Connections {
546+ target: model.application
536 onFocusRequested: {
547 onFocusRequested: {
537− if (spreadView.phase > 0) {
548+ if (!model.surface) {
538− spreadView.snapTo(model.index);
549+ // when an app has no surfaces, we assume there's only one entry representing it,
550+ // this delegate.
551+ claimFocus();
539 } else {
552 } else {
540− appDelegate.focus = true;
553+ // if the application has surfaces, focus request should be at surface-level.
541 }
554 }
542 }
555 }
543 }
556 }
qml/Stages/TabletStage.qml+12
@@ -766,6 +766,18 @@ AbstractStage {
766 target: model.surface
766 target: model.surface
767 onFocusRequested: spreadTile.focus = true;
767 onFocusRequested: spreadTile.focus = true;
768 }
768 }
769+ Connections {
770+ target: model.application
771+ onFocusRequested: {
772+ if (!model.surface) {
773+ // when an app has no surfaces, we assume there's only one entry representing it,
774+ // this delegate.
775+ spreadTile.focus = true;
776+ } else {
777+ // if the application has surfaces, focus request should be at surface-level.
778+ }
779+ }
780+ }
769
781
770 fullscreen: {
782 fullscreen: {
771 if (priv.mainStageDelegate && stage === ApplicationInfoInterface.SideStage) {
783 if (priv.mainStageDelegate && stage === ApplicationInfoInterface.SideStage) {
tests/mocks/Unity/Application/ApplicationInfo.cpp+9−3
@@ -108,9 +108,6 @@ void ApplicationInfo::createSurface()
108 m_closingSurfaces.removeAll(surface);
108 m_closingSurfaces.removeAll(surface);
109 }
109 }
110 });
110 });
111− connect(surface, &MirSurface::focusRequested, this, [this](){
112− Q_EMIT this->focusRequested();
113− });
114 connect(surface, &MirSurface::closeRequested, this, [this, surface](){
111 connect(surface, &MirSurface::closeRequested, this, [this, surface](){
115 m_closingSurfaces.append(surface);
112 m_closingSurfaces.append(surface);
116 if (m_state == Suspended) {
113 if (m_state == Suspended) {
@@ -367,3 +364,12 @@ void ApplicationInfo::onSurfaceCountChanged()
367 setState(Stopped);
364 setState(Stopped);
368 }
365 }
369}
366}
367+
368+void ApplicationInfo::requestFocus()
369+{
370+ if (m_surfaceList.count() == 0) {
371+ Q_EMIT focusRequested();
372+ } else {
373+ m_surfaceList.get(0)->requestFocus();
374+ }
375+}
tests/mocks/Unity/Application/ApplicationInfo.h+1−4
@@ -112,16 +112,13 @@ public:
112 //////
112 //////
113 // internal mock stuff
113 // internal mock stuff
114 void close();
114 void close();
115+ void requestFocus();
115
116
116Q_SIGNALS:
117Q_SIGNALS:
117 void fullscreenChanged(bool value);
118 void fullscreenChanged(bool value);
118 void manualSurfaceCreationChanged(bool value);
119 void manualSurfaceCreationChanged(bool value);
119 void closed();
120 void closed();
120
121
121− ////
122− // FIXME: Move to unity::shell::application::ApplicationInfoInterface
123− void focusRequested();
124−
125public Q_SLOTS:
122public Q_SLOTS:
126 Q_INVOKABLE void createSurface();
123 Q_INVOKABLE void createSurface();
127
124
tests/mocks/Unity/Application/ApplicationManager.cpp+1−5
@@ -302,11 +302,7 @@ bool ApplicationManager::requestFocusApplication(const QString &appId)
302 if (application == nullptr)
302 if (application == nullptr)
303 return false;
303 return false;
304
304
305− auto surfaceList = static_cast<MirSurfaceListModel*>(application->surfaceList());
306− if (surfaceList->count() == 0)
307− return false;
308−
309− surfaceList->get(0)->requestFocus();
305+ application->requestFocus();
310
306
311 return true;
307 return true;
312}
308}