diff options
| author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2012-04-26 02:34:30 -0400 |
|---|---|---|
| committer | Tarmac <> | 2012-04-26 02:34:30 -0400 |
| commit | 98202ab0f76a6001811f6685f1057c223520c568 (patch) | |
| tree | 5174a6e290ea02fd12becb6fd49f6c2292607c3f | |
| parent | be388ce31f5bb1c27b35409b6d3e702b0ed42f9c (diff) | |
| parent | b3780e5cd069c8d8ae38d2cd46ce9caeb9ee3efc (diff) | |
BamfLauncherIcon: Focus an application if no child window is actually on top of the stack. Raises all urgent windows.
This fixes bug #802816 that happens when an application raises a window on the top of the stack but the focus doesn't change. Plus, don't perform unneeded checks when focusing non-active applications.. Fixes: https://bugs.launchpad.net/bugs/802816, https://bugs.launchpad.net/bugs/986443. Approved by Tim Penhey. (bzr r2344)
| -rw-r--r-- | manual-tests/Launcher.txt | 23 | ||||
| -rw-r--r-- | plugins/unityshell/src/BamfLauncherIcon.cpp | 80 | ||||
| -rw-r--r-- | plugins/unityshell/src/PluginAdapter.cpp | 33 | ||||
| -rw-r--r-- | plugins/unityshell/src/PluginAdapter.h | 1 | ||||
| -rw-r--r-- | plugins/unityshell/src/WindowManager.cpp | 5 | ||||
| -rw-r--r-- | plugins/unityshell/src/WindowManager.h | 1 |
6 files changed, 108 insertions, 35 deletions
diff --git a/manual-tests/Launcher.txt b/manual-tests/Launcher.txt index 67b873681..9b3c1caed 100644 --- a/manual-tests/Launcher.txt +++ b/manual-tests/Launcher.txt @@ -489,6 +489,7 @@ Expected Result: The Firefox icon should *not* be highlighted during the drag&drop. Firefox should open the folder in a new Firefox window. + Test Launcher with Chromium Web apps ------------------------------------ This tests shows the integration of unity with the Chromium Web Apps @@ -517,3 +518,25 @@ Expected Results: application icon. * Clicking the "Home | Ubuntu" will activate its window, while clicking in the chromium icon will activate a chromium window. + + +Test Launcher raises focused non-top windows +-------------------------------------------- +This tests shows how the focused windows should be raised to the top of the +stack, when another non-active window is over them. + +Actions: + * Open a terminal Window + * Open The GIMP + * In GIMP load an image, say /usr/share/backgrounds/warty-final-ubuntu.png + * From the terminal window run the command "gimp foo-image.png" + +Expected Results: + * A gimp dialog will be raised (so the terminal window is below it), but not focused + * Terminal launcher icon must have a filled-in arrow on the right of the icon + +Actions: + * Click on the launcher terminal icon + +Expected Results: + * Terminal window will be raised to the top of the stack (over the GIMP window) diff --git a/plugins/unityshell/src/BamfLauncherIcon.cpp b/plugins/unityshell/src/BamfLauncherIcon.cpp index 84881d69e..01205fc24 100644 --- a/plugins/unityshell/src/BamfLauncherIcon.cpp +++ b/plugins/unityshell/src/BamfLauncherIcon.cpp @@ -208,50 +208,59 @@ void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) auto bamf_view = glib::object_cast<BamfView>(_bamf_app); user_visible = bamf_view_user_visible(bamf_view); - bool any_visible = false; - bool any_mapped = false; - bool any_on_monitor = (arg.monitor < 0); - int active_monitor = arg.monitor; - GList* children = bamf_view_get_children(bamf_view); - - for (GList* l = children; l; l = l->next) + if (active) { - if (!BAMF_IS_WINDOW(l->data)) - continue; + bool any_visible = false; + bool any_mapped = false; + bool any_on_top = false; + bool any_on_monitor = (arg.monitor < 0); + int active_monitor = arg.monitor; + GList* children = bamf_view_get_children(bamf_view); + + for (GList* l = children; l; l = l->next) + { + if (!BAMF_IS_WINDOW(l->data)) + continue; - auto view = static_cast<BamfView*>(l->data); - auto win = static_cast<BamfWindow*>(l->data); - Window xid = bamf_window_get_xid(win); + auto view = static_cast<BamfView*>(l->data); + auto win = static_cast<BamfWindow*>(l->data); + Window xid = bamf_window_get_xid(win); - if (!any_visible && wm->IsWindowOnCurrentDesktop(xid)) - { - any_visible = true; - } + if (!any_visible && wm->IsWindowOnCurrentDesktop(xid)) + { + any_visible = true; + } - if (!any_mapped && wm->IsWindowMapped(xid)) - { - any_mapped = true; - } + if (!any_mapped && wm->IsWindowMapped(xid)) + { + any_mapped = true; + } - if (!any_on_monitor && bamf_window_get_monitor(win) == arg.monitor && - wm->IsWindowMapped(xid) && wm->IsWindowVisible(xid)) - { - any_on_monitor = true; - } + if (!any_on_top && wm->IsWindowOnTop(xid)) + { + any_on_top = true; + } - if (bamf_view_is_active(view)) - { - active_monitor = bamf_window_get_monitor(win); + if (!any_on_monitor && bamf_window_get_monitor(win) == arg.monitor && + wm->IsWindowMapped(xid) && wm->IsWindowVisible(xid)) + { + any_on_monitor = true; + } + + if (bamf_view_is_active(view)) + { + active_monitor = bamf_window_get_monitor(win); + } } - } - g_list_free(children); + g_list_free(children); - if (!any_visible || !any_mapped) - active = false; + if (!any_visible || !any_mapped || !any_on_top) + active = false; - if (any_on_monitor && arg.monitor >= 0 && active_monitor != arg.monitor) - active = false; + if (any_on_monitor && arg.monitor >= 0 && active_monitor != arg.monitor) + active = false; + } } /* Behaviour: @@ -635,7 +644,8 @@ void BamfLauncherIcon::Focus(ActionArg arg) } } - wm->FocusWindowGroup(windows, visibility, arg.monitor); + bool only_top_win = !any_urgent; + wm->FocusWindowGroup(windows, visibility, arg.monitor, only_top_win); } bool BamfLauncherIcon::Spread(bool current_desktop, int state, bool force) diff --git a/plugins/unityshell/src/PluginAdapter.cpp b/plugins/unityshell/src/PluginAdapter.cpp index ad069a059..e9008c224 100644 --- a/plugins/unityshell/src/PluginAdapter.cpp +++ b/plugins/unityshell/src/PluginAdapter.cpp @@ -530,6 +530,39 @@ PluginAdapter::IsWindowVisible(guint32 xid) } bool +PluginAdapter::IsWindowOnTop(guint32 xid) +{ + Window win = xid; + CompWindow* window; + + window = m_Screen->findWindow(win); + + if (window) + { + if (window->inShowDesktopMode() || !window->isMapped() || !window->isViewable() || window->minimized()) + return false; + + CompPoint window_vp = window->defaultViewport(); + std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList(); + + for (CompWindow* sibling = window->next; sibling; sibling = sibling->next) + { + if (sibling->defaultViewport() == window_vp && !sibling->minimized() && + sibling->isMapped() && sibling->isViewable() && !sibling->inShowDesktopMode() && + !(sibling->state() & CompWindowStateAboveMask) && + std::find(our_xids.begin(), our_xids.end(), sibling->id()) == our_xids.end()) + { + return false; + } + } + + return true; + } + + return false; +} + +bool PluginAdapter::IsWindowClosable(guint32 xid) { Window win = xid; diff --git a/plugins/unityshell/src/PluginAdapter.h b/plugins/unityshell/src/PluginAdapter.h index 43300914b..70d5e433c 100644 --- a/plugins/unityshell/src/PluginAdapter.h +++ b/plugins/unityshell/src/PluginAdapter.h @@ -121,6 +121,7 @@ public: bool IsWindowObscured(guint xid); bool IsWindowMapped(guint xid); bool IsWindowVisible(guint32 xid); + bool IsWindowOnTop(guint32 xid); bool IsWindowClosable(guint32 xid); bool IsWindowMinimizable(guint32 xid); bool IsWindowMaximizable(guint32 xid); diff --git a/plugins/unityshell/src/WindowManager.cpp b/plugins/unityshell/src/WindowManager.cpp index c4f5c7486..cde2dc149 100644 --- a/plugins/unityshell/src/WindowManager.cpp +++ b/plugins/unityshell/src/WindowManager.cpp @@ -78,6 +78,11 @@ class WindowManagerDummy : public WindowManager return true; } + bool IsWindowOnTop(guint32 xid) + { + return false; + } + bool IsWindowClosable(guint32 xid) { return true; diff --git a/plugins/unityshell/src/WindowManager.h b/plugins/unityshell/src/WindowManager.h index 9b9590c24..4e74b022a 100644 --- a/plugins/unityshell/src/WindowManager.h +++ b/plugins/unityshell/src/WindowManager.h @@ -57,6 +57,7 @@ public: virtual bool IsWindowObscured(guint32 xid) = 0; virtual bool IsWindowMapped(guint32 xid) = 0; virtual bool IsWindowVisible(guint32 xid) = 0; + virtual bool IsWindowOnTop(guint32 xid) = 0; virtual bool IsWindowClosable(guint32 xid) = 0; virtual bool IsWindowMinimizable(guint32 xid) = 0; virtual bool IsWindowMaximizable(guint32 xid) = 0; |
