summaryrefslogtreecommitdiff
diff options
authorDidier Roche <didier.roche@canonical.com>2012-04-27 13:42:56 +0200
committerDidier Roche <didier.roche@canonical.com>2012-04-27 13:42:56 +0200
commit41e7dbcc037860af86cb77713e3d880a2f3dbd37 (patch)
treeb339d9f91411d0d27f8e2d5e8afc7d32509e440b
parent05e7d1ad58fa421d7be53daa1b6f8cfff4817ee5 (diff)
parentede961f2de3dbaa124a2bb3a4feb3c58e06e0c48 (diff)
New upstream release.
(bzr r55.3.643)
-rw-r--r--AUTHORS4
-rw-r--r--CMakeLists.txt2
-rw-r--r--ChangeLog1606
-rw-r--r--UnityCore/GLibSignal.cpp2
-rw-r--r--UnityCore/Hud.cpp10
-rw-r--r--debian/changelog6
-rw-r--r--manual-tests/Launcher.txt75
-rw-r--r--manual-tests/SoftwareCenter.txt16
-rw-r--r--manual-tests/Switcher.txt18
-rw-r--r--manual-tests/WindowButtons.txt11
-rw-r--r--plugins/unityshell/src/AbstractLauncherIcon.h9
-rw-r--r--plugins/unityshell/src/BFBLauncherIcon.cpp2
-rw-r--r--plugins/unityshell/src/BamfLauncherIcon.cpp150
-rw-r--r--plugins/unityshell/src/BamfLauncherIcon.h8
-rw-r--r--plugins/unityshell/src/DashController.cpp14
-rw-r--r--plugins/unityshell/src/DashStyle.cpp10
-rw-r--r--plugins/unityshell/src/DashStyle.h3
-rw-r--r--plugins/unityshell/src/DashView.cpp36
-rw-r--r--plugins/unityshell/src/DebugDBusInterface.cpp8
-rw-r--r--plugins/unityshell/src/DebugDBusInterface.h2
-rw-r--r--plugins/unityshell/src/DesktopLauncherIcon.cpp3
-rw-r--r--plugins/unityshell/src/DeviceLauncherIcon.cpp2
-rw-r--r--plugins/unityshell/src/DeviceLauncherIcon.h4
-rw-r--r--plugins/unityshell/src/DeviceLauncherSection.cpp123
-rw-r--r--plugins/unityshell/src/DeviceLauncherSection.h27
-rw-r--r--plugins/unityshell/src/DndData.h8
-rw-r--r--plugins/unityshell/src/GestureEngine.cpp3
-rw-r--r--plugins/unityshell/src/HudController.cpp56
-rw-r--r--plugins/unityshell/src/HudController.h3
-rw-r--r--plugins/unityshell/src/HudIcon.cpp26
-rw-r--r--plugins/unityshell/src/HudIcon.h6
-rw-r--r--plugins/unityshell/src/HudLauncherIcon.cpp7
-rw-r--r--plugins/unityshell/src/HudView.cpp50
-rw-r--r--plugins/unityshell/src/HudView.h4
-rw-r--r--plugins/unityshell/src/IconTexture.cpp3
-rw-r--r--plugins/unityshell/src/IconTexture.h2
-rw-r--r--plugins/unityshell/src/Launcher.cpp6
-rw-r--r--plugins/unityshell/src/LauncherController.cpp35
-rw-r--r--plugins/unityshell/src/LauncherController.h9
-rw-r--r--plugins/unityshell/src/LauncherIcon.cpp12
-rw-r--r--plugins/unityshell/src/LauncherIcon.h21
-rw-r--r--plugins/unityshell/src/LensBar.cpp16
-rw-r--r--plugins/unityshell/src/LensBarIcon.cpp1
-rw-r--r--plugins/unityshell/src/MockLauncherIcon.h11
-rw-r--r--plugins/unityshell/src/OverlayRenderer.cpp22
-rw-r--r--plugins/unityshell/src/PanelMenuView.cpp5
-rw-r--r--plugins/unityshell/src/PlacesGroup.cpp3
-rw-r--r--plugins/unityshell/src/PluginAdapter.cpp75
-rw-r--r--plugins/unityshell/src/PluginAdapter.h4
-rw-r--r--plugins/unityshell/src/PointerBarrier.h4
-rw-r--r--plugins/unityshell/src/QuicklistMenuItem.cpp32
-rw-r--r--plugins/unityshell/src/QuicklistMenuItem.h7
-rw-r--r--plugins/unityshell/src/QuicklistMenuItemSeparator.cpp6
-rw-r--r--plugins/unityshell/src/QuicklistMenuItemSeparator.h2
-rw-r--r--plugins/unityshell/src/QuicklistView.cpp252
-rw-r--r--plugins/unityshell/src/QuicklistView.h6
-rw-r--r--plugins/unityshell/src/ResultRendererTile.cpp26
-rw-r--r--plugins/unityshell/src/ResultViewGrid.cpp40
-rw-r--r--plugins/unityshell/src/ResultViewGrid.h6
-rw-r--r--plugins/unityshell/src/SearchBar.cpp9
-rw-r--r--plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp29
-rw-r--r--plugins/unityshell/src/SoftwareCenterLauncherIcon.h1
-rw-r--r--plugins/unityshell/src/StaticCairoText.cpp6
-rw-r--r--plugins/unityshell/src/SwitcherController.cpp6
-rw-r--r--plugins/unityshell/src/TrashLauncherIcon.cpp10
-rw-r--r--plugins/unityshell/src/TrashLauncherIcon.h6
-rw-r--r--plugins/unityshell/src/UBusMessages.h3
-rw-r--r--plugins/unityshell/src/UScreen.cpp128
-rw-r--r--plugins/unityshell/src/UScreen.h23
-rw-r--r--plugins/unityshell/src/UnityShowdesktopHandler.cpp15
-rw-r--r--plugins/unityshell/src/UnityShowdesktopHandler.h9
-rw-r--r--plugins/unityshell/src/WindowButtons.cpp43
-rw-r--r--plugins/unityshell/src/WindowManager.cpp24
-rw-r--r--plugins/unityshell/src/WindowManager.h19
-rw-r--r--plugins/unityshell/src/compizminimizedwindowhandler.h84
-rw-r--r--plugins/unityshell/src/inputremover.h45
-rw-r--r--plugins/unityshell/src/minimizedwindowhandler.cpp38
-rw-r--r--plugins/unityshell/src/minimizedwindowhandler.h2
-rw-r--r--plugins/unityshell/src/unityshell.cpp67
-rw-r--r--plugins/unityshell/src/unityshell.h17
-rw-r--r--services/panel-service.c3
-rw-r--r--standalone-clients/CMakeLists.txt23
-rw-r--r--standalone-clients/TestLauncher.cpp9
-rw-r--r--tests/autopilot/autopilot/emulators/bamf.py10
-rw-r--r--tests/autopilot/autopilot/emulators/unity/__init__.py79
-rw-r--r--tests/autopilot/autopilot/emulators/unity/dash.py46
-rw-r--r--tests/autopilot/autopilot/emulators/unity/hud.py4
-rw-r--r--tests/autopilot/autopilot/emulators/unity/icons.py6
-rw-r--r--tests/autopilot/autopilot/emulators/unity/launcher.py79
-rw-r--r--tests/autopilot/autopilot/emulators/unity/quicklist.py57
-rw-r--r--tests/autopilot/autopilot/emulators/unity/shortcut_hint.py25
-rw-r--r--tests/autopilot/autopilot/emulators/unity/window_manager.py22
-rw-r--r--tests/autopilot/autopilot/keybindings.py18
-rw-r--r--tests/autopilot/autopilot/matchers/__init__.py31
-rw-r--r--tests/autopilot/autopilot/tests/__init__.py21
-rw-r--r--tests/autopilot/autopilot/tests/test_command_lens.py38
-rw-r--r--tests/autopilot/autopilot/tests/test_dash.py243
-rw-r--r--tests/autopilot/autopilot/tests/test_home_lens.py4
-rw-r--r--tests/autopilot/autopilot/tests/test_hud.py302
-rw-r--r--tests/autopilot/autopilot/tests/test_ibus.py190
-rw-r--r--tests/autopilot/autopilot/tests/test_launcher.py243
-rw-r--r--tests/autopilot/autopilot/tests/test_panel.py215
-rw-r--r--tests/autopilot/autopilot/tests/test_quicklist.py295
-rw-r--r--tests/autopilot/autopilot/tests/test_shortcut_hint.py227
-rw-r--r--tests/test-gesture-engine/CMakeLists.txt2
-rw-r--r--tests/test-gesture-engine/compiz_mock/core/screen.h12
-rw-r--r--tests/test-gesture-engine/test_gesture_engine.cpp21
-rw-r--r--tests/test-minimize-window-handler/test-minimize-handler.cpp19
-rw-r--r--tests/test_showdesktop_handler.cpp108
-rw-r--r--tests/unit/TestQuicklistMenuitems.cpp4
-rwxr-xr-xtools/unity.cmake2
111 files changed, 4211 insertions, 1651 deletions
diff --git a/AUTHORS b/AUTHORS
index 868dea6f3..494544df3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -62,6 +62,7 @@
Marco Trevisan (Treviño) <mail@3v1n0.net>
Marco Trevisan (Treviño) <mail@3v1n0.net>, 3v1n0 <mail@3v1n0.net>
Marco Trevisan (Treviño) <mail@3v1n0.net>, Andrea Cimitan <andrea.cimitan@canonical.com>
+ Marco Trevisan (Treviño) <mail@3v1n0.net>, Brandon Schaefer <brandontschaefer@gmail.com>, Tim Penhey <tim.penhey@canonical.com>
Marco Trevisan (Treviño) <mail@3v1n0.net>, Michal Hruby <michal.mhr@gmail.com>
Marco Trevisan (Treviño) <mail@3v1n0.net>, Thomi Richards <thomi.richards@canonical.com>
Marius Gedminas <marius@gedmin.as>
@@ -70,6 +71,7 @@
Michael Rawson <michaelrawson76@gmail.com>
Michael Terry <michael.terry@canonical.com>
Michael Terry <mike@mterry.name>
+ Michael Vogt <michael.vogt@ubuntu.com>
Michal Hruby <michal.mhr@gmail.com>
Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
Mirco Müller <mirco.mueller@ubuntu.com>
@@ -101,6 +103,8 @@
Thomi Richards <thomir@gmail.com>, Alex Launi <alex.launi@canonical.com>
Thomi Richards <thomir@gmail.com>, Thomi Richards <thomi.richards@canonical.com>
Thomi Richards <thomi.richards@canonical.com>
+ Thomi Richards <thomi.richards@canonical.com>, Alex Launi <alex.launi@canonical.com>
+ Thomi Richards <thomi.richards@canonical.com>, Brandon Schaefer <brandontschaefer@gmail.com>
Thomi Richards <thomi.richards@canonical.com>, Gordon Allott <gord.allott@canonical.com>
Thomi Richards <thomi.richards@canonical.com>, Jason Smith <jason.smith@canonical.com>
Thomi Richards <thomi.richards@canonical.com>, Ted Gould <ted@gould.cx>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3928ef983..80c14071e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ include (cmake/Documentation.cmake)
#
set (PROJECT_NAME "unity")
set (UNITY_MAJOR 5)
-set (UNITY_MINOR 10)
+set (UNITY_MINOR 12)
set (UNITY_MICRO 0)
set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}")
set (UNITY_API_VERSION "5.0")
diff --git a/ChangeLog b/ChangeLog
index 5a2ad4357..9f30e5abb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,1609 @@
+2012-04-26 Sebastien Bacher <seb128@ubuntu.com>
+
+ Revert r2331, it's creating hang issues on start.. Fixes: . Approved by Didier Roche.
+
+2012-04-26 Sebastien Bacher <seb128@ubuntu.com>
+
+ Revert r2331, it's creating hang issues on start. The commit is not fixing any
+ important issue and not needed in the SRU, it can come once the problems have
+ been resolved.
+
+2012-04-26 Michael Vogt <michael.vogt@ubuntu.com>
+
+ Check for "exit_state" on the install-finished signal from aptdaemon (LP: #982921) and remove launcher icon again on failure.. Fixes: https://bugs.launchpad.net/bugs/982921. Approved by Tim Penhey.
+
+2012-04-26 Michael Vogt <michael.vogt@ubuntu.com>
+
+ manual-tests/SoftwareCenter.txt: add manual test for the launcher integration cancel
+
+2012-04-17 Michael Vogt <michael.vogt@ubuntu.com>
+
+ remove USC launcher again from unity on download/install failure or cancel
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ We need to flag a bamf view that we control using an icon using the "unity-seen" qdata, or unity will duplicate it on bamfdaemon respawn. (LP: #928912). Fixes: https://bugs.launchpad.net/bugs/928912. Approved by Michal Hruby, Tim Penhey.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_launcher: removed the xclock test... We'll put it back soon.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging thomi's fixes
+
+2012-04-26 Thomi Richards <thomi.richards@canonical.com>
+
+ Added xclock.
+
+2012-04-26 Thomi Richards <thomi.richards@canonical.com>
+
+ Renamed test methods.
+
+2012-04-26 Thomi Richards <thomi.richards@canonical.com>
+
+ Removed tautology from the test.
+
+2012-04-26 Thomi Richards <thomi.richards@canonical.com>
+
+ CLeaned up test.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, use kill instead of pkill to close applications
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: export the application ID for introspection
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_launcher: added test to check the launcher status after bamfdaemon killing
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ LauncherController: set the "unity-seen" qdata to all the BamfApplications we have
+
+ This avoid that we create two icons for the same application instance.
+ Moving to the safer GUINT...
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ 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.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with trunk.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual test: updated.
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merge with trunk
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual-tests, Launcher: added a test for non top non-focused windows
+
+2012-04-21 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: raise all the urgent windows, if there are any
+
+2012-04-21 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: focus an application if no child window is actually on top of the stack.
+
+ 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 for non-active applications.
+
+2012-04-21 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: add method to get if a window is on top.
+
+ Top window is a window that is on top of the stack, excluding invisible, not mapped,
+ minimized, set "above" and unity windows.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual-test, Launcher: added manual test for the Chromium web applications. Fixes: . Approved by Tim Penhey.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual-test, Launcher: added manual test for the Chromium web applications
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: activate the icon using the quicklist item using an Idle.
+
+ This fixes the bug #986461 that caused the spread not to initiate clicking on the quicklist application name.. Fixes: https://bugs.launchpad.net/bugs/986461. Approved by Thomi Richards.
+
+2012-04-26 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: removed the g_debug("%s", G_STRFUNC); from AddProperties dummy implementation
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_quicklist: add a test to check that spread works when initiated by quicklist
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, keybindings: include spread keybindings
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, add WindowManager emulator
+
+2012-04-25 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ test_quicklist: added test to check if the application label works
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ unityshell: set PluginAdapter as introspectable child
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: make it introspectable, implementation in PluginAdapter.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merge with trunk
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: remove the _quicklist_activated_id related source on destruction
+
+2012-04-21 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: activate the icon using the quicklist item using an Idle.
+
+ This fixes the bug #986461 that caused the spread not to initiate clicking on the quicklist
+ application name.
+
+2012-04-25 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix scale inversion when processing non-rect tile textures. Fixes: https://bugs.launchpad.net/bugs/988338. Approved by Gord Allott.
+
+2012-04-25 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix scale inversion when processing non-rect tile textures
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Don't crop the bottom of results in card view when a category is not expanded.. Fixes: https://bugs.launchpad.net/bugs/975003. Approved by Marco Trevisan (Treviño).
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes LP bug #975003.
+
+2012-04-25 Michal Hruby <michal.mhr@gmail.com>
+
+ Destroy lens views before destroying lens models. Fixes: . Approved by Gord Allott, Sam Spilsbury.
+
+2012-04-24 Michal Hruby <michal.mhr@gmail.com>
+
+ Add a comment
+
+2012-04-24 Michal Hruby <michal.mhr@gmail.com>
+
+ Destroy lens views before destroying lens models
+
+2012-04-25 Michal Hruby <michal.mhr@gmail.com>
+
+ Make sure hud's spinner stops spinning after hud service returns reply. Fixes: https://bugs.launchpad.net/bugs/987781. Approved by Gord Allott, Marco Trevisan (Treviño).
+
+2012-04-24 Michal Hruby <michal.mhr@gmail.com>
+
+ Make sure hud's spinner stops spinning after hud service returns reply
+
+2012-04-25 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ Shorten the press/release time of the Ctrl+Space for the IBus AP tests.. Fixes: . Approved by Thomi Richards.
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Shortens the press/release time for Ctrl+Space as jenkins is a little slow
+
+2012-04-24 Andrea Azzarone <azzaronea@gmail.com>
+
+ Enable dnd for all launcher icons (and not just the ones matching the type).. Fixes: https://bugs.launchpad.net/bugs/880798. Approved by Marco Trevisan (Treviño).
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix typo.
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes.
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Add a manual test.
+
+2012-04-25 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #880798.
+
+2012-04-24 Andrea Azzarone <azzaronea@gmail.com>
+
+ Set a shortcut for the new apps on the launcher too.. Fixes: https://bugs.launchpad.net/bugs/778499. Approved by Marco Trevisan (Treviño).
+
+2012-04-24 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix.
+
+2012-04-24 Andrea Azzarone <azzaronea@gmail.com>
+
+ Merge trunk.
+
+2012-04-23 Andrea Azzarone <azzaronea@gmail.com>
+
+ Adds AP test.
+
+2012-04-23 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #778499.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ DeviceLauncherSection: updated to use glib::SignalManager and glib::Object
+
+ This allow to be more safe; it fixes also some crashes caused by the fact that DeviceLauncherIcon didn't own the GVolume* object. Now it uses glib::Object completely, so we can automagically ref/unref the volume when the icon is created/removed.. Fixes: https://bugs.launchpad.net/bugs/918548, https://bugs.launchpad.net/bugs/977762. Approved by Andrea Azzarone.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ DeviceLauncherSection: use glib::SignalManager
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ DeviceLauncherIcon: use a glib::Object to handle the volume.
+
+ So we can be safe about reference. This will automagically add
+ and remove a reference when needed.
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ UnityScreen: use smart_pointers correctly, destruct items in correct order. Fixes: https://bugs.launchpad.net/bugs/987932. Approved by Marco Trevisan (Treviño).
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Remove useless namespace
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed spacing issue
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Some fixes, also added some comments about the ordering (was causing the crashes)
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Changed WindowThread to use a unique ptr
+ * Also fixed a memory leak with the debugger
+ * Some cleaning up also
+ * Thanks Treviño for the information :)
+
+2012-04-24 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ UnityScreen: destroy the controllers before the window thread
+
+ Fixes crashes enabling/disabling plugins in CCSM. Fixes: https://bugs.launchpad.net/bugs/931201, https://bugs.launchpad.net/bugs/942286, https://bugs.launchpad.net/bugs/947844, https://bugs.launchpad.net/bugs/952378. Approved by Marco Trevisan (Treviño).
+
+2012-04-23 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixes some crashes with the ccsm and plugins
+ * There still seems to be a crash, but it looks to be in bamf
+
+2012-04-24 Michal Hruby <michal.mhr@gmail.com>
+
+ GLibDBusProxy: Remove 1 second timeout we used before connecting to dbus proxies. Fixes: . Approved by Marco Trevisan (Treviño).
+
+2012-04-24 Michal Hruby <michal.mhr@gmail.com>
+
+ Remove 1 second timeout we used before connecting to dbus proxies
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudLauncherIcon: close the HUD when activating the icon
+
+ As design requested in bug #963918. Fixes: https://bugs.launchpad.net/bugs/963918. Approved by Gord Allott.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudLauncherIcon: removed unneeded space.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_hud: add test to check if clicking over the HUD icon closes it.
+
+2012-04-24 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudLauncherIcon: close the HUD when activating the icon
+
+ As design requested in bug #963918
+
+2012-04-24 smspillaz <sam.spilsbury@canonical.com>
+
+ See Bug 880449 : Minimized windows were being considered for showdesktop and had their input shape removed twice.
+
+ 1) Never allow different entities to fight over the input shape of the window. Have one shared interface between them with RAII semantics
+ 2) Don't allow minimized windows to enter showdesktop mode. Fixes: . Approved by Gord Allott.
+
+2012-04-23 smspillaz <sam.spilsbury@canonical.com>
+
+ Fix style, use <memory>
+
+2012-04-18 smspillaz <sam.spilsbury@canonical.com>
+
+ Don't showdesktop minimized windows
+
+2012-04-18 smspillaz <sam.spilsbury@canonical.com>
+
+ Make the minimize handler use the same mechanism
+
+2012-04-18 smspillaz <sam.spilsbury@canonical.com>
+
+ Acquire input shape removal through RAII semantics
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Hud: update the icon size to match the launcher icon size when in auto-hide mode
+
+ Plus prevent a couple of crashes. Fixes: https://bugs.launchpad.net/bugs/921506, https://bugs.launchpad.net/bugs/983646. Approved by Tim Penhey.
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudView: Set the minimum icon height to match the content_layout
+
+ So the icon is vertically centered to the hud search (minimal) layout if needed.
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudIcon: use unsigned integer for padding.
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudView: remove space
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudIcon: Fix the icon position to be relative to size, add a minimum vertical padding
+
+ This makes the icon draw correctly when it's big, also it makes the view to increas its
+ vertical size slightly to use some padding if needed.
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudView: fix the geometry not to change when the icon size changes
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ HudController: add SetIcon function that removes some code duplication
+
+2012-04-23 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ IconTexture: be more safe when handling _pixbuf_cached
+
+ Set it to null when invalid and during initialization
+
+2012-04-22 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with trunk (window button fixes)
+
+2012-04-22 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with trunk
+
+2012-04-01 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Hud: update the icon size to match the launcher icon size.
+
+2012-04-01 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with icon fixes branch
+
+2012-04-23 Andrea Azzarone <azzaronea@gmail.com>
+
+ Use 2 columns in the card view in desktop mode when filters are opened.. Fixes: https://bugs.launchpad.net/bugs/977817. Approved by Mirco Müller, Marco Trevisan (Treviño), Andrea Cimitan.
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix bug #977817.
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Merge trunk.
+
+2012-04-21 Michael Rawson <michaelrawson76@gmail.com>
+
+ Fixes position of "show desktop" icon-LP:964073. Fixes: https://bugs.launchpad.net/bugs/964073. Approved by Marco Trevisan (Treviño).
+
+2012-04-18 Michael Rawson <michaelrawson76@gmail.com>
+
+ Fixed braces
+
+2012-04-17 Michael Rawson <michaelrawson76@gmail.com>
+
+ Fixed indentation
+
+2012-04-15 Michael Rawson <michaelrawson76@gmail.com>
+
+ Fixed ccsm problem
+
+2012-04-15 Michael Rawson <michaelrawson76@gmail.com>
+
+ Removed excess DesktopLauncherIcons()
+
+2012-04-14 Michael Rawson <michaelrawson76@gmail.com>
+
+ Re-added code
+
+2012-04-14 Michael Rawson <michaelrawson76@gmail.com>
+
+ Made fix more explicit-thanks Marco
+
+2012-04-13 Michael Rawson <michaelrawson76@gmail.com>
+
+ Moved show desktop icon to intended position
+
+2012-04-21 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowButtons: avoid to disable the Overlay close button.
+
+ This fixes a regression I probabily introduced (sorry).. Fixes: https://bugs.launchpad.net/bugs/986264. Approved by Andrea Azzarone.
+
+2012-04-20 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowButtons: remove extra space, and be more crash-safe
+
+2012-04-20 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowButtons: avoid to disable the Overlay close button.
+
+ This fixes a regression I probabily introduced (sorry).
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Don't activate "home.lens" during dash closing.. Fixes: https://bugs.launchpad.net/bugs/914785. Approved by Michal Hruby, Marco Trevisan (Treviño).
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Merge trunk.
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Don't activate the home lens during the dash closing.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ Update IBus tests to only set the IME once per test case class.. Fixes: . Approved by Brandon Schaefer, Thomi Richards.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ Use a single setUpClass method.
+
+2012-04-20 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * setUpClass, not tearDownClass
+
+2012-04-20 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Removed param, as it is no longer needed
+
+2012-04-20 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Now the ibus only reset the context when it changes test engines
+
+2012-04-19 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Changed to deactivate to an explicit call
+
+2012-04-20 Chase Douglas <chase.douglas@ubuntu.com>
+
+ Fix potential pointer lockup on initial drag gesture.. Fixes: https://bugs.launchpad.net/bugs/979418. Approved by Marco Trevisan (Treviño), Alex Launi.
+
+2012-04-12 Chase Douglas <chase.douglas@ubuntu.com>
+
+ Add test comment
+
+2012-04-11 Chase Douglas <chase.douglas@ubuntu.com>
+
+ Fix pointer locking up after three touch window drag
+
+ GestureEngine::EndDrag() checks if a drag gesture was performed before
+ ungrabbing the pointer. Unfortunately, it checks if the gesture ID is
+ non-zero, but a zero ID is valid. We don't need to check the gesture ID
+ at all since the drag window is maintained properly.
+
+2012-04-11 Chase Douglas <chase.douglas@ubuntu.com>
+
+ Add regression test for drag gesture pointer grabs not being removed
+
+2012-04-11 Chase Douglas <chase.douglas@ubuntu.com>
+
+ Add grab counting in compiz screen mock
+
+2012-04-19 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowButtons: disable the close button if the controlled window is not closable
+
+ Added support to WindowManager to get if a window is closable and maximizable, then used the IsWindowClosable method to enable or disable the close window button.. Fixes: https://bugs.launchpad.net/bugs/981196. Approved by Thomi Richards, Brandon Schaefer.
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual-tests: WindowButtons, added test case for disabled close button
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowButtons: disable the close button if the controlled window is not closable
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: add functions to get if a window is maximizable and closable
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ IBus autopilot tests now wait for input method context to be created before typing characters.. Fixes: . Approved by Brandon Schaefer.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ ibus tests now wait for ibus to be activated in the target widget. This removes the need for sleep statements alltogether.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ IBus tests now wait until the im_active property on the SearchBar is set to true.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ First pass at fixing the ibus tests.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged launcher tests fix, needed by this branch.
+
+2012-04-19 Andrea Azzarone <azzaronea@gmail.com>
+
+ Add a sanity check to avoid crashes.. Fixes: https://bugs.launchpad.net/bugs/982730. Approved by Marco Trevisan (Treviño).
+
+2012-04-20 Andrea Azzarone <azzaronea@gmail.com>
+
+ Adds a sanity check to avoid crashes.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixes autopilot launcher test.. Fixes: . Approved by Alex Launi.
+
+2012-04-20 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed launcher emulator and tests.
+
+2012-04-19 Michal Hruby <michal.mhr@gmail.com>
+
+ Finetune priorities when updating dash results, prevents flickering. Fixes: https://bugs.launchpad.net/bugs/961979. Approved by Gord Allott.
+
+2012-04-19 Michal Hruby <michal.mhr@gmail.com>
+
+ Finetune priorities when updating dash results, prevents flickering
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Shortcut hint tests now all pass.. Fixes: . Approved by Alex Launi.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed shortcut hint tests, cleaned up the shortcut hint controller, and made tests use the new Eventually() matcher, which eliminates the need for many sleep() statements.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed two failing tests.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Improve autopilot assertion messages inside the new wait_for method.. Fixes: . Approved by Alex Launi.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Autopilot wait_for assertions have a slightly better error message.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed failing panel autopilot tests.. Fixes: . Approved by Brandon Schaefer.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed two failing panel tests.
+
+2012-04-19 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ HudIcon now filters out windows on different workspaces and windows that are hidden.. Fixes: . Approved by Marco Trevisan (Treviño).
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * changed xid back to a 0, not a pointer
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed ap test
+ * Uses nullptr now
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * remove debug include
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed the ? icon appearing.
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added ap test
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Now the hud filters out windows on different workspaces for the HudIcon.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed a failing test in the command_lens test suite.. Fixes: . Approved by Brandon Schaefer.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed a failing command lens test. Somehow the assertion got inverted in the porting process.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Hud autopilot tests use the new Eventually autopilot matcher to reduce the number of test failures due to timing issues.. Fixes: . Approved by Thomi Richards.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged trunk, resolved conflicts.
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed indent error
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed the dash test that was removed
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * uses properties
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts* merged trunk, fixed conflicts
+
+2012-04-17 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed 2 ap fails
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView: fixed the quicklist key navigation, to make it consistent with Gtk menus navigation.
+
+ The prelight of the items is now completely controlled by QuicklistView and never by QuicklistMenuItem, the children can define now when they are slectable.. Fixes: https://bugs.launchpad.net/bugs/911561, https://bugs.launchpad.net/bugs/978926, https://bugs.launchpad.net/bugs/979096. Approved by Thomi Richards.
+
+2012-04-19 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_quicklist: cyclic keynav docstring fixes
+
+2012-04-19 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_quicklist: use the Eventually matcher to avoid false-negatives
+
+2012-04-19 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with trunk
+
+2012-04-19 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot: quicklist emulator, applying Thomi's fixes.
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_quicklist: docstrings updated.
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot: quicklist, use only properties
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ TestQuicklistMenuitems: added GetSelectable tests
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, quicklist: added other tests to check the cyclic key-navigation
+
+ Also the quicklist emulator now includes the selectable_items property
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, quicklist: use the new selectable item property instead of computing it
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistMenuItem: add GetSelectable virtual method
+
+ So each item can define when it's possible to select them, by default all
+ the items are selectable when visible and enabled, while the Separator
+ item can never be selected.
+
+2012-04-13 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, quicklist: add more last/first tests
+
+2012-04-12 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_quicklist: added first bunch of key navigation tests
+
+2012-04-12 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView, QuicklistMenuItem: export absolute geometries for introspection
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView: add support to Home/End Page up/down buttons to select items
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView: use the new SelectItem into RecvItemMouseDrag
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistMenuItem: don't change the focus on move, only on enter/leave
+
+ This to keep the consistency with GTK menus.
+ Also when leaving an unselected entry, we shouldn't unselect all.
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistMenuItem: make the introspection prelight name more explicit
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView: enhance the key navigation to follow the same menus behavior
+
+ 1) When no item is selected pressing the Down arrow key should
+ select the first item (from top)
+ 2) When no item is selected pressing the Up arrow key should
+ select the last item (from top)
+ 3) When the last item is selected, pressing the Down arrow key
+ should select the first item
+ 4) When the first item is selected, pressing the Up arrow key
+ should select the last item
+
+ All these cases assume that the mouse pointer is outside the
+ quicklist or over an item and not moving, in the case that the
+ mouse pointer is moved over an unselected item, the focus should
+ be moved to that item.
+
+2012-04-11 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ QuicklistView: manage the prelight item status, avoid double-selected items
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Update HUD tests to use the new Eventually() matcher.. Fixes: . Approved by Brandon Schaefer.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Removed unused import, fixed reference to property being treated as a function.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged trunk.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Cleaned up code after review.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Hud tests now use Eventually() matcher object instead of wait_for.
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ Fixed going from the Hud to the Dash forgetting window focus when exiting from the Dash.. Fixes: https://bugs.launchpad.net/bugs/984639. Approved by Andrea Azzarone, Thomi Richards.
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Use the correct assert
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * removed sleep
+
+2012-04-18 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixes Hud to Dash not restoring window focus
+ * Also fixes a Dash ap test failing
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Home lens tests use wait_for instead of explicit sleep statements.. Fixes: . Approved by Brandon Schaefer, Alex Launi, Thomi Richards.
+
+2012-04-19 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged trunk, reso;lved conflicts.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Home lens tests now use the Eventually() syntax.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ IBus tests use new Eventually matcher.. Fixes: . Approved by Thomi Richards.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ IBus tests now use the Eventually() matcher instead of wait_for.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Don't close the dash if the click is inside the desktop dash border.. Fixes: https://bugs.launchpad.net/bugs/839472. Approved by Tim Penhey.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Merge trunk.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix AP test.
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes typo. Adds AP test.
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Clicking on the desktop dash border should do nothing, *NOT* close the dash.
+
+2012-04-18 Michal Hruby <michal.mhr@gmail.com>
+
+ Make sure we don't try to remove sources that were already removed.. Fixes: . Approved by Marco Trevisan (Treviño), Andrea Azzarone.
+
+2012-04-18 Michal Hruby <michal.mhr@gmail.com>
+
+ Don't remove invalid sources
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #980924.. Fixes: https://bugs.launchpad.net/bugs/980924. Approved by Gord Allott, Marco Trevisan (Treviño).
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Remove unneeded code.
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes LP bug #980924.
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ UScreen: code updated to be more C++ friendly.
+
+ Also moved into the unity namespace.. Fixes: . Approved by Andrea Azzarone.
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ UScreen: ref the GdkScreen object we own.
+
+2012-04-18 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ UScreen: code updated to be more C++ friendly.
+
+ Also moved into the unity namespace.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix compilation of standalone launcher.. Fixes: https://bugs.launchpad.net/bugs/983989. Approved by Marco Trevisan (Treviño), Sam Spilsbury.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix standalone launcher.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Use std::shared_ptr::reset instead of = some::Ptr(new...) for UScreen::proxy_. Fixes: . Approved by Marco Trevisan (Treviño).
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Revert prev commit. Use std::shared_ptr::reset.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Makes UScreen::proxy_ a unity::glib::DBusProxy.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix bug #977922.. Fixes: https://bugs.launchpad.net/bugs/977922. Approved by Tim Penhey.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix bug #977922.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix the switcher so it displays the full title of apps in Chinese. Fixes: https://bugs.launchpad.net/bugs/830801. Approved by Tim Penhey.
+
+2012-04-18 Andrea Azzarone <azzaronea@gmail.com>
+
+ Merge trunk
+
+2012-04-16 Andrea Azzarone <azzaronea@gmail.com>
+
+ Add a manual test.
+
+2012-04-14 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix bug #830801.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Launcher tests use Eventually() matcher.. Fixes: . Approved by Thomi Richards.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Launcher emulator now uses wait_for to block until the action has been performed. Reduces the need for sleep() statements inside tests.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Launcher tests now use Eventually() matcher. Also removed some cruft from the launcher emulators.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged ibus-test-to-wait_for-feature into launcher-tests-pep8-whitespace-fixes.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged hud-tests-to-wait_for-feature into ibus-test-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged ibus-test-to-wait_for-feature into launcher-tests-pep8-whitespace-fixes.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged hud-tests-to-wait_for-feature into ibus-test-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged ibus-test-to-wait_for-feature into launcher-tests-pep8-whitespace-fixes.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged hud-tests-to-wait_for-feature into ibus-test-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixes PEP8 and whitespace issues.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ IBUs tests now make use of the wait_for attribute feature. Also refactored the ibus tests so many of them are only a few lines long, and reduced the amount of duplicated code.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged home-lens-tests-to-wait_for-feature into hud-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged dash-tests-to-wait_for-feature into home-lens-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixes several timing issues. Unity exports some properties in arrays, which makes it slightly tricky to use the wait_for feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ More hud test changes.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Hud test changes first pass merge.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Home lens uses wait_for instead of explicit sleeps.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Dash autopilot tests use the new autopilot wait_for feature.. Fixes: . Approved by Brandon Schaefer, Tim Penhey.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Missed one spot.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Dash tests changed to use Eventually matcher.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ fixed code after code review.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ More fixes.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged fix-command-lens-ap-tests-with-new-wait_for-featuer into dash-tests-to-wait_for-feature.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged in code to fix up the dash tests.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Command lens uses Eventually() autopilot matcher to eliminate the need for sleep() statements in autopilot tests.. Fixes: . Approved by Brandon Schaefer, Tim Penhey.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Updated to use the Eventually matcher.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged wait_for-to-use-testtools-exception into fix-command-lens-ap-tests-with-new-wait_for-featuer.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Removed unused import
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Command lens tests updated to use the new wait_for feature, and various other API fixes.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Cleaned up docstrings and whitespace in autopilot panel tests.. Fixes: . Approved by Tim Penhey.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Whitespace, PEP8 and PEP257 fixes for the panel tests.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Adds an Eventually() matcher that allows us to block a while until a unity attribute matches a testtools match object.. Fixes: . Approved by Tim Penhey, Thomi Richards.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Check match and wait_for attribute are callables.:
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed code from review.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed code from review.
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix some uninitialized variables.. Fixes: https://bugs.launchpad.net/bugs/983333. Approved by Tim Penhey.
+
+2012-04-16 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fix bug #983333
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #983268. Fixes: https://bugs.launchpad.net/bugs/983268. Approved by Thomi Richards.
+
+2012-04-17 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #983268.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Extend the autopilot wait_for feature to use testtools matcher instances as well as ordinary values. Also added an 'Eventually' matcher which makes tests more explicit.. Fixes: . Approved by Alex Launi.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Fixed typo
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Added 'Eventually' autopilot matcher.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Extend the autopilot wait_for feature to use testtools matcher instances as well as ordinary values.. Fixes: . Approved by Alex Launi.
+
+2012-04-18 Thomi Richards <thomi.richards@canonical.com>
+
+ Don't use hasattr,
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Cleaned up code after code review.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ wait_for now deals with attributes that have a '-' in them correctly.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ wait_for attribute now accept testtools matchers.
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Attribute wait_for feature now raises an AssertionError instead of a RuntimeError. THis will make unit tests FAIL instead of ERRORing when wa wait_for call fails.
+
+2012-04-17 Andrea Cimitan <andrea.cimitan@canonical.com>
+
+ Fix transparent panel in non-GLSL hardware, and use bool 'false' instead 'FALSE'. Fixes: https://bugs.launchpad.net/bugs/965323. Approved by Robert Carr, Michal Hruby.
+
+2012-04-17 Andrea Cimitan <andrea.cimitan@canonical.com>
+
+ Correct fix for 965323
+
+2012-04-17 Andrea Cimitan <andrea.cimitan@canonical.com>
+
+ Use false as boolean instead FALSE, whitespaces
+
+2012-04-17 Andrea Cimitan <andrea.cimitan@canonical.com>
+
+ Attempt to fix 965323
+
+2012-04-17 Thomi Richards <thomi.richards@canonical.com>
+
+ Added the autopilot wait_for attribute feature.. Fixes: . Approved by Marco Trevisan (Treviño), Brandon Schaefer.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Dash and hud emulators use new wait_for attribute feature.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged autopilot-attribute-feature into convert-to-use-wait_for.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Don't change dash in this pipeline.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged branch that fixes the multi key code.
+
+2012-04-12 Thomi Richards <thomi.richards@canonical.com>
+
+ Cleaned up gsettings calling code. Don't want to run command through a shell, and removed extra quotes.
+
+2012-04-11 Alex Launi <alex.launi@canonical.com>
+
+ Small fixes for compose key tests
+
+2012-04-11 Alex Launi <alex.launi@canonical.com>
+
+ Args should be a list not a tuple
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Merged trunk.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Dash tests now use new autopilot wait_for mechanism.
+
+2012-04-13 Thomi Richards <thomi.richards@canonical.com>
+
+ Fix unity logging reset.
+
+2012-04-11 Thomi Richards <thomi.richards@canonical.com>
+
+ Feature seems to work. Trying it out on the dash tests.
+
+2012-04-11 Thomi Richards <thomi.richards@canonical.com>
+
+ Removed old code, added special sauce.
+
+2012-04-17 Lars Uebernickel <lars.uebernickel@canonical.com>
+
+ Force menu reposition on popup in case its contents have changed.
+
+ Fixes bug 883317.. Fixes: https://bugs.launchpad.net/bugs/883317. Approved by Marco Trevisan (Treviño).
+
+2012-04-13 Lars Uebernickel <lars.uebernickel@canonical.com>
+
+ Force menu reposition on popup in case its contents have changed
+
+2012-04-17 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix a couple of wrong reference/memory management issues. Fixes: https://bugs.launchpad.net/bugs/979429. Approved by Marco Trevisan (Treviño).
+
+2012-04-16 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix possible signal disconnection on already dead object
+
+2012-04-16 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix incorrect string freeing in Hud
+
+2012-04-16 Michal Hruby <michal.mhr@gmail.com>
+
+ Fix wrong unref in DebugInterface
+
+2012-04-17 Gord Allott <gord.allott@canonical.com>
+
+ Small fix for the unity cmake, depend on unity core was missing from a test. Fixes: . Approved by Michal Hruby.
+
+2012-04-17 Gord Allott <gord.allott@canonical.com>
+
+ fixes small cmake depends issue
+
+2012-04-16 Andrea Azzarone <azzaronea@gmail.com>
+
+ The shortcut keys in workspace section of the shortcut overlay aren't translated.. Fixes: https://bugs.launchpad.net/bugs/980828. Approved by Didier Roche.
+
+2012-04-13 Andrea Azzarone <azzaronea@gmail.com>
+
+ Fixes bug #980828.
+
+2012-04-16 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Fix the behaviour of alt-tab and clicking on the launcher icon to just raise the most recently used window, not all for that app.
+
+
+ BamfLauncherIcon's activation related code has been updated to be more multimonitor aware (for free I've fixed also some bugs that caused the windows not to be put in spread mode in multi-monitor), and to support both the "Launcher only on Primary Monitor" and "Launcher on all monitors" options.
+
+ PluginAdapter's FocusWindowGroup method has been updated to optionally only unminimize / raise and activate only the top window. This code would have been more optimized using a reverse iterator to fetch the top_window, but not to change the whole logic and to allow to keep the previous behavior (that initially we wanted for "long alt+tab") without duplicating code, I've just hacked that.
+ Implemented also GetWindowMonitor to workaround the mismatch we had with the compiz' window->outputDevice() and the UScreen values that now we use in the whole unity.
+
+ Screencast of the fixed version: http://ubuntuone.com/7YaWciQnaZHfzr35asSz0N. Fixes: https://bugs.launchpad.net/bugs/861250, https://bugs.launchpad.net/bugs/959339, https://bugs.launchpad.net/bugs/981795. Approved by Thomi Richards, Tim Penhey.
+
+2012-04-16 Tim Penhey <tim.penhey@canonical.com>
+
+ Test the alt-tab appears on the monitor that has window focus.
+
+2012-04-16 Tim Penhey <tim.penhey@canonical.com>
+
+ Add window stack assertions to the switcher tests.
+
+2012-04-16 Tim Penhey <tim.penhey@canonical.com>
+
+ Assert that the visible window stack is what we expect.
+
+2012-04-16 Tim Penhey <tim.penhey@canonical.com>
+
+ More AP test tweaks.
+
+2012-04-16 Tim Penhey <tim.penhey@canonical.com>
+
+ Tweaks to the test.
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ PluginAdapter: avoid to raise and unminimize top_window if already done
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Launcher: be more clear in comment (yeah?)
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ UScreen: use GetMonitorAtPosition in GetMonitorWithMouse
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager, BamfLauncherIcon: some code cleanup
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_launcher: updated click test to check minimized windows too
+
+ Removed debug data
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot, test_switcher: updated against new updates
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ unityshell: show the Alt+Tab window in the monitor where is the active window
+
+ As per design.
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: add method to get the active window.
+
+2012-04-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ PluginAdapter: removing debugging bits
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Merging with branch changes
+
+2012-04-14 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * removed something that got added somehow
+
+2012-04-14 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added an AP test for the new design changes.
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ SwitcherController: Removing the code for the Quick Alt+Tab, it should behave always at the same way
+
+ 19:11:04 <JohnLea> so to summarize the above, when a app icon is selected
+ in Alt-Tab, the most recently focused window (on any monitor, but only in
+ the current workspace) of that application which is not minimised
+ should be focused
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ autopilot: fixed the AP test
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: Also invisible windows shouldn't be counted as available in monitor
+
+ Now the spread works as expected, clicking on each monitor's panel! ;)
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: don't consider an unmapped window as one in monitor
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: focus a window if the application is not active on the current monitor
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Launcher: if the current launcher is used for all the monitors, don't filter windows per monitor
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ SwitcherController: include the switcher monitor when activating a group
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ WindowManager: add GetWindowMonitor method, and use UScreen to fetch it
+
+ This now used in PluginAdapter not to have inconsistences.
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ UScreen: allow to get the monitor for a given point
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ unityshell: switcher, use UScreen to get the monitor value.
+
+ Not using this can cause inconsistences, due to the fact that compiz
+ numbers the devices in a different way.
+
+2012-04-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ PluginAdapter::FocusWindowGroup: add a parameter to define if focusing the on-top window only
+
+ This allow to be more monitor/VP safe
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * remove extra line
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed the No new line error diff was reporting
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * merged trunk
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * removed random dash '-'
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Add autopilot test for both bugs!
+
+2012-04-12 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added more autopilot test for quick alt+tab
+
+2012-04-11 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * merged trunk
+
+2012-04-09 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * merged trunk
+
+2012-04-06 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added 2 autopilot test showing quick tab is true when pressed fast enough
+
+2012-04-06 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * fixed manual test I messed up
+
+2012-04-06 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added a timer for quick tab
+
+2012-04-06 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Merged trunk
+
+2012-04-05 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Added another manual test
+ * Fixes
+
+2012-04-04 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Fixed tabbing issues
+
+2012-04-04 Brandon Schaefer <brandontschaefer@gmail.com>
+
+ * Merged with trunk, fixed conficts
+
+2011-12-15 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: don't include dialog windows on Alt+Tab.
+
+2011-12-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ manual-tests: Added test for QuickAltTab
+
+2011-12-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ PluginAdapter: Add support for the FocusVisibility::OnlyVisibleOnTop on FocusWindowGroup
+
+ When a group is asked to focus with OnlyVisibleOnTop, we look for the
+ first non-minimized window on top of the stack and we raise and activate it.
+
+ Code indentation fixes included.
+
+2011-12-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ BamfLauncherIcon: when we receive a "quick" activate, use the OnlyVisibleOnTop focus visbility
+
+ Defined a new FocusVisibility called OnlyVisibleOnTop that is meant
+ to only focus the first application window on top of the stack.
+ That is used when we receive a Switcher activate with a button != 0.
+
+2011-12-14 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ SwitcherController: use the button value of ActionArg to indicate the switch type
+
+ Instead of defining another type of ActionArg, I've used the button value
+ of ActionArg to define if we're currently performing a quick-alt+tab or
+ a standard switch.
+ Basically:
+
+2012-04-16 Alexandros Frantzis <alexandros.frantzis@linaro.org>
+
+ Fix compilation with OpenGL ES 2.0.. Fixes: . Approved by Sam Spilsbury.
+
+2012-04-06 Alexandros Frantzis <alexandros.frantzis@linaro.org>
+
+ Fix compilation with OpenGL ES 2.0.
+
+2012-04-12 Gord Allott <gord.allott@canonical.com >
+
+ fixes an uninitalised variable in the dashview code
+
+2012-04-12 Gord Allott <gord.allott@canonical.com>
+
+ fixed uninitalised value
+
+2012-04-12 Didier Roche <didier.roche@canonical.com>
+
+ Release\ 5.10.0
+
2012-04-12 Michal Hruby <michal.mhr@gmail.com>
Make sure the lenses search for things we want on startup. Fixes: https://bugs.launchpad.net/bugs/979799. Approved by Gord Allott.
diff --git a/UnityCore/GLibSignal.cpp b/UnityCore/GLibSignal.cpp
index 3a1066816..965982b39 100644
--- a/UnityCore/GLibSignal.cpp
+++ b/UnityCore/GLibSignal.cpp
@@ -36,7 +36,7 @@ SignalBase::~SignalBase()
void SignalBase::Disconnect()
{
- if (G_IS_OBJECT(object_) && connection_id_)
+ if (connection_id_ && G_IS_OBJECT(object_))
g_signal_handler_disconnect(object_, connection_id_);
object_ = 0;
diff --git a/UnityCore/Hud.cpp b/UnityCore/Hud.cpp
index ad501a551..61035d682 100644
--- a/UnityCore/Hud.cpp
+++ b/UnityCore/Hud.cpp
@@ -159,11 +159,11 @@ void HudImpl::BuildQueries(GVariant* query_array)
{
GVariantIter iter;
g_variant_iter_init(&iter, query_array);
- glib::String formatted_text;
- glib::String icon;
- glib::String item_icon;
- glib::String completion_text;
- glib::String shortcut;
+ gchar* formatted_text;
+ gchar* icon;
+ gchar* item_icon;
+ gchar* completion_text;
+ gchar* shortcut;
GVariant* key = NULL;
while (g_variant_iter_loop(&iter, "(sssssv)",
diff --git a/debian/changelog b/debian/changelog
index ee5921b8f..dd3960dde 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+unity (5.12-0ubuntu1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Didier Roche <didrocks@ubuntu.com> Fri, 27 Apr 2012 08:33:25 +0200
+
unity (5.10.0-0ubuntu6) precise-proposed; urgency=low
* Cherry-picked upstream:
diff --git a/manual-tests/Launcher.txt b/manual-tests/Launcher.txt
index 751ddbe96..9b3c1caed 100644
--- a/manual-tests/Launcher.txt
+++ b/manual-tests/Launcher.txt
@@ -465,3 +465,78 @@ Expected Result:
The numbers [1-9] should be displayed overlaid on the icons.
"Keyboard Shortcut" menu should appear as well.
+
+Drag file to launcher icons
+---------------------------
+Setup:
+#. Add the Firefox icon to the launcher.
+#. Create an html file on the desktop.
+#. Create an empty folder on the desktop.
+
+Actions:
+#. Drag the html file.
+#. Drop it into the Firefox icon.
+
+Expected Result:
+The Firefox icon should be highlighted during the drag&drop.
+Firefox should open the html file.
+
+Actions:
+#. Drag the new folder.
+#. Drop it into the Firefox icon.
+
+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
+
+Setup:
+ * Open Chromium and go to a website, say ubuntu.com
+ * Go to the menu "File" -> "Create Application Shortcuts..."
+ * Select the checkbox "Applications Menu" (you can deselect the "Desktop" one)
+ * A new window is opened, and the launcher will continue matching it like a
+ chromium application.
+ * Close the chromium window.
+
+Actions:
+ * Open the dash and search for "chrom"
+ * An application called "Home | Ubuntu" should be shown
+ * Launch it
+
+Expected Results:
+ * The launcher will show an icon for the "Home | Ubuntu" application
+
+Actions:
+ * Open a standard chromium window
+
+Expected Results:
+ * The new chromium window will be associated to the standard chromium
+ 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/manual-tests/SoftwareCenter.txt b/manual-tests/SoftwareCenter.txt
new file mode 100644
index 000000000..7249c8ab3
--- /dev/null
+++ b/manual-tests/SoftwareCenter.txt
@@ -0,0 +1,16 @@
+The SoftwareCenter Launcher Integration cancel
+----------------------------------------------
+
+Setup:
+#. Open software-center
+
+Actions:
+#. Click on install on a big application like wesnoth
+#. Verify that the icon "flies" into the launcher
+#. Wait until the "In Progress" appears in the toplevel toolbar of s-c
+#. Click on the "In Progress" button in the toolbar
+#. Click on the "cancel" button of the install of the application
+
+Expected Result:
+ The icon is removed from the launcher again after the download was
+ canceled.
diff --git a/manual-tests/Switcher.txt b/manual-tests/Switcher.txt
index 4025d1a15..2c4704a5d 100644
--- a/manual-tests/Switcher.txt
+++ b/manual-tests/Switcher.txt
@@ -38,3 +38,21 @@ Outcome
of the panel should change inline with changes in alt-tab focus.
Also the menus shouldn't ever show. Even if the mouse has been left over
the panel when starting the Alt+Tab.
+
+Full app title in Chinese
+-------------------------
+This test ensures that the App Switcher (Alt+Tab) displays the full title
+of apps in Chinese.
+
+Setup:
+#. Install gnome-tweak-tool and run it.
+#. Make sure you have the default font scaling factor (1.0).
+
+Action:
+#. Run:
+ python -c 'from gi.repository import Gtk;win=Gtk.Window(title="显示桌面");win.connect("destroy", Gtk.main_quit);win.show_all();Gtk.main();'
+#. Press Alt+Tab.
+#. Continue to press Tab to select the newly created window.
+
+Outcome
+ The title of the newly created window should be "显示桌面" and *not* "显示桌...".
diff --git a/manual-tests/WindowButtons.txt b/manual-tests/WindowButtons.txt
new file mode 100644
index 000000000..b21c91296
--- /dev/null
+++ b/manual-tests/WindowButtons.txt
@@ -0,0 +1,11 @@
+Window Close Button should be Disabled if not available
+-------------------------------------------------------
+
+Actions:
+ * Start the Update Manager
+ * Press on the "Check" button
+ * On the "Updating Chache" dialog, press the "Details" toggle
+ * Press on the maximize window button that will show on the dialog decoration
+
+Expected Result:
+ * The close window button should be shown as disabled (grayed)
diff --git a/plugins/unityshell/src/AbstractLauncherIcon.h b/plugins/unityshell/src/AbstractLauncherIcon.h
index 372bba185..1cbcab329 100644
--- a/plugins/unityshell/src/AbstractLauncherIcon.h
+++ b/plugins/unityshell/src/AbstractLauncherIcon.h
@@ -128,7 +128,7 @@ public:
virtual void SetSortPriority(int priority) = 0;
- virtual bool OpenQuicklist(bool default_to_first_item = false, int monitor = -1) = 0;
+ virtual bool OpenQuicklist(bool select_first_item = false, int monitor = -1) = 0;
virtual void SetCenter(nux::Point3 center, int monitor, nux::Geometry parent_geo) = 0;
@@ -180,9 +180,11 @@ public:
virtual std::list<DbusmenuMenuitem*> Menus() = 0;
- virtual nux::DndAction QueryAcceptDrop(unity::DndData& dnd_data) = 0;
+ virtual nux::DndAction QueryAcceptDrop(DndData const& dnd_data) = 0;
- virtual void AcceptDrop(unity::DndData& dnd_data) = 0;
+ virtual bool ShouldHighlightOnDrag(DndData const& dnd_data) = 0;
+
+ virtual void AcceptDrop(DndData const& dnd_data) = 0;
virtual void SendDndEnter() = 0;
@@ -215,6 +217,7 @@ public:
sigc::signal<void, AbstractLauncherIcon::Ptr> needs_redraw;
sigc::signal<void, AbstractLauncherIcon::Ptr> remove;
+ sigc::signal<void> visibility_changed;
sigc::connection needs_redraw_connection;
sigc::connection on_icon_added_connection;
diff --git a/plugins/unityshell/src/BFBLauncherIcon.cpp b/plugins/unityshell/src/BFBLauncherIcon.cpp
index 057e4e020..1bf964f34 100644
--- a/plugins/unityshell/src/BFBLauncherIcon.cpp
+++ b/plugins/unityshell/src/BFBLauncherIcon.cpp
@@ -91,7 +91,7 @@ nux::Color BFBLauncherIcon::GlowColor()
void BFBLauncherIcon::ActivateLauncherIcon(ActionArg arg)
{
- ubus_manager_.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", 0, ""));
+ ubus_manager_.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, ""));
// dont chain down to avoid random dash close events
}
diff --git a/plugins/unityshell/src/BamfLauncherIcon.cpp b/plugins/unityshell/src/BamfLauncherIcon.cpp
index 5a413810c..32cfe7baa 100644
--- a/plugins/unityshell/src/BamfLauncherIcon.cpp
+++ b/plugins/unityshell/src/BamfLauncherIcon.cpp
@@ -18,6 +18,8 @@
* Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
*/
+#include <boost/algorithm/string.hpp>
+
#include <Nux/Nux.h>
#include <Nux/BaseWindow.h>
@@ -142,11 +144,14 @@ BamfLauncherIcon::~BamfLauncherIcon()
{
g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()),
g_quark_from_static_string("unity-seen"),
- GINT_TO_POINTER(0));
+ GUINT_TO_POINTER(0));
if (_fill_supported_types_id != 0)
g_source_remove(_fill_supported_types_id);
+ if (_quicklist_activated_id != 0)
+ g_source_remove(_quicklist_activated_id);
+
if (_window_moved_id != 0)
g_source_remove(_window_moved_id);
@@ -203,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:
@@ -486,6 +500,7 @@ void BamfLauncherIcon::AddProperties(GVariantBuilder* builder)
variant::BuilderWrapper(builder)
.add("desktop_file", DesktopFile())
.add("desktop_id", GetDesktopID())
+ .add("application_id", GPOINTER_TO_UINT(_bamf_app.RawPtr()))
.add("xids", g_variant_builder_end(&xids_builder))
.add("sticky", IsSticky());
}
@@ -630,7 +645,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)
@@ -961,7 +977,13 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus()
_gsignals.Add(new glib::Signal<void, DbusmenuMenuitem*, int>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
[&] (DbusmenuMenuitem*, int) {
- ActivateLauncherIcon(ActionArg(ActionArg::OTHER, 0));
+ _quicklist_activated_id =
+ g_idle_add([] (gpointer data) -> gboolean {
+ auto self = static_cast<BamfLauncherIcon*>(data);
+ self->ActivateLauncherIcon(ActionArg());
+ self->_quicklist_activated_id = 0;
+ return FALSE;
+ }, this);
}));
_menu_items_extra["AppName"] = glib::Object<DbusmenuMenuitem>(item);
@@ -1069,31 +1091,12 @@ std::string BamfLauncherIcon::GetRemoteUri()
return _remote_uri;
}
-std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& uris)
+std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(DndData const& uris)
{
std::set<std::string> result;
- gboolean is_home_launcher = g_str_has_suffix(DesktopFile().c_str(), "nautilus-home.desktop");
- if (is_home_launcher)
- {
- for (auto k : uris.Uris())
- result.insert(k);
- return result;
- }
-
- for (auto i : uris.Types())
- {
- for (auto j : GetSupportedTypes())
- {
- if (g_content_type_is_a(i.c_str(), j.c_str()))
- {
- for (auto k : uris.UrisByType(i))
- result.insert(k);
-
- break;
- }
- }
- }
+ for (auto uri : uris.Uris())
+ result.insert(uri);
return result;
}
@@ -1125,12 +1128,37 @@ void BamfLauncherIcon::OnDndLeave()
_dnd_hover_timer = 0;
}
-nux::DndAction BamfLauncherIcon::OnQueryAcceptDrop(unity::DndData& dnd_data)
+bool BamfLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
+{
+ bool is_home_launcher = boost::algorithm::ends_with(DesktopFile(), "nautilus-home.desktop") ||
+ boost::algorithm::ends_with(DesktopFile(), "nautilus.desktop");
+
+ if (is_home_launcher)
+ {
+ return true;
+ }
+
+ for (auto type : dnd_data.Types())
+ {
+ for (auto supported_type : GetSupportedTypes())
+ {
+ if (g_content_type_is_a(type.c_str(), supported_type.c_str()))
+ {
+ if (!dnd_data.UrisByType(type).empty())
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+nux::DndAction BamfLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)
{
return ValidateUrisForLaunch(dnd_data).empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
}
-void BamfLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data)
+void BamfLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
{
OpenInstanceWithUris(ValidateUrisForLaunch(dnd_data));
}
diff --git a/plugins/unityshell/src/BamfLauncherIcon.h b/plugins/unityshell/src/BamfLauncherIcon.h
index 8baaf0d3e..279e8a8a2 100644
--- a/plugins/unityshell/src/BamfLauncherIcon.h
+++ b/plugins/unityshell/src/BamfLauncherIcon.h
@@ -69,17 +69,18 @@ protected:
void UpdateIconGeometries(std::vector<nux::Point3> center);
void OnCenterStabilized(std::vector<nux::Point3> center);
void AddProperties(GVariantBuilder* builder);
- void OnAcceptDrop(unity::DndData& dnd_data);
+ void OnAcceptDrop(DndData const& dnd_data);
void OnDndEnter();
void OnDndHovered();
void OnDndLeave();
void OpenInstanceLauncherIcon(ActionArg arg);
void ToggleSticky();
- nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data);
+ bool OnShouldHighlightOnDrag(DndData const& dnd_data);
+ nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data);
std::list<DbusmenuMenuitem*> GetMenus();
- std::set<std::string> ValidateUrisForLaunch(unity::DndData& dnd_data);
+ std::set<std::string> ValidateUrisForLaunch(DndData const& dnd_data);
std::string GetRemoteUri();
std::string BamfName() const;
@@ -125,6 +126,7 @@ private:
bool _supported_types_filled;
guint _fill_supported_types_id;
guint _window_moved_id;
+ guint _quicklist_activated_id;
std::string _remote_uri;
std::string _desktop_file;
diff --git a/plugins/unityshell/src/DashController.cpp b/plugins/unityshell/src/DashController.cpp
index e139e6029..0791a2f19 100644
--- a/plugins/unityshell/src/DashController.cpp
+++ b/plugins/unityshell/src/DashController.cpp
@@ -58,7 +58,7 @@ Controller::Controller()
Settings::Instance().changed.connect([&]()
{
- if (window_)
+ if (window_ && view_)
{
window_->PushToFront();
window_->SetInputFocus();
@@ -72,8 +72,12 @@ Controller::~Controller()
if (window_)
window_->UnReference();
window_ = 0;
- g_source_remove(timeline_id_);
- g_source_remove(ensure_id_);
+
+ if (timeline_id_)
+ g_source_remove(timeline_id_);
+
+ if (ensure_id_)
+ g_source_remove(ensure_id_);
}
void Controller::SetupWindow()
@@ -264,8 +268,6 @@ void Controller::ShowDash()
return;
}
- adaptor->saveInputFocus ();
-
view_->AboutToShow();
window_->ShowWindow(true);
@@ -371,7 +373,7 @@ gboolean Controller::CheckShortcutActivation(const char* key_string)
std::string lens_id = view_->GetIdForShortcutActivation(std::string(key_string));
if (lens_id != "")
{
- GVariant* args = g_variant_new("(sus)", lens_id.c_str(), 0, "");
+ GVariant* args = g_variant_new("(sus)", lens_id.c_str(), dash::GOTO_DASH_URI, "");
OnActivateRequest(args);
g_variant_unref(args);
return true;
diff --git a/plugins/unityshell/src/DashStyle.cpp b/plugins/unityshell/src/DashStyle.cpp
index c95342d50..280733fe7 100644
--- a/plugins/unityshell/src/DashStyle.cpp
+++ b/plugins/unityshell/src/DashStyle.cpp
@@ -2185,6 +2185,16 @@ nux::BaseTexture* Style::GetDashShine()
return pimpl->dash_shine_.texture();
}
+int Style::GetDashBottomTileHeight() const
+{
+ return 30;
+}
+
+int Style::GetDashRightTileWidth() const
+{
+ return 30;
+}
+
int Style::GetVSeparatorSize() const
{
return 1;
diff --git a/plugins/unityshell/src/DashStyle.h b/plugins/unityshell/src/DashStyle.h
index fc2201fff..e1c23f796 100644
--- a/plugins/unityshell/src/DashStyle.h
+++ b/plugins/unityshell/src/DashStyle.h
@@ -180,6 +180,9 @@ public:
nux::BaseTexture* GetDashTopCornerMask();
nux::BaseTexture* GetDashTopTile();
+ int GetDashBottomTileHeight() const;
+ int GetDashRightTileWidth() const;
+
nux::BaseTexture* GetDashShine();
nux::BaseTexture* GetSearchMagnifyIcon();
diff --git a/plugins/unityshell/src/DashView.cpp b/plugins/unityshell/src/DashView.cpp
index 1f1fb497a..a458a48c3 100644
--- a/plugins/unityshell/src/DashView.cpp
+++ b/plugins/unityshell/src/DashView.cpp
@@ -110,6 +110,10 @@ DashView::~DashView()
g_source_remove (searching_timeout_id_);
if (hide_message_delay_id_)
g_source_remove(hide_message_delay_id_);
+
+ // Do this explicitely, otherwise dee will complain about invalid access
+ // to the lens models
+ RemoveLayout ();
}
void DashView::SetMonitorOffset(int x, int y)
@@ -315,7 +319,16 @@ void DashView::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
void DashView::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
{
- if (!content_geo_.IsPointInside(x, y))
+ dash::Style& style = dash::Style::Instance();
+ nux::Geometry geo(content_geo_);
+
+ if (Settings::Instance().GetFormFactor() == FormFactor::DESKTOP)
+ {
+ geo.width += style.GetDashRightTileWidth();
+ geo.height += style.GetDashBottomTileHeight();
+ }
+
+ if (!geo.IsPointInside(x, y))
{
ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
}
@@ -329,12 +342,21 @@ void DashView::OnActivateRequest(GVariant* args)
g_variant_get(args, "(sus)", &uri, &handled_type, &search_string);
- std::string id = AnalyseLensURI(uri.Str());
+ std::string id(AnalyseLensURI(uri.Str()));
- lens_bar_->Activate(id);
-
- if ((id == "home.lens" && handled_type != GOTO_DASH_URI ) || !visible_)
+ if (!visible_)
+ {
+ lens_bar_->Activate(id);
ubus_manager_.SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);
+ }
+ else if (/* visible_ && */ handled_type == NOT_HANDLED)
+ {
+ ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
+ }
+ else if (/* visible_ && */ handled_type == GOTO_DASH_URI)
+ {
+ lens_bar_->Activate(id);
+ }
}
std::string DashView::AnalyseLensURI(std::string const& uri)
@@ -737,6 +759,7 @@ std::string DashView::GetName() const
void DashView::AddProperties(GVariantBuilder* builder)
{
+ dash::Style& style = dash::Style::Instance();
int num_rows = 1; // The search bar
if (active_lens_view_)
@@ -750,8 +773,11 @@ void DashView::AddProperties(GVariantBuilder* builder)
form_factor = "desktop";
unity::variant::BuilderWrapper wrapper(builder);
+ wrapper.add(nux::Geometry(GetAbsoluteX(), GetAbsoluteY(), content_geo_.width, content_geo_.height));
wrapper.add("num_rows", num_rows);
wrapper.add("form_factor", form_factor);
+ wrapper.add("right-border-width", style.GetDashRightTileWidth());
+ wrapper.add("bottom-border-height", style.GetDashBottomTileHeight());
}
nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction)
diff --git a/plugins/unityshell/src/DebugDBusInterface.cpp b/plugins/unityshell/src/DebugDBusInterface.cpp
index 041f8fe03..9d7a24971 100644
--- a/plugins/unityshell/src/DebugDBusInterface.cpp
+++ b/plugins/unityshell/src/DebugDBusInterface.cpp
@@ -94,13 +94,10 @@ GDBusInterfaceVTable DebugDBusInterface::interface_vtable =
NULL
};
-static CompScreen* _screen;
static Introspectable* _parent_introspectable;
-DebugDBusInterface::DebugDBusInterface(Introspectable* parent,
- CompScreen* screen)
+DebugDBusInterface::DebugDBusInterface(Introspectable* parent)
{
- _screen = screen;
_parent_introspectable = parent;
_owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
unity::DBUS_BUS_NAME.c_str(),
@@ -177,8 +174,9 @@ DebugDBusInterface::HandleDBusMethodCall(GDBusConnection* connection,
g_variant_get(parameters, "(&s)", &input);
ret = GetState(input);
+ // GetState returns a floating variant and
+ // g_dbus_method_invocation_return_value ref sinks it
g_dbus_method_invocation_return_value(invocation, ret);
- g_variant_unref(ret);
}
else if (g_strcmp0(method_name, "StartLogToFile") == 0)
{
diff --git a/plugins/unityshell/src/DebugDBusInterface.h b/plugins/unityshell/src/DebugDBusInterface.h
index e82422c2b..3c11a5a0b 100644
--- a/plugins/unityshell/src/DebugDBusInterface.h
+++ b/plugins/unityshell/src/DebugDBusInterface.h
@@ -36,7 +36,7 @@ std::list<Introspectable*> GetIntrospectableNodesFromQuery(std::string const& qu
class DebugDBusInterface
{
public:
- DebugDBusInterface(Introspectable* introspectable, CompScreen* uscreen);
+ DebugDBusInterface(Introspectable* introspectable);
~DebugDBusInterface();
private:
diff --git a/plugins/unityshell/src/DesktopLauncherIcon.cpp b/plugins/unityshell/src/DesktopLauncherIcon.cpp
index 729d5d5ff..cc642b632 100644
--- a/plugins/unityshell/src/DesktopLauncherIcon.cpp
+++ b/plugins/unityshell/src/DesktopLauncherIcon.cpp
@@ -35,8 +35,7 @@ DesktopLauncherIcon::DesktopLauncherIcon()
icon_name = "desktop";
SetQuirk(QUIRK_VISIBLE, true);
SetQuirk(QUIRK_RUNNING, false);
- SetIconType(TYPE_BEGIN);
- SetShowInSwitcher(false);
+ SetIconType(TYPE_DESKTOP);
}
DesktopLauncherIcon::~DesktopLauncherIcon()
diff --git a/plugins/unityshell/src/DeviceLauncherIcon.cpp b/plugins/unityshell/src/DeviceLauncherIcon.cpp
index ea91a565c..034e5c5e6 100644
--- a/plugins/unityshell/src/DeviceLauncherIcon.cpp
+++ b/plugins/unityshell/src/DeviceLauncherIcon.cpp
@@ -43,7 +43,7 @@ GduDevice* get_device_for_device_file (const gchar *device_file);
}
-DeviceLauncherIcon::DeviceLauncherIcon(GVolume* volume)
+DeviceLauncherIcon::DeviceLauncherIcon(glib::Object<GVolume> const& volume)
: SimpleLauncherIcon()
, volume_(volume)
, device_file_(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE))
diff --git a/plugins/unityshell/src/DeviceLauncherIcon.h b/plugins/unityshell/src/DeviceLauncherIcon.h
index 0665e6c5d..d6fcb51d7 100644
--- a/plugins/unityshell/src/DeviceLauncherIcon.h
+++ b/plugins/unityshell/src/DeviceLauncherIcon.h
@@ -36,7 +36,7 @@ class DeviceLauncherIcon : public SimpleLauncherIcon
{
public:
- DeviceLauncherIcon(GVolume* volume);
+ DeviceLauncherIcon(glib::Object<GVolume> const& volume);
void UpdateVisibility(int visibility = -1);
void OnRemoved();
@@ -67,7 +67,7 @@ private:
void ShowNotification(std::string const&, unsigned, GdkPixbuf*, std::string const&);
private:
- GVolume* volume_;
+ glib::Object<GVolume> volume_;
glib::String device_file_;
std::string name_;
glib::Object<GduDevice> gdu_device_;
diff --git a/plugins/unityshell/src/DeviceLauncherSection.cpp b/plugins/unityshell/src/DeviceLauncherSection.cpp
index 2d9fed667..bbf1a7283 100644
--- a/plugins/unityshell/src/DeviceLauncherSection.cpp
+++ b/plugins/unityshell/src/DeviceLauncherSection.cpp
@@ -25,128 +25,101 @@ namespace launcher
DeviceLauncherSection::DeviceLauncherSection()
: monitor_(g_volume_monitor_get())
-{
- on_volume_added_handler_id_ = g_signal_connect(monitor_,
- "volume-added",
- G_CALLBACK(&DeviceLauncherSection::OnVolumeAdded),
- this);
-
- on_volume_removed_handler_id_ = g_signal_connect(monitor_,
- "volume-removed",
- G_CALLBACK(&DeviceLauncherSection::OnVolumeRemoved),
- this);
-
- on_mount_added_handler_id_ = g_signal_connect(monitor_,
- "mount-added",
- G_CALLBACK(&DeviceLauncherSection::OnMountAdded),
- this);
-
- on_mount_pre_unmount_handler_id_ = g_signal_connect(monitor_,
- "mount-pre-unmount",
- G_CALLBACK(&DeviceLauncherSection::OnMountPreUnmount),
- this);
-
- on_device_populate_entry_id_ = g_idle_add((GSourceFunc)&DeviceLauncherSection::PopulateEntries, this);
+{
+ typedef glib::Signal<void, GVolumeMonitor*, GVolume*> VolumeSignal;
+ sig_manager_.Add(new VolumeSignal(monitor_, "volume-added", sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeAdded)));
+ sig_manager_.Add(new VolumeSignal(monitor_, "volume-removed", sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeRemoved)));
+
+ typedef glib::Signal<void, GVolumeMonitor*, GMount*> MountSignal;
+ sig_manager_.Add(new MountSignal(monitor_, "mount-added", sigc::mem_fun(this, &DeviceLauncherSection::OnMountAdded)));
+ sig_manager_.Add(new MountSignal(monitor_, "mount-pre-unmount", sigc::mem_fun(this, &DeviceLauncherSection::OnMountPreUnmount)));
+
+ on_device_populate_entry_id_ = g_idle_add([] (gpointer data) {
+ auto self = static_cast<DeviceLauncherSection*>(data);
+ self->PopulateEntries();
+ self->on_device_populate_entry_id_ = 0;
+ return FALSE;
+ }, this);
}
DeviceLauncherSection::~DeviceLauncherSection()
{
- if (on_volume_added_handler_id_)
- g_signal_handler_disconnect((gpointer) monitor_,
- on_volume_added_handler_id_);
-
- if (on_volume_removed_handler_id_)
- g_signal_handler_disconnect((gpointer) monitor_,
- on_volume_removed_handler_id_);
-
- if (on_mount_added_handler_id_)
- g_signal_handler_disconnect((gpointer) monitor_,
- on_mount_added_handler_id_);
-
- if (on_mount_pre_unmount_handler_id_)
- g_signal_handler_disconnect((gpointer) monitor_,
- on_mount_pre_unmount_handler_id_);
-
if (on_device_populate_entry_id_)
g_source_remove(on_device_populate_entry_id_);
}
-bool DeviceLauncherSection::PopulateEntries(DeviceLauncherSection* self)
+void DeviceLauncherSection::PopulateEntries()
{
- GList* volumes = g_volume_monitor_get_volumes(self->monitor_);
+ GList* volumes = g_volume_monitor_get_volumes(monitor_);
for (GList* v = volumes; v; v = v->next)
{
- glib::Object<GVolume> volume((GVolume* )v->data);
+ if (!G_IS_VOLUME(v->data))
+ continue;
+
+ // This will unref the volume, since the list entries needs that.
+ // We'll keep a reference in the icon.
+ glib::Object<GVolume> volume(G_VOLUME(v->data));
DeviceLauncherIcon* icon = new DeviceLauncherIcon(volume);
- self->map_[volume] = icon;
- self->IconAdded.emit(AbstractLauncherIcon::Ptr(icon));
+ map_[volume] = icon;
+ IconAdded.emit(AbstractLauncherIcon::Ptr(icon));
}
g_list_free(volumes);
-
- self->on_device_populate_entry_id_ = 0;
-
- return false;
}
/* Uses a std::map to track all the volume icons shown and not shown.
* Keep in mind: when "volume-removed" is recevied we should erase
* the pair (GVolume - DeviceLauncherIcon) from the std::map to avoid leaks
*/
-void DeviceLauncherSection::OnVolumeAdded(GVolumeMonitor* monitor,
- GVolume* volume,
- DeviceLauncherSection* self)
+void DeviceLauncherSection::OnVolumeAdded(GVolumeMonitor* monitor, GVolume* volume)
{
- DeviceLauncherIcon* icon = new DeviceLauncherIcon(volume);
-
- self->map_[volume] = icon;
- self->IconAdded.emit(AbstractLauncherIcon::Ptr(icon));
+ // This just wraps the volume in a glib::Object, global ref_count is only
+ // temporary changed.
+ glib::Object<GVolume> gvolume(volume, glib::AddRef());
+ DeviceLauncherIcon* icon = new DeviceLauncherIcon(gvolume);
+
+ map_[gvolume] = icon;
+ IconAdded.emit(AbstractLauncherIcon::Ptr(icon));
}
-void DeviceLauncherSection::OnVolumeRemoved(GVolumeMonitor* monitor,
- GVolume* volume,
- DeviceLauncherSection* self)
+void DeviceLauncherSection::OnVolumeRemoved(GVolumeMonitor* monitor, GVolume* volume)
{
+ auto volume_it = map_.find(volume);
+
// It should not happen! Let me do the check anyway.
- if (self->map_.find(volume) != self->map_.end())
- {
- self->map_[volume]->OnRemoved();
- self->map_.erase(volume);
+ if (volume_it != map_.end())
+ {
+ volume_it->second->OnRemoved();
+ map_.erase(volume_it);
}
}
/* Keep in mind: we could have a GMount without a related GVolume
* so check everything to avoid unwanted behaviors.
*/
-void DeviceLauncherSection::OnMountAdded(GVolumeMonitor* monitor,
- GMount* mount,
- DeviceLauncherSection* self)
+void DeviceLauncherSection::OnMountAdded(GVolumeMonitor* monitor, GMount* mount)
{
- std::map<GVolume* , DeviceLauncherIcon* >::iterator it;
glib::Object<GVolume> volume(g_mount_get_volume(mount));
- it = self->map_.find(volume);
+ auto volume_it = map_.find(volume);
- if (it != self->map_.end())
- it->second->UpdateVisibility(1);
+ if (volume_it != map_.end())
+ volume_it->second->UpdateVisibility(1);
}
/* We don't use "mount-removed" signal since it is received after "volume-removed"
* signal. You should read also the comment above.
*/
-void DeviceLauncherSection::OnMountPreUnmount(GVolumeMonitor* monitor,
- GMount* mount,
- DeviceLauncherSection* self)
+void DeviceLauncherSection::OnMountPreUnmount(GVolumeMonitor* monitor, GMount* mount)
{
- std::map<GVolume* , DeviceLauncherIcon* >::iterator it;
glib::Object<GVolume> volume(g_mount_get_volume(mount));
- it = self->map_.find(volume);
+ auto volume_it = map_.find(volume);
- if (it != self->map_.end())
- it->second->UpdateVisibility(0);
+ if (volume_it != map_.end())
+ volume_it->second->UpdateVisibility(0);
}
} // namespace launcher
diff --git a/plugins/unityshell/src/DeviceLauncherSection.h b/plugins/unityshell/src/DeviceLauncherSection.h
index 9870f37e4..6ddb7b00e 100644
--- a/plugins/unityshell/src/DeviceLauncherSection.h
+++ b/plugins/unityshell/src/DeviceLauncherSection.h
@@ -25,6 +25,7 @@
#include <sigc++/sigc++.h>
#include <sigc++/signal.h>
#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/GLibSignal.h>
#include "DeviceLauncherIcon.h"
@@ -45,31 +46,17 @@ public:
sigc::signal<void, AbstractLauncherIcon::Ptr> IconAdded;
private:
- static bool PopulateEntries(DeviceLauncherSection* self);
-
- static void OnVolumeAdded(GVolumeMonitor* monitor,
- GVolume* volume,
- DeviceLauncherSection* self);
+ void PopulateEntries();
- static void OnVolumeRemoved(GVolumeMonitor* monitor,
- GVolume* volume,
- DeviceLauncherSection* self);
-
- static void OnMountAdded(GVolumeMonitor* monitor,
- GMount* mount,
- DeviceLauncherSection* self);
-
- static void OnMountPreUnmount(GVolumeMonitor* monitor,
- GMount* mount,
- DeviceLauncherSection* self);
+ void OnVolumeAdded(GVolumeMonitor* monitor, GVolume* volume);
+ void OnVolumeRemoved(GVolumeMonitor* monitor, GVolume* volume);
+ void OnMountAdded(GVolumeMonitor* monitor, GMount* mount);
+ void OnMountPreUnmount(GVolumeMonitor* monitor, GMount* mount);
private:
+ glib::SignalManager sig_manager_;
glib::Object<GVolumeMonitor> monitor_;
std::map<GVolume*, DeviceLauncherIcon*> map_;
- gulong on_volume_added_handler_id_;
- gulong on_volume_removed_handler_id_;
- gulong on_mount_added_handler_id_;
- gulong on_mount_pre_unmount_handler_id_;
gulong on_device_populate_entry_id_;
};
diff --git a/plugins/unityshell/src/DndData.h b/plugins/unityshell/src/DndData.h
index d6df7778a..e714d8bcf 100644
--- a/plugins/unityshell/src/DndData.h
+++ b/plugins/unityshell/src/DndData.h
@@ -42,22 +42,22 @@ public:
/**
* Returns a std::set<std::string> with all the uris.
**/
- std::set<std::string>& Uris() { return uris_; }
+ std::set<std::string> const& Uris() const { return uris_; }
/**
* Returns a std::set<std::string> with all the types.
**/
- std::set<std::string>& Types() { return types_; }
+ std::set<std::string> const& Types() const { return types_; }
/**
* Returns a std::set<std::string> with all uris of a given type.
**/
- std::set<std::string>& UrisByType(const std::string& type) { return types_to_uris_[type]; }
+ std::set<std::string> const& UrisByType(const std::string& type) const { return types_to_uris_.find(type)->second; }
/**
* Returns a std::set<std::string> with all types of a given uri.
**/
- std::string& TypeByUri(const std::string& uris) { return uris_to_types_[uris]; }
+ std::string const& TypeByUri(const std::string& uris) { return uris_to_types_.find(uris)->second; }
private:
std::set<std::string> uris_;
diff --git a/plugins/unityshell/src/GestureEngine.cpp b/plugins/unityshell/src/GestureEngine.cpp
index 41efe8030..9bf825b3a 100644
--- a/plugins/unityshell/src/GestureEngine.cpp
+++ b/plugins/unityshell/src/GestureEngine.cpp
@@ -32,6 +32,7 @@ GestureEngine::GestureEngine(CompScreen* screen)
_screen = screen;
_drag_id = 0;
+ _drag_window = 0;
_pinch_id = 0;
_touch_id = 0;
_drag_grab = 0;
@@ -174,7 +175,7 @@ GestureEngine::OnDragFinish(GeisAdapter::GeisDragData* data)
void
GestureEngine::EndDrag()
{
- if (_drag_id && _drag_window)
+ if (_drag_window)
{
_screen->removeGrab(_drag_grab, NULL);
_drag_grab = 0;
diff --git a/plugins/unityshell/src/HudController.cpp b/plugins/unityshell/src/HudController.cpp
index 1970d1175..9dfbbdf5c 100644
--- a/plugins/unityshell/src/HudController.cpp
+++ b/plugins/unityshell/src/HudController.cpp
@@ -88,9 +88,14 @@ Controller::~Controller()
window_->UnReference();
window_ = 0;
- g_source_remove(timeline_id_);
- g_source_remove(ensure_id_);
- g_source_remove(type_wait_handle_);
+ if (timeline_id_)
+ g_source_remove(timeline_id_);
+
+ if (ensure_id_)
+ g_source_remove(ensure_id_);
+
+ if (type_wait_handle_)
+ g_source_remove(type_wait_handle_);
}
void Controller::SetupWindow()
@@ -165,6 +170,16 @@ void Controller::EnsureHud()
}
}
+void Controller::SetIcon(std::string const& icon_name)
+{
+ LOG_DEBUG(logger) << "setting icon to - " << icon_name;
+
+ if (view_)
+ view_->SetIcon(icon_name, tile_size, icon_size, launcher_width - tile_size);
+
+ ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(icon_name.c_str()));
+}
+
nux::BaseWindow* Controller::window() const
{
return window_;
@@ -296,6 +311,10 @@ void Controller::ShowHud()
// Windows list stack for all the monitors
GList *windows = bamf_matcher_get_window_stack_for_monitor(matcher, -1);
+ // Reset values, in case we can't find a window ie. empty current desktop
+ active_xid = 0;
+ active_win = nullptr;
+
for (GList *l = windows; l; l = l->next)
{
if (!BAMF_IS_WINDOW(l->data))
@@ -306,6 +325,8 @@ void Controller::ShowHud()
Window xid = bamf_window_get_xid(win);
if (bamf_view_user_visible(view) && bamf_window_get_window_type(win) != BAMF_WINDOW_DOCK &&
+ WindowManager::Default()->IsWindowOnCurrentDesktop(xid) &&
+ WindowManager::Default()->IsWindowVisible(xid) &&
std::find(unity_xids.begin(), unity_xids.end(), xid) == unity_xids.end())
{
active_win = win;
@@ -330,8 +351,7 @@ void Controller::ShowHud()
}
LOG_DEBUG(logger) << "Taking application icon: " << focused_app_icon_;
- ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(focused_app_icon_.c_str()));
- view_->SetIcon(focused_app_icon_);
+ SetIcon(focused_app_icon_);
window_->ShowWindow(true);
window_->PushToFront();
@@ -447,22 +467,12 @@ void Controller::OnActivateRequest(GVariant* variant)
void Controller::OnSearchChanged(std::string search_string)
{
- //FIXME!! - when the service is smart enough to not fall over if you send many requests, this should be removed
+ // we're using live_search_reached, so this is called 40ms after the text
+ // is input in the search bar
LOG_DEBUG(logger) << "Search Changed";
- auto on_search_changed_timeout_lambda = [] (gpointer data) -> gboolean {
- Controller* self = static_cast<Controller*>(data);
- self->hud_service_.RequestQuery(self->last_search_);
- self->type_wait_handle_ = 0;
- return FALSE;
- };
-
+
last_search_ = search_string;
-
- if (type_wait_handle_)
- {
- g_source_remove(type_wait_handle_);
- }
- type_wait_handle_ = g_timeout_add(100, on_search_changed_timeout_lambda, this);
+ hud_service_.RequestQuery(last_search_);
}
void Controller::OnSearchActivated(std::string search_string)
@@ -483,8 +493,7 @@ void Controller::OnQueryActivated(Query::Ptr query)
void Controller::OnQuerySelected(Query::Ptr query)
{
LOG_DEBUG(logger) << "Selected query, " << query->formatted_text;
- view_->SetIcon(query->icon_name);
- ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(query->icon_name.c_str()));
+ SetIcon(query->icon_name);
}
void Controller::OnQueriesFinished(Hud::Queries queries)
@@ -500,9 +509,8 @@ void Controller::OnQueriesFinished(Hud::Queries queries)
}
}
- LOG_DEBUG(logger) << "setting icon to - " << icon_name;
- view_->SetIcon(icon_name);
- ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(icon_name.c_str()));
+ SetIcon(icon_name);
+ view_->SearchFinished();
}
// Introspectable
diff --git a/plugins/unityshell/src/HudController.h b/plugins/unityshell/src/HudController.h
index 8efecfc3d..22203cb71 100644
--- a/plugins/unityshell/src/HudController.h
+++ b/plugins/unityshell/src/HudController.h
@@ -48,6 +48,8 @@ public:
nux::BaseWindow* window() const;
nux::Property<int> launcher_width;
+ nux::Property<int> icon_size;
+ nux::Property<int> tile_size;
nux::Property<bool> launcher_locked_out;
nux::Property<bool> multiple_launchers;
@@ -65,6 +67,7 @@ private:
void SetupWindow();
void SetupHudView();
void RegisterUBusInterests();
+ void SetIcon(std::string const& icon_name);
int GetTargetMonitor();
bool IsLockedToLauncher(int monitor);
diff --git a/plugins/unityshell/src/HudIcon.cpp b/plugins/unityshell/src/HudIcon.cpp
index 70676ba1e..e2ed3c0c5 100644
--- a/plugins/unityshell/src/HudIcon.cpp
+++ b/plugins/unityshell/src/HudIcon.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Canonical Ltd
+ * Copyright (C) 2010-2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Gord Allott <gord.allott@canonical.com>
+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
*/
@@ -24,8 +25,7 @@
namespace
{
nux::logging::Logger logger("unity.hud.icon");
- const unsigned int tile_margin = 4;
- const unsigned int minimum_width = 64;
+ const unsigned int vertical_padding = 4;
}
namespace unity
@@ -33,13 +33,9 @@ namespace unity
namespace hud
{
-Icon::Icon(std::string const& icon_name, unsigned int size)
- : IconTexture(icon_name, size, true)
+Icon::Icon()
+ : IconTexture("", 0, true)
{
- int tile_size = size + tile_margin * 2;
- SetMinimumWidth(minimum_width);
- SetMinimumHeight(tile_size);
- icon_renderer_.SetTargetSize(tile_size, size, 0);
background_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_back_54.png", -1, true));
gloss_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_shine_54.png", -1, true));
edge_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_edge_54.png", -1, true));
@@ -53,6 +49,14 @@ Icon::Icon(std::string const& icon_name, unsigned int size)
});
}
+void Icon::SetIcon(std::string const& icon_name, unsigned int icon_size, unsigned int tile_size)
+{
+ IconTexture::SetByIconName(icon_name, icon_size);
+ icon_renderer_.SetTargetSize(tile_size, icon_size, 0);
+ SetMinimumWidth(tile_size);
+ SetMinimumHeight(tile_size + vertical_padding * 2);
+}
+
void Icon::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
{
if (texture() == nullptr)
@@ -63,8 +67,8 @@ void Icon::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
arg.colorify = nux::color::White;
arg.running_arrow = true;
arg.running_on_viewport = true;
- arg.render_center = nux::Point3(32, 32, 0);
- arg.logical_center = nux::Point3(52, 50, 0);
+ arg.render_center = nux::Point3(GetMinimumWidth() / 2.0f, GetMinimumHeight() / 2.0f, 0.0f);
+ arg.logical_center = arg.render_center;
arg.window_indicators = true;
arg.backlight_intensity = 1.0f;
arg.alpha = 1.0f;
diff --git a/plugins/unityshell/src/HudIcon.h b/plugins/unityshell/src/HudIcon.h
index 15aa28748..e4658b484 100644
--- a/plugins/unityshell/src/HudIcon.h
+++ b/plugins/unityshell/src/HudIcon.h
@@ -34,8 +34,10 @@ namespace hud
class Icon : public unity::IconTexture
{
public:
- typedef nux::ObjectPtr<IconTexture> Ptr;
- Icon(std::string const& icon_name, unsigned int size);
+ typedef nux::ObjectPtr<Icon> Ptr;
+ Icon();
+
+ void SetIcon(std::string const& icon_name, unsigned int icon_size, unsigned int tile_size);
protected:
void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
diff --git a/plugins/unityshell/src/HudLauncherIcon.cpp b/plugins/unityshell/src/HudLauncherIcon.cpp
index 207486a1e..4710b3b8e 100644
--- a/plugins/unityshell/src/HudLauncherIcon.cpp
+++ b/plugins/unityshell/src/HudLauncherIcon.cpp
@@ -72,7 +72,7 @@ HudLauncherIcon::HudLauncherIcon(LauncherHideMode hide_mode)
ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::bind(sigc::mem_fun(this, &HudLauncherIcon::OnOverlayShown), true));
ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::bind(sigc::mem_fun(this, &HudLauncherIcon::OnOverlayShown), false));
- mouse_enter.connect([&](int m) { ubus_manager_.SendMessage(UBUS_DASH_ABOUT_TO_SHOW, NULL); });
+ mouse_enter.connect([&](int m) { ubus_manager_.SendMessage(UBUS_DASH_ABOUT_TO_SHOW); });
}
void HudLauncherIcon::SetHideMode(LauncherHideMode hide_mode)
@@ -117,7 +117,10 @@ nux::Color HudLauncherIcon::GlowColor()
void HudLauncherIcon::ActivateLauncherIcon(ActionArg arg)
{
- // wut? activate? noo we don't do that.
+ if (GetQuirk(QUIRK_VISIBLE))
+ {
+ ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST);
+ }
}
std::list<DbusmenuMenuitem*> HudLauncherIcon::GetMenus()
diff --git a/plugins/unityshell/src/HudView.cpp b/plugins/unityshell/src/HudView.cpp
index 71a0434c7..d26788f83 100644
--- a/plugins/unityshell/src/HudView.cpp
+++ b/plugins/unityshell/src/HudView.cpp
@@ -39,11 +39,10 @@ namespace hud
namespace
{
nux::logging::Logger logger("unity.hud.view");
-const int icon_size = 46;
const int grow_anim_length = 90 * 1000;
const int pause_before_grow_length = 32 * 1000;
-const int default_width = 1024;
+const int default_width = 960;
const int default_height = 276;
const int content_width = 941;
@@ -126,6 +125,9 @@ View::~View()
{
RemoveChild((*button).GetPointer());
}
+
+ if (timeline_id_)
+ g_source_remove(timeline_id_);
}
void View::ProcessGrowShrink()
@@ -175,7 +177,7 @@ void View::ResetToDefault()
void View::Relayout()
{
- nux::Geometry geo = GetGeometry();
+ nux::Geometry const& geo = GetGeometry();
content_geo_ = GetBestFitGeometry(geo);
LOG_DEBUG(logger) << "content_geo: " << content_geo_.width << "x" << content_geo_.height;
@@ -267,10 +269,20 @@ void View::SetQueries(Hud::Queries queries)
QueueDraw();
}
-void View::SetIcon(std::string icon_name)
+void View::SetIcon(std::string icon_name, unsigned int tile_size, unsigned int size, unsigned int padding)
{
+ if (!icon_)
+ return;
+
LOG_DEBUG(logger) << "Setting icon to " << icon_name;
- icon_->SetByIconName(icon_name, icon_size);
+
+ icon_->SetIcon(icon_name, size, tile_size);
+ icon_->SetMinimumWidth(tile_size + padding);
+
+ /* We need to compute this value manually, since the _content_layout height changes */
+ int content_height = search_bar_->GetBaseHeight() + top_padding + bottom_padding;
+ icon_->SetMinimumHeight(std::max(icon_->GetMinimumHeight(), content_height));
+
QueueDraw();
}
@@ -307,10 +319,8 @@ nux::Geometry View::GetBestFitGeometry(nux::Geometry const& for_geo)
int width = default_width;
int height = default_height;
- if (!show_embedded_icon_)
- {
- width -= icon_->GetGeometry().width;
- }
+ if (show_embedded_icon_)
+ width += icon_->GetGeometry().width;
LOG_DEBUG (logger) << "best fit is, " << width << ", " << height;
@@ -343,7 +353,7 @@ void View::SetupViews()
layout_ = new nux::HLayout();
{
// fill layout with icon
- icon_ = new Icon("", icon_size);
+ icon_ = new Icon();
{
AddChild(icon_.GetPointer());
layout_->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL);
@@ -361,7 +371,7 @@ void View::SetupViews()
search_bar_->SetMinimumHeight(style.GetSearchBarHeight());
search_bar_->SetMaximumHeight(style.GetSearchBarHeight());
search_bar_->search_hint = _("Type your command");
- search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged));
+ search_bar_->live_search_reached.connect(sigc::mem_fun(this, &View::OnSearchChanged));
AddChild(search_bar_.GetPointer());
content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT);
@@ -382,14 +392,6 @@ void View::OnSearchChanged(std::string const& search_string)
{
LOG_DEBUG(logger) << "got search change";
search_changed.emit(search_string);
- if (search_string.empty())
- {
- search_bar_->search_hint = _("Type your command");
- }
- else
- {
- search_bar_->search_hint = "";
- }
std::list<HudButton::Ptr>::iterator it;
for(it = buttons_.begin(); it != buttons_.end(); ++it)
@@ -457,7 +459,7 @@ void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
if (timeline_need_more_draw_ && !timeline_id_)
{
- timeline_id_ = g_timeout_add(0, [] (gpointer data) -> gboolean
+ timeline_id_ = g_idle_add([] (gpointer data) -> gboolean
{
View *self = static_cast<View*>(data);
self->QueueDraw();
@@ -501,13 +503,17 @@ bool View::InspectKeyEvent(unsigned int eventType,
else
{
search_bar_->search_string = "";
- search_bar_->search_hint = _("Type your command");
}
return true;
}
return false;
}
+void View::SearchFinished()
+{
+ search_bar_->SearchFinished();
+}
+
void View::OnSearchbarActivated()
{
// The "Enter" key has been received and the text entry has the key focus.
@@ -571,13 +577,11 @@ nux::Area* View::FindKeyFocusArea(unsigned int event_type,
if (search_bar_->search_string == "")
{
- search_bar_->search_hint = _("Type your command");
ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
}
else
{
search_bar_->search_string = "";
- search_bar_->search_hint = _("Type your command");
return search_bar_->text_entry();
}
return NULL;
diff --git a/plugins/unityshell/src/HudView.h b/plugins/unityshell/src/HudView.h
index 66c9705a4..9a5a20a6e 100644
--- a/plugins/unityshell/src/HudView.h
+++ b/plugins/unityshell/src/HudView.h
@@ -53,8 +53,9 @@ public:
nux::View* default_focus() const;
void SetQueries(Hud::Queries queries);
- void SetIcon(std::string icon_name);
+ void SetIcon(std::string icon_name, unsigned int tile_size, unsigned int size, unsigned int padding);
void ShowEmbeddedIcon(bool show);
+ void SearchFinished();
void AboutToShow();
void AboutToHide();
@@ -123,4 +124,3 @@ private:
}
}
#endif
-
diff --git a/plugins/unityshell/src/IconTexture.cpp b/plugins/unityshell/src/IconTexture.cpp
index 1668ad95b..23d45ec5d 100644
--- a/plugins/unityshell/src/IconTexture.cpp
+++ b/plugins/unityshell/src/IconTexture.cpp
@@ -46,6 +46,7 @@ using namespace unity;
IconTexture::IconTexture(nux::BaseTexture* texture, guint width, guint height)
: TextureArea(NUX_TRACKER_LOCATION),
_accept_key_nav_focus(false),
+ _pixbuf_cached(nullptr),
_size(height),
_texture_cached(texture),
_texture_width(width),
@@ -60,6 +61,7 @@ IconTexture::IconTexture(nux::BaseTexture* texture, guint width, guint height)
IconTexture::IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading)
: TextureArea(NUX_TRACKER_LOCATION),
_accept_key_nav_focus(false),
+ _pixbuf_cached(nullptr),
_icon_name(!icon_name.empty() ? icon_name : DEFAULT_ICON),
_size(size),
_texture_width(0),
@@ -167,6 +169,7 @@ void IconTexture::IconLoaded(std::string const& icon_name, unsigned size,
}
else
{
+ _pixbuf_cached = nullptr;
_loading = false;
// Protects against a missing default icon, we only request it if icon_name
diff --git a/plugins/unityshell/src/IconTexture.h b/plugins/unityshell/src/IconTexture.h
index 0b6bcf638..52209e115 100644
--- a/plugins/unityshell/src/IconTexture.h
+++ b/plugins/unityshell/src/IconTexture.h
@@ -63,7 +63,7 @@ protected:
std::string GetName() const;
void AddProperties(GVariantBuilder* builder);
virtual bool DoCanFocus();
- GdkPixbuf* _pixbuf_cached;
+ GdkPixbuf* _pixbuf_cached;
protected:
void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
diff --git a/plugins/unityshell/src/Launcher.cpp b/plugins/unityshell/src/Launcher.cpp
index ac108076c..1b1bc473c 100644
--- a/plugins/unityshell/src/Launcher.cpp
+++ b/plugins/unityshell/src/Launcher.cpp
@@ -406,6 +406,7 @@ Launcher::AddProperties(GVariantBuilder* builder)
.add("hovered", _hovered)
.add("hidemode", options()->hide_mode)
.add("hidden", _hidden)
+ .add("is_showing", ! _hidden)
.add("x", abs_geo.x)
.add("y", abs_geo.y)
.add("width", abs_geo.width)
@@ -2685,9 +2686,6 @@ void Launcher::OnDNDDataCollected(const std::list<char*>& mimes)
break;
}
- if (!_dnd_data.Uris().size())
- return;
-
_hide_machine->SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, true);
if (IsOverlayOpen())
@@ -2706,7 +2704,7 @@ void Launcher::OnDNDDataCollected(const std::list<char*>& mimes)
{
for (auto it : *_model)
{
- if (it->QueryAcceptDrop(_dnd_data) != nux::DNDACTION_NONE)
+ if (it->ShouldHighlightOnDrag(_dnd_data))
it->SetQuirk(AbstractLauncherIcon::QUIRK_DROP_PRELIGHT, true);
else
it->SetQuirk(AbstractLauncherIcon::QUIRK_DROP_DIM, true);
diff --git a/plugins/unityshell/src/LauncherController.cpp b/plugins/unityshell/src/LauncherController.cpp
index 94dbf9cb5..f6cb5b753 100644
--- a/plugins/unityshell/src/LauncherController.cpp
+++ b/plugins/unityshell/src/LauncherController.cpp
@@ -151,7 +151,6 @@ public:
DeviceLauncherSection* device_section_;
LauncherEntryRemoteModel remote_model_;
AbstractLauncherIcon::Ptr expo_icon_;
- AbstractLauncherIcon::Ptr desktop_launcher_icon_;
AbstractLauncherIcon::Ptr desktop_icon_;
int num_workspaces_;
bool show_desktop_icon_;
@@ -498,7 +497,7 @@ void Controller::Impl::SortAndUpdate()
std::stringstream shortcut_string;
shortcut_string << (shortcut % 10);
icon->SetShortcut(shortcut_string.str()[0]);
- shortcut++;
+ ++shortcut;
}
// reset shortcut
else
@@ -608,6 +607,8 @@ void Controller::Impl::OnFavoriteStoreFavoriteAdded(std::string const& entry, st
else
model_->ReorderBefore(result, other, false);
}
+
+ SortAndUpdate();
}
void Controller::Impl::OnFavoriteStoreFavoriteRemoved(std::string const& entry)
@@ -700,13 +701,12 @@ void Controller::Impl::RemoveExpoAction()
void Controller::Impl::InsertDesktopIcon()
{
- desktop_launcher_icon_ = AbstractLauncherIcon::Ptr(new DesktopLauncherIcon());
- RegisterIcon(desktop_launcher_icon_);
+ RegisterIcon(desktop_icon_);
}
void Controller::Impl::RemoveDesktopIcon()
{
- model_->RemoveIcon(desktop_launcher_icon_);
+ model_->RemoveIcon(desktop_icon_);
}
void Controller::Impl::RegisterIcon(AbstractLauncherIcon::Ptr icon)
@@ -740,10 +740,12 @@ void Controller::Impl::OnViewOpened(BamfMatcher* matcher, BamfView* view, gpoint
return;
}
- AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));
+ g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
+ AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));
+ icon->visibility_changed.connect(sigc::mem_fun(self, &Impl::SortAndUpdate));
icon->SetSortPriority(self->sort_priority_++);
-
self->RegisterIcon(icon);
+ self->SortAndUpdate();
}
AbstractLauncherIcon::Ptr Controller::Impl::CreateFavorite(const char* file_path)
@@ -761,9 +763,8 @@ AbstractLauncherIcon::Ptr Controller::Impl::CreateFavorite(const char* file_path
return result;
}
- g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
-
bamf_view_set_sticky(BAMF_VIEW(app), true);
+ g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));
icon->SetSortPriority(sort_priority_++);
result = icon;
@@ -789,6 +790,7 @@ SoftwareCenterLauncherIcon::Ptr Controller::Impl::CreateSCLauncherIcon(std::stri
}
bamf_view_set_sticky(BAMF_VIEW(app), true);
+ g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path);
result->SetSortPriority(sort_priority_++);
@@ -830,8 +832,8 @@ void Controller::Impl::SetupBamf()
if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))
continue;
- g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
+ g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));
icon->SetSortPriority(sort_priority_++);
RegisterIcon(icon);
@@ -847,7 +849,7 @@ void Controller::Impl::SetupBamf()
void Controller::Impl::SendHomeActivationRequest()
{
- ubus.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", 0, ""));
+ ubus.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, ""));
}
Controller::Controller(Display* display)
@@ -904,9 +906,16 @@ std::vector<AbstractLauncherIcon::Ptr> Controller::GetAltTabIcons(bool current)
results.push_back(pimpl->desktop_icon_);
for (auto icon : *(pimpl->model_))
+ {
if (icon->ShowInSwitcher(current))
- results.push_back(icon);
-
+ {
+ //otherwise we get two desktop icons in the switcher.
+ if (icon->GetIconType() != AbstractLauncherIcon::IconType::TYPE_DESKTOP)
+ {
+ results.push_back(icon);
+ }
+ }
+ }
return results;
}
diff --git a/plugins/unityshell/src/LauncherController.h b/plugins/unityshell/src/LauncherController.h
index 71712e436..e2dbc7619 100644
--- a/plugins/unityshell/src/LauncherController.h
+++ b/plugins/unityshell/src/LauncherController.h
@@ -25,6 +25,7 @@
#include <vector>
#include <sigc++/sigc++.h>
+#include "LauncherOptions.h"
#include "SoftwareCenterLauncherIcon.h"
namespace unity
@@ -64,10 +65,10 @@ public:
void HandleLauncherKeyPress(int when);
void HandleLauncherKeyRelease(bool was_tap, int when);
- bool HandleLauncherKeyEvent(Display *display,
- unsigned int key_sym,
- unsigned long key_code,
- unsigned long key_state,
+ bool HandleLauncherKeyEvent(Display *display,
+ unsigned int key_sym,
+ unsigned long key_code,
+ unsigned long key_state,
char* key_string);
void KeyNavActivate();
diff --git a/plugins/unityshell/src/LauncherIcon.cpp b/plugins/unityshell/src/LauncherIcon.cpp
index e7051d91c..448bd72f5 100644
--- a/plugins/unityshell/src/LauncherIcon.cpp
+++ b/plugins/unityshell/src/LauncherIcon.cpp
@@ -202,6 +202,7 @@ LauncherIcon::AddProperties(GVariantBuilder* builder)
.add("icon_type", _icon_type)
.add("tooltip_text", tooltip_text())
.add("sort_priority", _sort_priority)
+ .add("shortcut", _shortcut)
.add("monitors_visibility", g_variant_builder_end(&monitors_builder))
.add("active", GetQuirk(QUIRK_ACTIVE))
.add("visible", GetQuirk(QUIRK_VISIBLE))
@@ -537,7 +538,7 @@ void LauncherIcon::RecvMouseLeave(int monitor)
_tooltip->ShowWindow(false);
}
-bool LauncherIcon::OpenQuicklist(bool default_to_first_item, int monitor)
+bool LauncherIcon::OpenQuicklist(bool select_first_item, int monitor)
{
std::list<DbusmenuMenuitem*> menus = Menus();
@@ -583,8 +584,8 @@ bool LauncherIcon::OpenQuicklist(bool default_to_first_item, int monitor)
_quicklist->AddMenuItem(ql_item);
}
- if (default_to_first_item)
- _quicklist->DefaultToFirstItem();
+ if (select_first_item)
+ _quicklist->SelectFirstItem();
if (monitor < 0)
{
@@ -853,6 +854,11 @@ LauncherIcon::SetQuirk(LauncherIcon::Quirk quirk, bool value)
UBusServer* ubus = ubus_server_get_default();
ubus_server_send_message(ubus, UBUS_LAUNCHER_ICON_URGENT_CHANGED, g_variant_new_boolean(value));
}
+
+ if (quirk == QUIRK_VISIBLE)
+ {
+ visibility_changed.emit();
+ }
}
gboolean
diff --git a/plugins/unityshell/src/LauncherIcon.h b/plugins/unityshell/src/LauncherIcon.h
index cb7a17e10..7d1c3ea66 100644
--- a/plugins/unityshell/src/LauncherIcon.h
+++ b/plugins/unityshell/src/LauncherIcon.h
@@ -86,7 +86,7 @@ public:
void ShowTooltip();
- bool OpenQuicklist(bool default_to_first_item = false, int monitor = -1);
+ bool OpenQuicklist(bool select_first_item = false, int monitor = -1);
void SetCenter(nux::Point3 center, int parent_monitor, nux::Geometry parent_geo);
@@ -166,12 +166,18 @@ public:
void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote);
- nux::DndAction QueryAcceptDrop(unity::DndData& dnd_data)
+ nux::DndAction QueryAcceptDrop(DndData const& dnd_data)
{
return OnQueryAcceptDrop(dnd_data);
}
- void AcceptDrop(unity::DndData& dnd_data)
+
+ bool ShouldHighlightOnDrag(DndData const& dnd_data)
+ {
+ return OnShouldHighlightOnDrag(dnd_data);
+ }
+
+ void AcceptDrop(DndData const& dnd_data)
{
return OnAcceptDrop(dnd_data);
}
@@ -240,12 +246,17 @@ protected:
return "";
}
- virtual nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data)
+ virtual nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data)
{
return nux::DNDACTION_NONE;
}
- virtual void OnAcceptDrop(unity::DndData& dnd_data) {}
+ virtual bool OnShouldHighlightOnDrag(DndData const& dnd_data)
+ {
+ return false;
+ }
+
+ virtual void OnAcceptDrop(DndData const& dnd_data) {}
virtual void OnDndEnter() {}
diff --git a/plugins/unityshell/src/LensBar.cpp b/plugins/unityshell/src/LensBar.cpp
index 6c27a4e7e..024e8944d 100644
--- a/plugins/unityshell/src/LensBar.cpp
+++ b/plugins/unityshell/src/LensBar.cpp
@@ -21,8 +21,6 @@
#include "CairoTexture.h"
#include "LensBar.h"
-#include "UBusMessages.h"
-#include "UBusWrapper.h"
namespace unity
{
@@ -75,9 +73,7 @@ void LensBar::SetupHomeLens()
layout_->AddView(icon, 0, nux::eCenter, nux::MINOR_SIZE_FULL);
AddChild(icon);
- icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); QueueDraw(); });
- icon->mouse_down.connect([&] (int x, int y, unsigned long button, unsigned long keyboard) { QueueDraw(); });
- icon->key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });
+ icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); });
icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
}
@@ -90,9 +86,7 @@ void LensBar::AddLens(Lens::Ptr& lens)
layout_->AddView(icon, 0, nux::eCenter, nux::eFix);
AddChild(icon);
- icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); QueueDraw(); });
- icon->mouse_down.connect([&] (int x, int y, unsigned long button, unsigned long keyboard) { QueueDraw(); });
- icon->key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });
+ icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); });
icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
}
@@ -119,12 +113,6 @@ void LensBar::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
nux::GetPainter().RenderSinglePaintLayer(gfx_context, base, bg_layer_.get());
gfx_context.PopClippingRectangle();
-
- // trigger a redraw of the decoration, as the special masking of the
- // decoration is usually destroyed by the clipping-rects/previous paints
- ubus_server_send_message(ubus_server_get_default(),
- UBUS_DASH_DECORATION_DAMAGED,
- NULL);
}
void LensBar::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
diff --git a/plugins/unityshell/src/LensBarIcon.cpp b/plugins/unityshell/src/LensBarIcon.cpp
index 8c62b84ec..dc730213d 100644
--- a/plugins/unityshell/src/LensBarIcon.cpp
+++ b/plugins/unityshell/src/LensBarIcon.cpp
@@ -57,6 +57,7 @@ LensBarIcon::LensBarIcon(std::string id_, std::string icon_hint)
SetAcceptKeyNavFocusOnMouseEnter(true);
active.changed.connect(sigc::mem_fun(this, &LensBarIcon::OnActiveChanged));
+ key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });
}
LensBarIcon::~LensBarIcon()
diff --git a/plugins/unityshell/src/MockLauncherIcon.h b/plugins/unityshell/src/MockLauncherIcon.h
index fc2c95597..d0d45f296 100644
--- a/plugins/unityshell/src/MockLauncherIcon.h
+++ b/plugins/unityshell/src/MockLauncherIcon.h
@@ -120,7 +120,7 @@ public:
void SetSortPriority(int priority) { sort_priority_ = priority; }
- bool OpenQuicklist(bool default_to_first_item = false, int monitor = -1)
+ bool OpenQuicklist(bool select_first_item = false, int monitor = -1)
{
return false;
}
@@ -257,12 +257,17 @@ public:
return std::list<DbusmenuMenuitem*> ();
}
- nux::DndAction QueryAcceptDrop(unity::DndData& dnd_data)
+ nux::DndAction QueryAcceptDrop(DndData const& dnd_data)
{
return nux::DNDACTION_NONE;
}
- void AcceptDrop(unity::DndData& dnd_data) {}
+ bool ShouldHighlightOnDrag(DndData const& dnd_data)
+ {
+ return false;
+ }
+
+ void AcceptDrop(DndData const& dnd_data) {}
void SendDndEnter() {}
diff --git a/plugins/unityshell/src/OverlayRenderer.cpp b/plugins/unityshell/src/OverlayRenderer.cpp
index 5da4826fa..268e1ebd2 100644
--- a/plugins/unityshell/src/OverlayRenderer.cpp
+++ b/plugins/unityshell/src/OverlayRenderer.cpp
@@ -50,7 +50,6 @@ public:
void Init();
void OnBackgroundColorChanged(GVariant* args);
- void OnDashDecorationDamanged(GVariant* args);
void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_draw);
void DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
@@ -117,9 +116,6 @@ void OverlayRendererImpl::Init()
ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED,
sigc::mem_fun(this, &OverlayRendererImpl::OnBackgroundColorChanged));
- ubus_manager_.RegisterInterest(UBUS_DASH_DECORATION_DAMAGED,
- sigc::mem_fun(this, &OverlayRendererImpl::OnDashDecorationDamanged));
-
ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
}
@@ -135,11 +131,6 @@ void OverlayRendererImpl::OnBackgroundColorChanged(GVariant* args)
parent->need_redraw.emit();
}
-void OverlayRendererImpl::OnDashDecorationDamanged(GVariant* args)
-{
- parent->need_redraw.emit();
-}
-
void OverlayRendererImpl::InitASMInverseTextureMaskShader()
{
nux::NString AsmVtx =
@@ -387,14 +378,15 @@ void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry c
bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE;
nux::Geometry geo(content_geo);
-
+ int excess_border = (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges) ? EXCESS_BORDER : 0;
+
nux::Geometry larger_content_geo = content_geo;
- larger_content_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER);
+ larger_content_geo.OffsetSize(excess_border, excess_border);
nux::Geometry larger_geo(larger_content_geo);
nux::Geometry larger_absolute_geo = absolute_geo;
- larger_absolute_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER);
+ larger_absolute_geo.OffsetSize(excess_border, excess_border);
nux::TexCoordXForm texxform_absolute_bg;
texxform_absolute_bg.flip_v_coord = true;
@@ -775,13 +767,15 @@ void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geo
nux::Geometry geo = geometry;
bgs = 0;
+ int excess_border = (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) ? EXCESS_BORDER : 0;
+
nux::Geometry larger_content_geo = content_geo;
- larger_content_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER);
+ larger_content_geo.OffsetSize(excess_border, excess_border);
nux::Geometry larger_geo(larger_content_geo);
nux::Geometry larger_absolute_geo = absolute_geo;
- larger_absolute_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER);
+ larger_absolute_geo.OffsetSize(excess_border, excess_border);
gfx_context.PushClippingRectangle(larger_geo);
diff --git a/plugins/unityshell/src/PanelMenuView.cpp b/plugins/unityshell/src/PanelMenuView.cpp
index 6c64e3d77..9ac720bf9 100644
--- a/plugins/unityshell/src/PanelMenuView.cpp
+++ b/plugins/unityshell/src/PanelMenuView.cpp
@@ -983,6 +983,11 @@ void PanelMenuView::OnApplicationClosed(BamfApplication* app)
void PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
{
+ if (reinterpret_cast<BamfView*>(_view_name_changed_signal.object()) == view)
+ {
+ _view_name_changed_signal.Disconnect();
+ }
+
if (BAMF_IS_APPLICATION(view))
{
OnApplicationClosed(reinterpret_cast<BamfApplication*>(view));
diff --git a/plugins/unityshell/src/PlacesGroup.cpp b/plugins/unityshell/src/PlacesGroup.cpp
index 1f33a10e3..22115e56f 100644
--- a/plugins/unityshell/src/PlacesGroup.cpp
+++ b/plugins/unityshell/src/PlacesGroup.cpp
@@ -382,7 +382,8 @@ void
PlacesGroup::Relayout()
{
if (_idle_id == 0)
- _idle_id = g_idle_add((GSourceFunc)OnIdleRelayout, this);
+ _idle_id = g_idle_add_full(G_PRIORITY_HIGH,
+ (GSourceFunc)OnIdleRelayout, this, NULL);
}
gboolean
diff --git a/plugins/unityshell/src/PluginAdapter.cpp b/plugins/unityshell/src/PluginAdapter.cpp
index c786d680f..e9008c224 100644
--- a/plugins/unityshell/src/PluginAdapter.cpp
+++ b/plugins/unityshell/src/PluginAdapter.cpp
@@ -23,6 +23,7 @@
#include "UScreen.h"
#include <NuxCore/Logger.h>
+#include <UnityCore/Variant.h>
namespace
{
@@ -529,6 +530,52 @@ 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;
+ CompWindow* window;
+
+ window = m_Screen->findWindow(win);
+ if (window)
+ return (window->actions() & CompWindowActionCloseMask);
+
+ return false;
+}
+
+bool
PluginAdapter::IsWindowMinimizable(guint32 xid)
{
Window win = xid;
@@ -541,6 +588,19 @@ PluginAdapter::IsWindowMinimizable(guint32 xid)
return false;
}
+bool
+PluginAdapter::IsWindowMaximizable(guint32 xid)
+{
+ Window win = xid;
+ CompWindow* window;
+
+ window = m_Screen->findWindow(win);
+ if (window)
+ return (window->actions() & MAXIMIZABLE);
+
+ return false;
+}
+
void
PluginAdapter::Restore(guint32 xid)
{
@@ -806,7 +866,7 @@ PluginAdapter::GetWindowMonitor(guint32 xid) const
int x = geo.x + geo.width/2;
int y = geo.y + geo.height/2;
- return UScreen::GetDefault()->GetMonitorAtPosition(x, y);
+ return unity::UScreen::GetDefault()->GetMonitorAtPosition(x, y);
}
return -1;
@@ -1240,3 +1300,16 @@ PluginAdapter::OnWindowClosed(CompWindow *w)
_last_focused_window = NULL;
}
+void
+PluginAdapter::AddProperties(GVariantBuilder* builder)
+{
+ unity::variant::BuilderWrapper wrapper(builder);
+ wrapper.add(GetScreenGeometry())
+ .add("workspace_count", WorkspaceCount())
+ .add("active_window", GetActiveWindow())
+ .add("screen_grabbed", IsScreenGrabbed())
+ .add("scale_active", IsScaleActive())
+ .add("scale_active_for_group", IsScaleActiveForGroup())
+ .add("expo_active", IsExpoActive())
+ .add("viewport_switch_running", IsViewPortSwitchStarted());
+}
diff --git a/plugins/unityshell/src/PluginAdapter.h b/plugins/unityshell/src/PluginAdapter.h
index 9394b3986..70d5e433c 100644
--- a/plugins/unityshell/src/PluginAdapter.h
+++ b/plugins/unityshell/src/PluginAdapter.h
@@ -121,7 +121,10 @@ 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);
void Restore(guint32 xid);
void RestoreAt(guint32 xid, int x, int y);
@@ -163,6 +166,7 @@ public:
protected:
PluginAdapter(CompScreen* screen);
+ void AddProperties(GVariantBuilder* builder);
private:
std::string MatchStringForXids(std::vector<Window> *windows);
diff --git a/plugins/unityshell/src/PointerBarrier.h b/plugins/unityshell/src/PointerBarrier.h
index bda0715fb..07c414664 100644
--- a/plugins/unityshell/src/PointerBarrier.h
+++ b/plugins/unityshell/src/PointerBarrier.h
@@ -50,7 +50,7 @@ enum BarrierDirection
RIGHT = 4,
};
-class PointerBarrierWrapper
+class PointerBarrierWrapper : public sigc::trackable
{
public:
typedef std::shared_ptr<PointerBarrierWrapper> Ptr;
@@ -102,4 +102,4 @@ private:
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/plugins/unityshell/src/QuicklistMenuItem.cpp b/plugins/unityshell/src/QuicklistMenuItem.cpp
index a125135f0..4c0c0e1b6 100644
--- a/plugins/unityshell/src/QuicklistMenuItem.cpp
+++ b/plugins/unityshell/src/QuicklistMenuItem.cpp
@@ -89,10 +89,8 @@ QuicklistMenuItem::Initialize(DbusmenuMenuitem* item, bool debug)
this);
}
- mouse_down.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseDown));
mouse_up.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseUp));
mouse_click.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseClick));
- mouse_move.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseMove));
mouse_drag.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseDrag));
mouse_enter.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseEnter));
mouse_leave.connect(sigc::mem_fun(this, &QuicklistMenuItem::RecvMouseLeave));
@@ -215,6 +213,12 @@ QuicklistMenuItem::GetVisible()
DBUSMENU_MENUITEM_PROP_VISIBLE);
}
+bool
+QuicklistMenuItem::GetSelectable()
+{
+ return GetVisible() && GetEnabled();
+}
+
void QuicklistMenuItem::ItemActivated()
{
if (_debug)
@@ -333,11 +337,6 @@ OnItemActivated(guint timestamp,
//self->ItemActivated ();
}
-void QuicklistMenuItem::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
-{
-
-}
-
void QuicklistMenuItem::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
{
sigMouseReleased.emit(this, x, y);
@@ -352,11 +351,6 @@ void QuicklistMenuItem::RecvMouseClick(int x, int y, unsigned long button_flags,
sigMouseClick.emit(this, x, y);
}
-void QuicklistMenuItem::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
-{
-
-}
-
void QuicklistMenuItem::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
{
sigMouseDrag.emit(this, x, y);
@@ -364,13 +358,11 @@ void QuicklistMenuItem::RecvMouseDrag(int x, int y, int dx, int dy, unsigned lon
void QuicklistMenuItem::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags)
{
- _prelight = true;
sigMouseEnter.emit(this);
}
void QuicklistMenuItem::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags)
{
- _prelight = false;
sigMouseLeave.emit(this);
}
@@ -484,20 +476,14 @@ std::string QuicklistMenuItem::GetName() const
void QuicklistMenuItem::AddProperties(GVariantBuilder* builder)
{
- nux::Geometry abs_geo = GetAbsoluteGeometry();
-
unity::variant::BuilderWrapper(builder)
- .add("absolute_x", abs_geo.x)
- .add("absolute_y", abs_geo.y)
+ .add(GetAbsoluteGeometry())
.add("text", _text)
- .add("x", GetBaseX())
- .add("y", GetBaseY())
- .add("width", GetBaseWidth())
- .add("height", GetBaseHeight())
.add("enabled", GetEnabled())
.add("active", GetActive())
.add("visible", GetVisible())
- .add("lit", _prelight);
+ .add("selectable", GetSelectable())
+ .add("selected", _prelight);
}
} //NAMESPACE
diff --git a/plugins/unityshell/src/QuicklistMenuItem.h b/plugins/unityshell/src/QuicklistMenuItem.h
index 1d8615bde..abf1e09e3 100644
--- a/plugins/unityshell/src/QuicklistMenuItem.h
+++ b/plugins/unityshell/src/QuicklistMenuItem.h
@@ -85,11 +85,13 @@ public:
virtual bool GetEnabled();
virtual bool GetActive();
virtual bool GetVisible();
+ virtual bool GetSelectable();
+protected:
// Introspection
std::string GetName() const;
void AddProperties(GVariantBuilder* builder);
-protected:
+
static const int ITEM_INDENT_ABS = 16;
static const int ITEM_CORNER_RADIUS_ABS = 3;
static const int ITEM_MARGIN = 4;
@@ -116,10 +118,8 @@ protected:
void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags);
void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags);
- void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
void RecvMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags);
- void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
sigc::signal<void, QuicklistMenuItem*> sigMouseEnter;
@@ -134,7 +134,6 @@ protected:
nux::Color _color; //!< Item rendering color factor.
bool _debug;
-
bool _prelight; //!< True when the mouse is over the item.
void DrawText(nux::CairoGraphics* cairo, int width, int height, nux::Color const& color);
diff --git a/plugins/unityshell/src/QuicklistMenuItemSeparator.cpp b/plugins/unityshell/src/QuicklistMenuItemSeparator.cpp
index c2c0aa55c..2c901f506 100644
--- a/plugins/unityshell/src/QuicklistMenuItemSeparator.cpp
+++ b/plugins/unityshell/src/QuicklistMenuItemSeparator.cpp
@@ -59,6 +59,12 @@ QuicklistMenuItemSeparator::~QuicklistMenuItemSeparator()
{
}
+bool
+QuicklistMenuItemSeparator::GetSelectable()
+{
+ return false;
+}
+
void
QuicklistMenuItemSeparator::PreLayoutManagement()
{
diff --git a/plugins/unityshell/src/QuicklistMenuItemSeparator.h b/plugins/unityshell/src/QuicklistMenuItemSeparator.h
index 708460381..50987a120 100644
--- a/plugins/unityshell/src/QuicklistMenuItemSeparator.h
+++ b/plugins/unityshell/src/QuicklistMenuItemSeparator.h
@@ -43,6 +43,8 @@ public:
~QuicklistMenuItemSeparator();
+ virtual bool GetSelectable();
+
protected:
void PreLayoutManagement();
diff --git a/plugins/unityshell/src/QuicklistView.cpp b/plugins/unityshell/src/QuicklistView.cpp
index f1a3cb5ad..6d4304cf9 100644
--- a/plugins/unityshell/src/QuicklistView.cpp
+++ b/plugins/unityshell/src/QuicklistView.cpp
@@ -69,7 +69,7 @@ QuicklistView::QuicklistView()
, _bottom_padding_correction_single_item(-4)
, _offset_correction(-1)
, _cairo_text_has_changed(true)
- , _current_item_index(0)
+ , _current_item_index(-1)
{
SetGeometry(nux::Geometry(0, 0, 1, 1));
@@ -138,13 +138,35 @@ QuicklistView::RecvEndFocus()
{
}
+void
+QuicklistView::SelectItem(int index)
+{
+ CancelItemsPrelightStatus();
+ int target_item = -1;
+
+ if (IsMenuItemSelectable(index))
+ {
+ QuicklistMenuItem* menu_item = GetNthItems(index);
+
+ if (menu_item)
+ {
+ target_item = index;
+ menu_item->_prelight = true;
+ }
+ }
+
+ if (_current_item_index != target_item)
+ {
+ _current_item_index = target_item;
+ selection_change.emit();
+ QueueDraw();
+ }
+}
+
bool
-QuicklistView::IsMenuItemSeperator(int index)
+QuicklistView::IsMenuItemSelectable(int index)
{
- QuicklistMenuItem* menu_item = NULL;
- DbusmenuMenuitem* item = NULL;
- const gchar* label = NULL;
- bool result = false;
+ QuicklistMenuItem* menu_item = nullptr;
if (index < 0)
return false;
@@ -153,17 +175,7 @@ QuicklistView::IsMenuItemSeperator(int index)
if (!menu_item)
return false;
- item = menu_item->_menuItem;
- if (!item)
- return false;
-
- label = dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_LABEL);
- if (!label)
- result = true;
- else
- result = false;
-
- return result;
+ return menu_item->GetSelectable();
}
void
@@ -175,56 +187,103 @@ QuicklistView::RecvKeyPressed(unsigned long eventType,
{
switch (key_sym)
{
+ // home or page up (highlight the first menu-hitem)
+ case NUX_VK_PAGE_UP:
+ case NUX_VK_HOME:
+ {
+ int num_items = GetNumItems();
+ int target_index = -1;
+
+ do
+ {
+ ++target_index;
+ }
+ while (!IsMenuItemSelectable(target_index) && target_index < num_items);
+
+ if (target_index < num_items)
+ SelectItem(target_index);
+
+ break;
+ }
+ // end or page down (highlight the last menu-hitem)
+ case NUX_VK_PAGE_DOWN:
+ case NUX_VK_END:
+ {
+ int target_index = GetNumItems();
+
+ do
+ {
+ --target_index;
+ }
+ while (!IsMenuItemSelectable(target_index) && target_index >= 0);
+
+ if (target_index >= 0)
+ SelectItem(target_index);
+
+ break;
+ }
// up (highlight previous menu-item)
case NUX_VK_UP:
case NUX_KP_UP:
- // protect against edge-case of first item being a separator
- if (_current_item_index == 1 && IsMenuItemSeperator(0))
- break;
+ {
+ int target_index = _current_item_index;
+ bool loop_back = false;
- if (_current_item_index > 0)
- {
- GetNthItems(_current_item_index)->_prelight = false;
- _current_item_index--;
+ if (target_index <= 0)
+ target_index = GetNumItems();
- while (IsMenuItemSeperator(_current_item_index))
- _current_item_index--;
+ do
+ {
+ --target_index;
+
+ // If the first item is not selectable, we must loop from the last one
+ if (!loop_back && target_index == 0 && !IsMenuItemSelectable(target_index))
+ {
+ loop_back = true;
+ target_index = GetNumItems() - 1;
+ }
+ }
+ while (!IsMenuItemSelectable(target_index) && target_index >= 0);
- selection_change.emit();
+ if (target_index >= 0)
+ SelectItem(target_index);
- GetNthItems(_current_item_index)->_prelight = true;
- QueueDraw();
- }
break;
+ }
// down (highlight next menu-item)
case NUX_VK_DOWN:
case NUX_KP_DOWN:
- // protect against edge-case of last item being a separator
- if (_current_item_index == (GetNumItems() - 1) && IsMenuItemSeperator(GetNumItems()))
- break;
+ {
+ int target_index = _current_item_index;
+ int num_items = GetNumItems();
+ bool loop_back = false;
- if (_current_item_index < GetNumItems() - 1)
- {
- GetNthItems(_current_item_index)->_prelight = false;
- _current_item_index++;
+ if (target_index >= num_items - 1)
+ target_index = -1;
- while (IsMenuItemSeperator(_current_item_index))
- _current_item_index++;
+ do
+ {
+ ++target_index;
+
+ // If the last item is not selectable, we must loop from the first one
+ if (!loop_back && target_index == num_items - 1 && !IsMenuItemSelectable(target_index))
+ {
+ loop_back = true;
+ target_index = 0;
+ }
+ }
+ while (!IsMenuItemSelectable(target_index) && target_index < num_items);
- selection_change.emit();
+ if (target_index < num_items)
+ SelectItem(target_index);
- GetNthItems(_current_item_index)->_prelight = true;
- QueueDraw();
- }
break;
+ }
// left (close quicklist, go back to laucher key-nav)
case NUX_VK_LEFT:
case NUX_KP_LEFT:
- _current_item_index = 0;
- selection_change.emit();
- GetNthItems(_current_item_index)->_prelight = true;
Hide();
// inform Launcher we switch back to Launcher key-nav
ubus_server_send_message(ubus_server_get_default(),
@@ -234,32 +293,23 @@ QuicklistView::RecvKeyPressed(unsigned long eventType,
// esc (close quicklist, exit key-nav)
case NUX_VK_ESCAPE:
- _current_item_index = 0;
- selection_change.emit();
- GetNthItems(_current_item_index)->_prelight = true;
Hide();
// inform UnityScreen we leave key-nav completely
ubus_server_send_message(ubus_server_get_default(),
UBUS_LAUNCHER_END_KEY_NAV,
NULL);
- selection_change.emit();
break;
// <SPACE>, <RETURN> (activate selected menu-item)
case NUX_VK_SPACE:
case NUX_VK_ENTER:
case NUX_KP_ENTER:
- if (_current_item_index >= 0 && _current_item_index < GetNumItems() &&
- GetNthItems(_current_item_index)->GetEnabled())
+ if (IsMenuItemSelectable(_current_item_index))
{
-
dbusmenu_menuitem_handle_event(GetNthItems(_current_item_index)->_menuItem,
"clicked",
NULL,
0);
- _current_item_index = 0;
- selection_change.emit();
- GetNthItems(_current_item_index)->_prelight = true;
Hide();
}
break;
@@ -365,6 +415,12 @@ void QuicklistView::Hide()
UnGrabKeyboard();
//EnableInputWindow (false);
ShowWindow(false);
+
+ if (_current_item_index != -1)
+ {
+ selection_change.emit();
+ _current_item_index = -1;
+ }
}
}
@@ -618,54 +674,53 @@ void QuicklistView::CancelItemsPrelightStatus()
void QuicklistView::RecvItemMouseDrag(QuicklistMenuItem* item, int x, int y)
{
nux::Geometry geo;
- std::list<QuicklistMenuItem*>::iterator it;
- for (it = _item_list.begin(); it != _item_list.end(); it++)
+
+ for (auto it : _item_list)
{
- if (!(*it)->GetVisible())
+ int item_index = GetItemIndex(it);
+
+ if (!IsMenuItemSelectable(item_index))
continue;
- geo = (*it)->GetGeometry();
+ geo = it->GetGeometry();
geo.width = _item_layout->GetBaseWidth();
if (geo.IsPointInside(x + item->GetBaseX(), y + item->GetBaseY()))
{
- (*it)->_prelight = true;
- }
- else
- {
- (*it)->_prelight = false;
+ SelectItem(item_index);
}
}
- for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
+ for (auto it : _default_item_list)
{
- if (!(*it)->GetVisible())
+ int item_index = GetItemIndex(it);
+
+ if (!IsMenuItemSelectable(item_index))
continue;
- geo = (*it)->GetGeometry();
+ geo = it->GetGeometry();
geo.width = _default_item_layout->GetBaseWidth();
if (geo.IsPointInside(x + item->GetBaseX(), y + item->GetBaseY()))
{
- (*it)->_prelight = true;
- }
- else
- {
- (*it)->_prelight = false;
+ SelectItem(item_index);
}
}
-
- NeedRedraw();
}
void QuicklistView::RecvItemMouseEnter(QuicklistMenuItem* item)
{
- NeedRedraw();
+ int item_index = GetItemIndex(item);
+
+ SelectItem(item_index);
}
void QuicklistView::RecvItemMouseLeave(QuicklistMenuItem* item)
{
- NeedRedraw();
+ int item_index = GetItemIndex(item);
+
+ if (item_index < 0 || item_index == _current_item_index)
+ SelectItem(-1);
}
void QuicklistView::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
@@ -786,14 +841,37 @@ QuicklistMenuItem* QuicklistView::GetNthItems(int index)
if (_item_list.size() > 0)
i = _item_list.size() - 1;
std::list<QuicklistMenuItem*>::iterator it;
- for (it = _item_list.begin(); it != _item_list.end(); i++, it++)
+ for (it = _default_item_list.begin(); it != _default_item_list.end(); i++, it++)
{
if (i == index)
return *it;
}
}
- return 0;
+ return nullptr;
+}
+
+int QuicklistView::GetItemIndex(QuicklistMenuItem* item)
+{
+ int index = -1;
+
+ for (auto it : _item_list)
+ {
+ ++index;
+
+ if (it == item)
+ return index;
+ }
+
+ for (auto it : _default_item_list)
+ {
+ ++index;
+
+ if (it == item)
+ return index;
+ }
+
+ return index;
}
QuicklistMenuItemType QuicklistView::GetNthType(int index)
@@ -801,6 +879,7 @@ QuicklistMenuItemType QuicklistView::GetNthType(int index)
QuicklistMenuItem* item = GetNthItems(index);
if (item)
return item->GetItemType();
+
return MENUITEM_TYPE_UNKNOWN;
}
@@ -809,13 +888,9 @@ std::list<QuicklistMenuItem*> QuicklistView::GetChildren()
return _item_list;
}
-void QuicklistView::DefaultToFirstItem()
+void QuicklistView::SelectFirstItem()
{
- if (GetNumItems() >= 1)
- {
- GetNthItems(0)->_prelight = true;
- QueueDraw();
- }
+ SelectItem(0);
}
void ql_tint_dot_hl(cairo_t* cr,
@@ -1400,15 +1475,10 @@ std::string QuicklistView::GetName() const
void QuicklistView::AddProperties(GVariantBuilder* builder)
{
- nux::Geometry abs_geo = GetAbsoluteGeometry();
-
variant::BuilderWrapper(builder)
- .add("x", abs_geo.x)
- .add("y", abs_geo.y)
+ .add(GetAbsoluteGeometry())
.add("base_x", GetBaseX())
.add("base_y", GetBaseY())
- .add("width", GetBaseWidth())
- .add("height", GetBaseHeight())
.add("active", IsVisible());
}
diff --git a/plugins/unityshell/src/QuicklistView.h b/plugins/unityshell/src/QuicklistView.h
index fd60d20a8..d1433b94a 100644
--- a/plugins/unityshell/src/QuicklistView.h
+++ b/plugins/unityshell/src/QuicklistView.h
@@ -62,8 +62,9 @@ public:
int GetNumItems();
QuicklistMenuItem* GetNthItems(int index);
QuicklistMenuItemType GetNthType(int index);
+ int GetItemIndex(QuicklistMenuItem* item);
std::list<QuicklistMenuItem*> GetChildren();
- void DefaultToFirstItem();
+ void SelectFirstItem();
void TestMenuItems(DbusmenuMenuitem* root);
@@ -130,7 +131,8 @@ private:
//! Check the mouse up event sent by an item. Detect the item where the mous is and emit the appropriate signal.
void CheckAndEmitItemSignal(int x, int y);
- bool IsMenuItemSeperator(int index);
+ void SelectItem(int index);
+ bool IsMenuItemSelectable(int index);
//nux::CairoGraphics* _cairo_graphics;
int _anchorX;
diff --git a/plugins/unityshell/src/ResultRendererTile.cpp b/plugins/unityshell/src/ResultRendererTile.cpp
index aa7d75243..0560838ab 100644
--- a/plugins/unityshell/src/ResultRendererTile.cpp
+++ b/plugins/unityshell/src/ResultRendererTile.cpp
@@ -95,7 +95,7 @@ void ResultRendererTile::Render(nux::GraphicsEngine& GfxContext,
int x_offset, int y_offset)
{
TextureContainer* container = row.renderer<TextureContainer*>();
- if (container == nullptr || container->icon == nullptr)
+ if (container == nullptr)
return;
dash::Style& style = dash::Style::Instance();
@@ -104,8 +104,19 @@ void ResultRendererTile::Render(nux::GraphicsEngine& GfxContext,
// set up our texture mode
nux::TexCoordXForm texxform;
- int icon_left_hand_side = geometry.x + (geometry.width - container->icon->GetWidth()) / 2;
- int icon_top_side = geometry.y + padding + ((tile_icon_size - container->icon->GetHeight()) / 2);
+ int icon_width, icon_height;
+ if (container->icon == nullptr)
+ {
+ icon_width = icon_height = tile_icon_size;
+ }
+ else
+ {
+ icon_width = container->icon->GetWidth();
+ icon_height = container->icon->GetHeight();
+ }
+
+ int icon_left_hand_side = geometry.x + (geometry.width - icon_width) / 2;
+ int icon_top_side = geometry.y + padding + (tile_icon_size - icon_height) / 2;
if (container->blurred_icon && state == ResultRendererState::RESULT_RENDERER_NORMAL)
{
@@ -312,7 +323,6 @@ nux::BaseTexture* ResultRendererTile::CreateTextureCallback(std::string const& t
pixbuf_width = style.GetTileWidth() - (padding * 2);
pixbuf_height = pixbuf_width * aspect;
-
if (pixbuf_height > height)
{
// scaled too big, scale down
@@ -326,13 +336,19 @@ nux::BaseTexture* ResultRendererTile::CreateTextureCallback(std::string const& t
pixbuf_width = pixbuf_height / aspect;
}
+ if (gdk_pixbuf_get_height(pixbuf) == pixbuf_height)
+ {
+ // we changed our mind, fast path is good
+ return nux::CreateTexture2DFromPixbuf(pixbuf, true);
+ }
+
nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, pixbuf_width, pixbuf_height);
cairo_t* cr = cairo_graphics.GetInternalContext();
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
- float scale = gdk_pixbuf_get_height(pixbuf) / float(pixbuf_height);
+ float scale = float(pixbuf_height) / gdk_pixbuf_get_height(pixbuf);
//cairo_translate(cr,
// static_cast<int>((width - (pixbuf_width * scale)) * 0.5),
diff --git a/plugins/unityshell/src/ResultViewGrid.cpp b/plugins/unityshell/src/ResultViewGrid.cpp
index af75f86b0..4acfd144b 100644
--- a/plugins/unityshell/src/ResultViewGrid.cpp
+++ b/plugins/unityshell/src/ResultViewGrid.cpp
@@ -55,6 +55,7 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
, preview_row_(0)
, last_lazy_loaded_result_ (0)
, lazy_load_handle_(0)
+ , view_changed_handle_(0)
, last_mouse_down_x_(-1)
, last_mouse_down_y_(-1)
, recorded_dash_width_(-1)
@@ -107,12 +108,17 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
ResultViewGrid::~ResultViewGrid()
{
- g_source_remove(lazy_load_handle_);
+ if (lazy_load_handle_)
+ g_source_remove(lazy_load_handle_);
+
+ if (view_changed_handle_)
+ g_source_remove(view_changed_handle_);
}
gboolean ResultViewGrid::OnLazyLoad (gpointer data)
{
ResultViewGrid *self = (ResultViewGrid*)data;
+ self->lazy_load_handle_ = 0;
self->DoLazyLoad();
return FALSE;
}
@@ -126,9 +132,26 @@ void ResultViewGrid::QueueLazyLoad()
last_lazy_loaded_result_ = 0; // we always want to reset the lazy load index here
}
+void ResultViewGrid::QueueViewChanged()
+{
+ if (view_changed_handle_ == 0)
+ {
+ // using G_PRIORITY_HIGH because this needs to happen *before* next draw
+ view_changed_handle_ = g_idle_add_full (G_PRIORITY_HIGH,
+ [](gpointer data) -> gboolean
+ {
+ ResultViewGrid *self = (ResultViewGrid*)data;
+ self->SizeReallocate();
+ self->last_lazy_loaded_result_ = 0; // reset the lazy load index
+ self->DoLazyLoad(); // also calls QueueDraw
+ self->view_changed_handle_ = 0;
+ return FALSE;
+ }, this, NULL);
+ }
+}
+
void ResultViewGrid::DoLazyLoad()
{
- lazy_load_handle_ = 0;
// FIXME - so this code was nice, it would only load the visible entries on the screen
// however nux does not give us a good enough indicator right now that we are scrolling,
// thus if you scroll more than a screen in one frame, you will end up with at least one frame where
@@ -190,7 +213,7 @@ void ResultViewGrid::DoLazyLoad()
int ResultViewGrid::GetItemsPerRow()
{
- int items_per_row = (GetGeometry().width - (padding * 2)) / (renderer_->width + horizontal_spacing);
+ int items_per_row = (GetGeometry().width - (padding * 2) + horizontal_spacing) / (renderer_->width + horizontal_spacing);
return (items_per_row) ? items_per_row : 1; // always at least one item per row
}
@@ -235,17 +258,13 @@ void ResultViewGrid::SetModelRenderer(ResultRenderer* renderer)
void ResultViewGrid::AddResult(Result& result)
{
results_.push_back(result);
-
- SizeReallocate();
- QueueLazyLoad();
- NeedRedraw();
+ QueueViewChanged();
}
void ResultViewGrid::RemoveResult(Result& result)
{
ResultView::RemoveResult(result);
- SizeReallocate();
- QueueLazyLoad();
+ QueueViewChanged();
}
void ResultViewGrid::SizeReallocate()
@@ -267,7 +286,7 @@ void ResultViewGrid::SizeReallocate()
}
else
{
- total_height = renderer_->height;
+ total_height = renderer_->height + vertical_spacing;
}
int width = (items_per_row * renderer_->width) + (padding*2) + ((items_per_row - 1) * horizontal_spacing);
@@ -564,7 +583,6 @@ long ResultViewGrid::ComputeContentSize()
QueueLazyLoad();
long ret = ResultView::ComputeContentSize();
return ret;
-
}
diff --git a/plugins/unityshell/src/ResultViewGrid.h b/plugins/unityshell/src/ResultViewGrid.h
index 0f7b9ce68..03d168584 100644
--- a/plugins/unityshell/src/ResultViewGrid.h
+++ b/plugins/unityshell/src/ResultViewGrid.h
@@ -78,8 +78,9 @@ private:
typedef std::tuple <int, int> ResultListBounds;
ResultListBounds GetVisableResults();
- static gboolean OnLazyLoad (gpointer data);
+ static gboolean OnLazyLoad(gpointer data);
void QueueLazyLoad();
+ void QueueViewChanged();
void DoLazyLoad();
int GetItemsPerRow();
@@ -94,7 +95,8 @@ private:
std::string focused_uri_;
int last_lazy_loaded_result_;
- uint lazy_load_handle_;
+ unsigned lazy_load_handle_;
+ unsigned view_changed_handle_;
int last_mouse_down_x_;
int last_mouse_down_y_;
std::string current_drag_uri_;
diff --git a/plugins/unityshell/src/SearchBar.cpp b/plugins/unityshell/src/SearchBar.cpp
index 5a4a5bc07..032ce4dea 100644
--- a/plugins/unityshell/src/SearchBar.cpp
+++ b/plugins/unityshell/src/SearchBar.cpp
@@ -126,6 +126,8 @@ SearchBar::SearchBar(NUX_FILE_LINE_DECL)
, show_filter_hint_(true)
, expander_view_(nullptr)
, show_filters_(nullptr)
+ , last_width_(-1)
+ , last_height_(-1)
, live_search_timeout_(0)
, start_spinner_timeout_(0)
{
@@ -140,6 +142,8 @@ SearchBar::SearchBar(bool show_filter_hint_, NUX_FILE_LINE_DECL)
, show_filter_hint_(show_filter_hint_)
, expander_view_(nullptr)
, show_filters_(nullptr)
+ , last_width_(-1)
+ , last_height_(-1)
, live_search_timeout_(0)
, start_spinner_timeout_(0)
{
@@ -516,7 +520,7 @@ void SearchBar::UpdateBackground(bool force)
{
int RADIUS = 5;
nux::Geometry geo(GetGeometry());
- geo.width = layered_layout_->GetAbsoluteX() +
+ geo.width = layered_layout_->GetAbsoluteX() +
layered_layout_->GetAbsoluteWidth() -
GetAbsoluteX() +
SEARCH_ENTRY_RIGHT_BORDER;
@@ -661,7 +665,8 @@ void SearchBar::AddProperties(GVariantBuilder* builder)
.add("filter-label-x", show_filters_->GetAbsoluteX())
.add("filter-label-y", show_filters_->GetAbsoluteY())
.add("filter-label-width", show_filters_->GetAbsoluteWidth())
- .add("filter-label-height", show_filters_->GetAbsoluteHeight());
+ .add("filter-label-height", show_filters_->GetAbsoluteHeight())
+ .add("im_active", pango_entry_->im_active());
}
} // namespace unity
diff --git a/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp b/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp
index 8932c9007..915063252 100644
--- a/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp
+++ b/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp
@@ -46,15 +46,7 @@ SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(BamfApplication* app,
{
aptdaemon_trans_.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged));
- aptdaemon_trans_.Connect("Finished", [&] (GVariant *)
- {
- tooltip_text = BamfName();
- SetQuirk(QUIRK_PROGRESS, false);
- SetQuirk(QUIRK_URGENT, true);
- SetProgress(0.0f);
- finished_ = true;
- needs_urgent_ = true;
- });
+ aptdaemon_trans_.Connect("Finished", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnFinished));
SetIconType(TYPE_APPLICATION);
icon_name = icon_path;
@@ -130,6 +122,25 @@ void SoftwareCenterLauncherIcon::ActivateLauncherIcon(ActionArg arg)
SetQuirk(QUIRK_STARTING, false);
}
+void SoftwareCenterLauncherIcon::OnFinished(GVariant *params)
+{
+ glib::String exit_state;
+ g_variant_get_child(params, 0, "s", &exit_state);
+
+ if (exit_state.Str() == "exit-success")
+ {
+ tooltip_text = BamfName();
+ SetQuirk(QUIRK_PROGRESS, false);
+ SetQuirk(QUIRK_URGENT, true);
+ SetProgress(0.0f);
+ finished_ = true;
+ needs_urgent_ = true;
+ } else {
+ // failure condition, remove icon again
+ UnStick();
+ }
+};
+
void SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params)
{
gint32 progress;
diff --git a/plugins/unityshell/src/SoftwareCenterLauncherIcon.h b/plugins/unityshell/src/SoftwareCenterLauncherIcon.h
index e71eaac34..3f40e6af2 100644
--- a/plugins/unityshell/src/SoftwareCenterLauncherIcon.h
+++ b/plugins/unityshell/src/SoftwareCenterLauncherIcon.h
@@ -51,6 +51,7 @@ protected:
private:
void OnPropertyChanged(GVariant* params);
+ void OnFinished(GVariant *params);
void OnDragAnimationFinished();
glib::DBusProxy aptdaemon_trans_;
diff --git a/plugins/unityshell/src/StaticCairoText.cpp b/plugins/unityshell/src/StaticCairoText.cpp
index 06094f994..80dbddbc1 100644
--- a/plugins/unityshell/src/StaticCairoText.cpp
+++ b/plugins/unityshell/src/StaticCairoText.cpp
@@ -377,11 +377,11 @@ void StaticCairoText::GetTextExtents(const TCHAR* font,
// logRect has some issues using italic style
if (inkRect.x + inkRect.width > logRect.x + logRect.width)
- width = (inkRect.x + inkRect.width - logRect.x) /PANGO_SCALE;
+ width = std::ceil(static_cast<float>(inkRect.x + inkRect.width - logRect.x) / PANGO_SCALE);
else
- width = logRect.width / PANGO_SCALE;
+ width = std::ceil(static_cast<float>(logRect.width) / PANGO_SCALE);
- height = logRect.height / PANGO_SCALE;
+ height = std::ceil(static_cast<float>(logRect.height) / PANGO_SCALE);
_cached_extent_height = height;
_cached_extent_width = width;
_baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
diff --git a/plugins/unityshell/src/SwitcherController.cpp b/plugins/unityshell/src/SwitcherController.cpp
index 97fa7c7da..eb62245b1 100644
--- a/plugins/unityshell/src/SwitcherController.cpp
+++ b/plugins/unityshell/src/SwitcherController.cpp
@@ -439,6 +439,12 @@ bool Controller::CompareSwitcherItemsPriority(AbstractLauncherIcon::Ptr first,
{
if (first->GetIconType() == second->GetIconType())
return first->SwitcherPriority() > second->SwitcherPriority();
+
+ if (first->GetIconType() == AbstractLauncherIcon::IconType::TYPE_DESKTOP)
+ return true;
+
+ if (second->GetIconType() == AbstractLauncherIcon::IconType::TYPE_DESKTOP)
+ return false;
return first->GetIconType() < second->GetIconType();
}
diff --git a/plugins/unityshell/src/TrashLauncherIcon.cpp b/plugins/unityshell/src/TrashLauncherIcon.cpp
index 105d3a2e4..057af3baa 100644
--- a/plugins/unityshell/src/TrashLauncherIcon.cpp
+++ b/plugins/unityshell/src/TrashLauncherIcon.cpp
@@ -158,12 +158,18 @@ void TrashLauncherIcon::OnTrashChanged(GFileMonitor* monitor,
}
-nux::DndAction TrashLauncherIcon::OnQueryAcceptDrop(unity::DndData& dnd_data)
+nux::DndAction TrashLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)
{
return nux::DNDACTION_MOVE;
}
-void TrashLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data)
+bool TrashLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
+{
+ return true;
+}
+
+
+void TrashLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
{
for (auto it : dnd_data.Uris())
{
diff --git a/plugins/unityshell/src/TrashLauncherIcon.h b/plugins/unityshell/src/TrashLauncherIcon.h
index cce3569e8..cf7e9277d 100644
--- a/plugins/unityshell/src/TrashLauncherIcon.h
+++ b/plugins/unityshell/src/TrashLauncherIcon.h
@@ -42,8 +42,10 @@ public:
protected:
void UpdateTrashIcon();
- nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data);
- void OnAcceptDrop(unity::DndData& dnd_data);
+ nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data);
+ bool OnShouldHighlightOnDrag(DndData const& dnd_data);
+ void OnAcceptDrop(DndData const& dnd_data);
+
std::string GetName() const;
private:
diff --git a/plugins/unityshell/src/UBusMessages.h b/plugins/unityshell/src/UBusMessages.h
index 25f9e6595..66b7faef5 100644
--- a/plugins/unityshell/src/UBusMessages.h
+++ b/plugins/unityshell/src/UBusMessages.h
@@ -90,7 +90,4 @@
#define UBUS_SWITCHER_SHOWN "SWITCHER_SHOWN"
#define UBUS_SWITCHER_SELECTION_CHANGED "SWITCHER_SELECTION_CHANGED"
-// Signal sent when someone thinks the decoration might got damanged by a paint
-#define UBUS_DASH_DECORATION_DAMAGED "DASH_DECORATION_DAMAGED"
-
#endif // UBUS_MESSAGES_H
diff --git a/plugins/unityshell/src/UScreen.cpp b/plugins/unityshell/src/UScreen.cpp
index ff68baa29..1e2e62483 100644
--- a/plugins/unityshell/src/UScreen.cpp
+++ b/plugins/unityshell/src/UScreen.cpp
@@ -17,47 +17,51 @@
*/
#include "UScreen.h"
+#include <NuxCore/Logger.h>
-static UScreen* _default_screen = NULL;
+namespace unity
+{
-UScreen::UScreen()
- : _refresh_id(0)
+namespace
{
- GdkScreen* screen;
+static UScreen* default_screen_ = nullptr;
+nux::logging::Logger logger("unity.screen");
+}
- screen = gdk_screen_get_default();
- g_signal_connect(screen, "size-changed",
- (GCallback)UScreen::Changed, this);
- g_signal_connect(screen, "monitors-changed",
- (GCallback)UScreen::Changed, this);
+UScreen::UScreen()
+ : screen_(gdk_screen_get_default(), glib::AddRef())
+ , proxy_("org.freedesktop.UPower",
+ "/org/freedesktop/UPower",
+ "org.freedesktop.UPower",
+ G_BUS_TYPE_SYSTEM)
+ , refresh_id_(0)
+ , primary_(0)
+{
+ size_changed_signal_.Connect(screen_, "size-changed", sigc::mem_fun(this, &UScreen::Changed));
+ monitors_changed_signal_.Connect(screen_, "monitors-changed", sigc::mem_fun(this, &UScreen::Changed));
+ proxy_.Connect("Resuming", [&] (GVariant* data) { resuming.emit(); });
Refresh();
-
- proxy_ = unity::glib::DBusProxy::Ptr(new unity::glib::DBusProxy("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", G_BUS_TYPE_SYSTEM));
- proxy_->Connect("Resuming", [&](GVariant* data) -> void { resuming.emit(); });
}
UScreen::~UScreen()
{
- if (_default_screen == this)
- _default_screen = NULL;
+ if (default_screen_ == this)
+ default_screen_ = nullptr;
- g_signal_handlers_disconnect_by_func((gpointer)gdk_screen_get_default(),
- (gpointer)UScreen::Changed,
- (gpointer)this);
+ if (refresh_id_ != 0)
+ g_source_remove(refresh_id_);
}
-UScreen*
-UScreen::GetDefault()
+UScreen* UScreen::GetDefault()
{
- if (G_UNLIKELY(!_default_screen))
- _default_screen = new UScreen();
+ if (G_UNLIKELY(!default_screen_))
+ default_screen_ = new UScreen();
- return _default_screen;
+ return default_screen_;
}
-int
-UScreen::GetMonitorWithMouse()
+int UScreen::GetMonitorWithMouse()
{
GdkDevice* device;
GdkDisplay *display;
@@ -67,87 +71,71 @@ UScreen::GetMonitorWithMouse()
display = gdk_display_get_default();
device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(display));
- gdk_device_get_position(device, NULL, &x, &y);
+ gdk_device_get_position(device, nullptr, &x, &y);
return GetMonitorAtPosition(x, y);
}
-int
-UScreen::GetPrimaryMonitor()
+int UScreen::GetPrimaryMonitor()
{
return primary_;
}
-int
-UScreen::GetMonitorAtPosition(int x, int y)
+int UScreen::GetMonitorAtPosition(int x, int y)
{
- GdkScreen* screen = gdk_screen_get_default();
-
- return gdk_screen_get_monitor_at_point(screen, x, y);
+ return gdk_screen_get_monitor_at_point(screen_, x, y);
}
-nux::Geometry&
-UScreen::GetMonitorGeometry(int monitor)
+nux::Geometry& UScreen::GetMonitorGeometry(int monitor)
{
- return _monitors[monitor];
+ return monitors_[monitor];
}
-std::vector<nux::Geometry>&
-UScreen::GetMonitors()
+std::vector<nux::Geometry>& UScreen::GetMonitors()
{
- return _monitors;
+ return monitors_;
}
-void
-UScreen::Changed(GdkScreen* screen, UScreen* self)
+void UScreen::Changed(GdkScreen* screen)
{
- if (self->_refresh_id)
+ if (refresh_id_)
return;
- self->_refresh_id = g_idle_add((GSourceFunc)UScreen::OnIdleChanged, self);
-}
-
-gboolean
-UScreen::OnIdleChanged(UScreen* self)
-{
- self->_refresh_id = 0;
- self->Refresh();
+ refresh_id_ = g_idle_add([] (gpointer data) -> gboolean {
+ auto self = static_cast<UScreen*>(data);
+ self->refresh_id_ = 0;
+ self->Refresh();
- return FALSE;
+ return FALSE;
+ }, this);
}
-void
-UScreen::Refresh()
+void UScreen::Refresh()
{
- GdkScreen* screen;
- nux::Geometry last_geo(0, 0, 1, 1);
+ LOG_DEBUG(logger) << "Screen geometry changed";
- screen = gdk_screen_get_default();
+ nux::Geometry last_geo;
+ monitors_.clear();
+ primary_ = gdk_screen_get_primary_monitor(screen_);
- _monitors.erase(_monitors.begin(), _monitors.end());
-
- g_print("\nScreen geometry changed:\n");
-
- primary_ = gdk_screen_get_primary_monitor(screen);
- for (int i = 0; i < gdk_screen_get_n_monitors(screen); i++)
+ for (int i = 0; i < gdk_screen_get_n_monitors(screen_); i++)
{
GdkRectangle rect = { 0 };
-
- gdk_screen_get_monitor_geometry(screen, i, &rect);
-
+ gdk_screen_get_monitor_geometry(screen_, i, &rect);
nux::Geometry geo(rect.x, rect.y, rect.width, rect.height);
// Check for mirrored displays
if (geo == last_geo)
continue;
- last_geo = geo;
- _monitors.push_back(geo);
+ last_geo = geo;
+ monitors_.push_back(geo);
- g_print(" %dx%dx%dx%d\n", geo.x, geo.y, geo.width, geo.height);
+ LOG_DEBUG(logger) << "Monitor " << i << " has geometry " << geo.x << "x"
+ << geo.y << "x" << geo.width << "x" << geo.height;
}
- g_print("\n");
-
- changed.emit(primary_, _monitors);
+ changed.emit(primary_, monitors_);
}
+
+} // Namespace
diff --git a/plugins/unityshell/src/UScreen.h b/plugins/unityshell/src/UScreen.h
index 7bd755107..6e350209d 100644
--- a/plugins/unityshell/src/UScreen.h
+++ b/plugins/unityshell/src/UScreen.h
@@ -24,7 +24,12 @@
#include <sigc++/sigc++.h>
#include <vector>
-#include "UnityCore/GLibDBusProxy.h"
+#include <UnityCore/GLibSignal.h>
+#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/GLibDBusProxy.h>
+
+namespace unity
+{
class UScreen : public sigc::trackable
{
@@ -43,19 +48,21 @@ public:
// <void, primary_monitor, monitors>
sigc::signal<void, int, std::vector<nux::Geometry>&> changed;
-
sigc::signal<void> resuming;
private:
- static void Changed(GdkScreen* screen, UScreen* self);
- static gboolean OnIdleChanged(UScreen* self);
- void Refresh();
+ void Changed(GdkScreen* screen);
+ void Refresh();
private:
- std::vector<nux::Geometry> _monitors;
- guint32 _refresh_id;
+ std::vector<nux::Geometry> monitors_;
+ glib::Object<GdkScreen> screen_;
+ glib::DBusProxy proxy_;
+ glib::Signal<void, GdkScreen*> size_changed_signal_;
+ glib::Signal<void, GdkScreen*> monitors_changed_signal_;
+ guint refresh_id_;
int primary_;
- unity::glib::DBusProxy::Ptr proxy_;
};
+} // Namespace
#endif // _UNITY_SCREEN_H_
diff --git a/plugins/unityshell/src/UnityShowdesktopHandler.cpp b/plugins/unityshell/src/UnityShowdesktopHandler.cpp
index 6d17c89a0..d34ecf11d 100644
--- a/plugins/unityshell/src/UnityShowdesktopHandler.cpp
+++ b/plugins/unityshell/src/UnityShowdesktopHandler.cpp
@@ -51,7 +51,7 @@ bool ShowdesktopHandler::ShouldHide (ShowdesktopHandlerWindowInterface *wi)
return false;
if (wi->Hidden())
- if ((wi->ShowDesktopMode() || wi->Shaded()))
+ if ((wi->ShowDesktopMode() || wi->Shaded() || wi->Minimized()))
return false;
return true;
@@ -79,9 +79,10 @@ ShowdesktopHandler::InhibitingXid()
return inhibiting_xid;
}
-ShowdesktopHandler::ShowdesktopHandler (ShowdesktopHandlerWindowInterface *wi) :
+ShowdesktopHandler::ShowdesktopHandler (ShowdesktopHandlerWindowInterface *wi, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire_interface) :
showdesktop_handler_window_interface_ (wi),
- remover_ (wi->InputRemover()),
+ lock_acquire_interface_ (lock_acquire_interface),
+ remover_(),
state_ (StateVisible),
progress_ (0.0f)
{
@@ -105,8 +106,7 @@ void ShowdesktopHandler::FadeOut()
{
showdesktop_handler_window_interface_->Hide();
showdesktop_handler_window_interface_->NotifyHidden();
- remover_->save();
- remover_->remove();
+ remover_ = lock_acquire_interface_->InputRemover();
if (std::find (animating_windows.begin(),
animating_windows.end(),
@@ -127,7 +127,7 @@ void ShowdesktopHandler::FadeIn()
{
showdesktop_handler_window_interface_->Show();
showdesktop_handler_window_interface_->NotifyShown();
- remover_->restore();
+ remover_.reset();
if (std::find (animating_windows.begin(),
animating_windows.end(),
@@ -184,8 +184,7 @@ void ShowdesktopHandler::HandleShapeEvent()
/* Ignore sent events from the InputRemover */
if (remover_)
{
- remover_->save();
- remover_->remove();
+ remover_->refresh();
}
}
diff --git a/plugins/unityshell/src/UnityShowdesktopHandler.h b/plugins/unityshell/src/UnityShowdesktopHandler.h
index 72283bbbb..820fdafd4 100644
--- a/plugins/unityshell/src/UnityShowdesktopHandler.h
+++ b/plugins/unityshell/src/UnityShowdesktopHandler.h
@@ -71,8 +71,6 @@ class ShowdesktopHandlerWindowInterface
unsigned int NoCoreInstanceMask () { return GetNoCoreInstanceMask (); }
- compiz::WindowInputRemoverInterface::Ptr InputRemover () { return GetInputRemover (); }
-
private:
virtual void DoEnableFocus () = 0;
@@ -104,15 +102,13 @@ class ShowdesktopHandlerWindowInterface
virtual void DoDeleteHandler () = 0;
virtual unsigned int GetNoCoreInstanceMask () = 0;
-
- virtual compiz::WindowInputRemoverInterface::Ptr GetInputRemover () = 0;
};
class ShowdesktopHandler
{
public:
- ShowdesktopHandler (ShowdesktopHandlerWindowInterface *uwi);
+ ShowdesktopHandler (ShowdesktopHandlerWindowInterface *uwi, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire_interface);
~ShowdesktopHandler ();
typedef enum {
@@ -145,7 +141,8 @@ public:
private:
ShowdesktopHandlerWindowInterface *showdesktop_handler_window_interface_;
- compiz::WindowInputRemoverInterface::Ptr remover_;
+ compiz::WindowInputRemoverLockAcquireInterface *lock_acquire_interface_;
+ compiz::WindowInputRemoverLock::Ptr remover_;
ShowdesktopHandler::State state_;
float progress_;
bool was_hidden_;
diff --git a/plugins/unityshell/src/WindowButtons.cpp b/plugins/unityshell/src/WindowButtons.cpp
index 7d4a5faf0..2824c77f2 100644
--- a/plugins/unityshell/src/WindowButtons.cpp
+++ b/plugins/unityshell/src/WindowButtons.cpp
@@ -530,6 +530,9 @@ void WindowButtons::OnOverlayShown(GVariant* data)
if (button)
{
+ if (button->GetType() == panel::WindowButtonType::CLOSE)
+ button->SetEnabled(true);
+
if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
restore_button = button;
@@ -596,6 +599,21 @@ void WindowButtons::OnOverlayHidden(GVariant* data)
if (button)
{
+ if (window_xid_)
+ {
+ if (button->GetType() == panel::WindowButtonType::CLOSE)
+ {
+ bool closable = WindowManager::Default()->IsWindowClosable(window_xid_);
+ button->SetEnabled(closable);
+ }
+
+ if (button->GetType() == panel::WindowButtonType::MINIMIZE)
+ {
+ bool minimizable = WindowManager::Default()->IsWindowMinimizable(window_xid_);
+ button->SetEnabled(minimizable);
+ }
+ }
+
if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
restore_button = button;
@@ -721,15 +739,26 @@ void WindowButtons::SetControlledWindow(Window xid)
{
window_xid_ = xid;
- for (auto area : GetChildren())
+ if (window_xid_ && active_overlay_.empty())
{
- auto button = dynamic_cast<WindowButton*>(area);
-
- if (button->GetType() == panel::WindowButtonType::MINIMIZE)
+ for (auto area : GetChildren())
{
- bool minimizable = WindowManager::Default()->IsWindowMinimizable(xid);
- button->SetEnabled(minimizable);
- break;
+ auto button = dynamic_cast<WindowButton*>(area);
+
+ if (!button)
+ continue;
+
+ if (button->GetType() == panel::WindowButtonType::CLOSE)
+ {
+ bool closable = WindowManager::Default()->IsWindowClosable(xid);
+ button->SetEnabled(closable);
+ }
+
+ if (button->GetType() == panel::WindowButtonType::MINIMIZE)
+ {
+ bool minimizable = WindowManager::Default()->IsWindowMinimizable(xid);
+ button->SetEnabled(minimizable);
+ }
}
}
}
diff --git a/plugins/unityshell/src/WindowManager.cpp b/plugins/unityshell/src/WindowManager.cpp
index c851d79e1..cde2dc149 100644
--- a/plugins/unityshell/src/WindowManager.cpp
+++ b/plugins/unityshell/src/WindowManager.cpp
@@ -78,11 +78,26 @@ class WindowManagerDummy : public WindowManager
return true;
}
+ bool IsWindowOnTop(guint32 xid)
+ {
+ return false;
+ }
+
+ bool IsWindowClosable(guint32 xid)
+ {
+ return true;
+ }
+
bool IsWindowMinimizable(guint32 xid)
{
return true;
}
+ bool IsWindowMaximizable(guint32 xid)
+ {
+ return true;
+ }
+
void Restore(guint32 xid)
{
g_debug("%s", G_STRFUNC);
@@ -204,6 +219,10 @@ class WindowManagerDummy : public WindowManager
{
g_debug("%s", G_STRFUNC);
}
+
+ void AddProperties(GVariantBuilder* builder)
+ {
+ }
};
WindowManager*
@@ -221,6 +240,11 @@ WindowManager::SetDefault(WindowManager* manager)
window_manager = manager;
}
+std::string WindowManager::GetName() const
+{
+ return "WindowManager";
+}
+
#define NET_WM_MOVERESIZE_MOVE 8
void WindowManager::StartMove(guint32 xid, int x, int y)
diff --git a/plugins/unityshell/src/WindowManager.h b/plugins/unityshell/src/WindowManager.h
index 735956226..4e74b022a 100644
--- a/plugins/unityshell/src/WindowManager.h
+++ b/plugins/unityshell/src/WindowManager.h
@@ -19,24 +19,18 @@
#ifndef WINDOW_MANAGER_H
#define WINDOW_MANAGER_H
-#include <glib.h>
-#include <sigc++/sigc++.h>
#include <Nux/Nux.h>
-#include <Nux/WindowThread.h>
-#include <NuxGraphics/GLWindowManager.h>
#include <gdk/gdkx.h>
#include <core/core.h>
-class WindowManager
+#include "Introspectable.h"
+
+class WindowManager : public unity::debug::Introspectable
{
// This is a glue interface that breaks the dependancy of Unity with Compiz
// Basically it has a default implementation that does nothing useful, but
// the idea is that unity.cpp uses SetDefault() early enough in it's
// initialization so the things that require it get a usable implementation
- //
- // Currently only the Panel uses it but hopefully we'll get more of
- // PluginAdaptor features moved into here and also get the Launcher to use
- // it.
public:
WindowManager() :
@@ -63,7 +57,10 @@ 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;
virtual void ShowDesktop() = 0;
@@ -140,6 +137,10 @@ public:
sigc::signal<void, const char*, const char*, CompOption::Vector&> compiz_event;
+protected:
+ std::string GetName() const;
+ virtual void AddProperties(GVariantBuilder* builder) = 0;
+
private:
Atom m_MoveResizeAtom;
};
diff --git a/plugins/unityshell/src/compizminimizedwindowhandler.h b/plugins/unityshell/src/compizminimizedwindowhandler.h
index 3c5bebf64..a797daa02 100644
--- a/plugins/unityshell/src/compizminimizedwindowhandler.h
+++ b/plugins/unityshell/src/compizminimizedwindowhandler.h
@@ -46,7 +46,7 @@ class CompizMinimizedWindowHandler:
{
public:
- CompizMinimizedWindowHandler (CompWindow *w);
+ CompizMinimizedWindowHandler (CompWindow *w, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire);
~CompizMinimizedWindowHandler ();
void setVisibility (bool visible);
@@ -92,10 +92,10 @@ template <typename Screen, typename Window>
bool compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvents = true;
template <typename Screen, typename Window>
-compiz::CompizMinimizedWindowHandler<Screen, Window>::CompizMinimizedWindowHandler(CompWindow *w) :
- MinimizedWindowHandler (screen->dpy (), w->id ())
+compiz::CompizMinimizedWindowHandler<Screen, Window>::CompizMinimizedWindowHandler(CompWindow *w, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire) :
+ MinimizedWindowHandler (screen->dpy(), w->id(), lock_acquire)
{
- priv = new PrivateCompizMinimizedWindowHandler ();
+ priv = new PrivateCompizMinimizedWindowHandler();
priv->mWindow = w;
@@ -113,13 +113,13 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::getTransients ()
{
std::vector <unsigned int> transients;
- for (CompWindow *w : screen->windows ())
+ for (CompWindow *w : screen->windows())
{
compiz::CompTransientForReader *reader = new compiz::CompTransientForReader (w);
- if (reader->isTransientFor (priv->mWindow->id ()) ||
- reader->isGroupTransientFor (priv->mWindow->id ()))
- transients.push_back (w->id ());
+ if (reader->isTransientFor (priv->mWindow->id()) ||
+ reader->isGroupTransientFor (priv->mWindow->id()))
+ transients.push_back (w->id());
delete reader;
}
@@ -131,23 +131,23 @@ template <typename Screen, typename Window>
void
compiz::CompizMinimizedWindowHandler<Screen, Window>::setVisibility (bool visible)
{
- MinimizedWindowHandler::setVisibility (visible, priv->mWindow->id ());
+ MinimizedWindowHandler::setVisibility (visible, priv->mWindow->id());
- CompositeWindow::get (priv->mWindow)->addDamage ();
+ CompositeWindow::get (priv->mWindow)->addDamage();
}
template <typename Screen, typename Window>
void
compiz::CompizMinimizedWindowHandler<Screen, Window>::minimize ()
{
- Atom wmState = XInternAtom (screen->dpy (), "WM_STATE", 0);
+ Atom wmState = XInternAtom (screen->dpy(), "WM_STATE", 0);
unsigned long data[2];
- std::vector<unsigned int> transients = getTransients ();
+ std::vector<unsigned int> transients = getTransients();
handleEvents = true;
priv->mWindow->windowNotify (CompWindowNotifyMinimize);
- priv->mWindow->changeState (priv->mWindow->state () | CompWindowStateHiddenMask);
+ priv->mWindow->changeState (priv->mWindow->state() | CompWindowStateHiddenMask);
minimizedWindows.push_back (this);
@@ -159,8 +159,8 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::minimize ()
{
Window *w = Window::get (win);
if (!w->mMinimizeHandler)
- w->mMinimizeHandler.reset (new Type (win));
- w->mMinimizeHandler->minimize ();
+ w->mMinimizeHandler.reset (new Type (win, w));
+ w->mMinimizeHandler->minimize();
}
}
@@ -170,16 +170,16 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::minimize ()
data[0] = IconicState;
data[1] = None;
- XChangeProperty (screen->dpy (), priv->mWindow->id (), wmState, wmState,
+ XChangeProperty (screen->dpy(), priv->mWindow->id(), wmState, wmState,
32, PropModeReplace, (unsigned char *) data, 2);
- priv->mWindow->changeState (priv->mWindow->state () | CompWindowStateHiddenMask);
+ priv->mWindow->changeState (priv->mWindow->state() | CompWindowStateHiddenMask);
/* Don't allow other windows to be focused by moveInputFocusToOtherWindow */
for (auto mh : minimizedWindows)
mh->priv->mWindow->focusSetEnabled (Window::get (mh->priv->mWindow), false);
- priv->mWindow->moveInputFocusToOtherWindow ();
+ priv->mWindow->moveInputFocusToOtherWindow();
for (auto mh : minimizedWindows)
mh->priv->mWindow->focusSetEnabled (Window::get (mh->priv->mWindow), true);
@@ -189,12 +189,12 @@ template <typename Screen, typename Window>
void
compiz::CompizMinimizedWindowHandler<Screen, Window>::windowNotify (CompWindowNotify n)
{
- if (n == CompWindowNotifyFocusChange && priv->mWindow->minimized ())
+ if (n == CompWindowNotifyFocusChange && priv->mWindow->minimized())
{
for (auto mh : minimizedWindows)
mh->priv->mWindow->focusSetEnabled (Window::get (mh->priv->mWindow), false);
- priv->mWindow->moveInputFocusToOtherWindow ();
+ priv->mWindow->moveInputFocusToOtherWindow();
for (auto mh : minimizedWindows)
mh->priv->mWindow->focusSetEnabled (Window::get (mh->priv->mWindow), true);
@@ -206,10 +206,10 @@ void
compiz::CompizMinimizedWindowHandler<Screen, Window>::updateFrameRegion (CompRegion &r)
{
unsigned int oldUpdateFrameRegionIndex;
- r = CompRegion ();
+ r = CompRegion();
/* Ensure no other plugins can touch this frame region */
- oldUpdateFrameRegionIndex = priv->mWindow->updateFrameRegionGetCurrentIndex ();
+ oldUpdateFrameRegionIndex = priv->mWindow->updateFrameRegionGetCurrentIndex();
priv->mWindow->updateFrameRegionSetCurrentIndex (MAXSHORT);
priv->mWindow->updateFrameRegion (r);
priv->mWindow->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex);
@@ -217,19 +217,19 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::updateFrameRegion (CompReg
template <typename Screen, typename Window>
void
-compiz::CompizMinimizedWindowHandler<Screen, Window>::unminimize ()
+compiz::CompizMinimizedWindowHandler<Screen, Window>::unminimize()
{
- Atom wmState = XInternAtom (screen->dpy (), "WM_STATE", 0);
+ Atom wmState = XInternAtom (screen->dpy(), "WM_STATE", 0);
unsigned long data[2];
- std::vector<unsigned int> transients = getTransients ();
+ std::vector<unsigned int> transients = getTransients();
minimizedWindows.remove (this);
priv->mWindow->focusSetEnabled (Window::get (priv->mWindow), true);
priv->mWindow->windowNotify (CompWindowNotifyUnminimize);
- priv->mWindow->changeState (priv->mWindow->state () & ~CompWindowStateHiddenMask);
+ priv->mWindow->changeState (priv->mWindow->state() & ~CompWindowStateHiddenMask);
priv->mWindow->windowNotify (CompWindowNotifyShow);
for (unsigned int &w : transients)
@@ -241,20 +241,20 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::unminimize ()
Window *w = Window::get (win);
if (w && w->mMinimizeHandler)
{
- w->mMinimizeHandler->unminimize ();
- w->mMinimizeHandler.reset ();
+ w->mMinimizeHandler->unminimize();
+ w->mMinimizeHandler.reset();
}
}
}
setVisibility (true);
- priv->mWindow->changeState (priv->mWindow->state () & ~CompWindowStateHiddenMask);
+ priv->mWindow->changeState (priv->mWindow->state() & ~CompWindowStateHiddenMask);
data[0] = NormalState;
data[1] = None;
- XChangeProperty (screen->dpy (), priv->mWindow->id (), wmState, wmState,
+ XChangeProperty (screen->dpy(), priv->mWindow->id(), wmState, wmState,
32, PropModeReplace, (unsigned char *) data, 2);
}
@@ -266,7 +266,7 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::getPaintMask ()
for (CompWindow *w : minimizingWindows)
{
- if (w->id () == priv->mWindow->id ())
+ if (w->id() == priv->mWindow->id())
doMask = false;
break;
}
@@ -300,8 +300,8 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::handleCompizEvent (const c
else
{
/* Ugly hack for LP#977189 */
- CompositeWindow::get (w)->release ();
- GLWindow::get (w)->release ();
+ CompositeWindow::get (w)->release();
+ GLWindow::get (w)->release();
minimizingWindows.remove (w);
}
}
@@ -309,7 +309,7 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::handleCompizEvent (const c
}
if (!CompOption::getBoolOptionNamed (o, "active", false) &&
- minimizingWindows.empty ())
+ minimizingWindows.empty())
{
handleEvents = false;
}
@@ -320,8 +320,8 @@ void
compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvent (XEvent *event)
{
/* Ignore sent events from the InputRemover */
- if (screen->XShape () && event->type ==
- screen->shapeEvent () + ShapeNotify &&
+ if (screen->XShape() && event->type ==
+ screen->shapeEvent() + ShapeNotify &&
!event->xany.send_event)
{
CompWindow *w = screen->findWindow (((XShapeEvent *) event)->window);
@@ -329,7 +329,7 @@ compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvent (XEvent *event
if (w)
{
Window *pw = Window::get (w);
- Type *compizMinimizeHandler = pw->mMinimizeHandler.get ();
+ Type *compizMinimizeHandler = pw->mMinimizeHandler.get();
/* Restore and re-save input shape and remove */
if (compizMinimizeHandler)
@@ -345,18 +345,18 @@ template <typename Screen, typename Window>
void
compiz::CompizMinimizedWindowHandler<Screen, Window>::setFunctions (bool keepMinimized)
{
- for (CompWindow *w : screen->windows ())
+ for (CompWindow *w : screen->windows())
{
- bool m = w->minimized ();
- bool enable = keepMinimized && w->mapNum () > 0;
+ bool m = w->minimized();
+ bool enable = keepMinimized && w->mapNum() > 0;
if (m)
- w->unminimize ();
+ w->unminimize();
w->minimizeSetEnabled (Window::get (w), enable);
w->unminimizeSetEnabled (Window::get (w), enable);
w->minimizedSetEnabled (Window::get (w), enable);
if (m)
- Window::get (w)->window->minimize ();
+ Window::get (w)->window->minimize();
}
}
diff --git a/plugins/unityshell/src/inputremover.h b/plugins/unityshell/src/inputremover.h
index 5bbed4d83..69284f718 100644
--- a/plugins/unityshell/src/inputremover.h
+++ b/plugins/unityshell/src/inputremover.h
@@ -23,7 +23,6 @@
#define _COMPIZ_INPUTREMOVER_H
#include <memory>
-
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
@@ -83,6 +82,50 @@ private:
int mShapeError;
};
+
+class WindowInputRemoverLock
+{
+ public:
+
+ typedef std::shared_ptr <WindowInputRemoverLock> Ptr;
+ typedef std::weak_ptr <WindowInputRemoverLock> Weak;
+
+ WindowInputRemoverLock (WindowInputRemoverInterface *remover) :
+ remover_ (remover)
+ {
+ remover->save();
+ remover->remove();
+ }
+
+ ~WindowInputRemoverLock ()
+ {
+ remover_->restore();
+ delete remover_;
+ }
+
+ void refresh ()
+ {
+ remover_->save();
+ remover_->remove();
+ }
+
+ private:
+ WindowInputRemoverInterface *remover_;
+};
+
+class WindowInputRemoverLockAcquireInterface
+{
+public:
+
+ virtual ~WindowInputRemoverLockAcquireInterface () {}
+
+ WindowInputRemoverLock::Ptr InputRemover () { return GetInputRemover (); }
+
+private:
+
+ virtual WindowInputRemoverLock::Ptr GetInputRemover () = 0;
+};
+
}
#endif
diff --git a/plugins/unityshell/src/minimizedwindowhandler.cpp b/plugins/unityshell/src/minimizedwindowhandler.cpp
index 761287f37..7f8d8559f 100644
--- a/plugins/unityshell/src/minimizedwindowhandler.cpp
+++ b/plugins/unityshell/src/minimizedwindowhandler.cpp
@@ -20,6 +20,7 @@
*/
#include "minimizedwindowhandler.h"
+#include "inputremover.h"
#include <cstring>
namespace compiz
@@ -35,7 +36,8 @@ public:
std::list <MinimizedWindowHandler::Ptr> mTransients;
- WindowInputRemover *mRemover;
+ WindowInputRemoverLock::Ptr mRemover;
+ WindowInputRemoverLockAcquireInterface *mLockAcquire;
};
}
@@ -56,19 +58,13 @@ compiz::MinimizedWindowHandler::setVisibility (bool visible, Window shapeWin)
{
if (!visible && !priv->mRemover)
{
- priv->mRemover = new compiz::WindowInputRemover (priv->mDpy, shapeWin);
+ priv->mRemover = priv->mLockAcquire->InputRemover();
if (!priv->mRemover)
return;
-
- if (priv->mRemover->save ())
- priv->mRemover->remove ();
}
else if (visible && priv->mRemover)
{
- priv->mRemover->restore ();
-
- delete priv->mRemover;
- priv->mRemover = NULL;
+ priv->mRemover.reset();
}
}
@@ -78,7 +74,7 @@ compiz::MinimizedWindowHandler::getTransients ()
std::vector<unsigned int> transients;
compiz::X11TransientForReader *reader = new compiz::X11TransientForReader (priv->mDpy, priv->mXid);
- transients = reader->getTransients ();
+ transients = reader->getTransients();
delete reader;
@@ -99,15 +95,15 @@ compiz::MinimizedWindowHandler::minimize ()
Window root = DefaultRootWindow (priv->mDpy), parent = priv->mXid, lastParent = priv->mXid;
Window *children;
unsigned int nchildren;
- compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0));
+ compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0, priv->mLockAcquire));
auto predicate_this = boost::bind (&compiz::MinimizedWindowHandler::contains, this, _1);
- auto predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get (), _1);
+ auto predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get(), _1);
std::vector<unsigned int> transients = getTransients ();
for (unsigned int &w : transients)
{
- compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w));
+ compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w, priv->mLockAcquire));
holder->priv->mTransients.push_back (p);
}
@@ -118,7 +114,7 @@ compiz::MinimizedWindowHandler::minimize ()
priv->mTransients.push_back (mw);
for (MinimizedWindowHandler::Ptr &mw : priv->mTransients)
- mw->minimize ();
+ mw->minimize();
do
{
@@ -180,15 +176,15 @@ compiz::MinimizedWindowHandler::unminimize ()
Window root = DefaultRootWindow (priv->mDpy), parent = priv->mXid, lastParent = priv->mXid;
Window *children;
unsigned int nchildren;
- compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0));
+ compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0, priv->mLockAcquire));
auto predicate_this = boost::bind (&compiz::MinimizedWindowHandler::contains, this, _1);
- auto predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get (), _1);
+ auto predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get(), _1);
- std::vector<unsigned int> transients = getTransients ();
+ std::vector<unsigned int> transients = getTransients();
for (unsigned int &w : transients)
{
- compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w));
+ compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w, priv->mLockAcquire));
holder->priv->mTransients.push_back (p);
}
@@ -199,7 +195,7 @@ compiz::MinimizedWindowHandler::unminimize ()
priv->mTransients.push_back (mw);
for (MinimizedWindowHandler::Ptr &mw : priv->mTransients)
- mw->unminimize ();
+ mw->unminimize();
do
{
@@ -264,13 +260,13 @@ compiz::MinimizedWindowHandler::unminimize ()
XDeleteProperty (priv->mDpy, priv->mXid, netWmState);
}
-compiz::MinimizedWindowHandler::MinimizedWindowHandler (Display *dpy, unsigned int xid)
+compiz::MinimizedWindowHandler::MinimizedWindowHandler (Display *dpy, unsigned int xid, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire)
{
priv = new PrivateMinimizedWindowHandler;
priv->mDpy = dpy;
priv->mXid = xid;
- priv->mRemover = NULL;
+ priv->mLockAcquire = lock_acquire;
}
compiz::MinimizedWindowHandler::~MinimizedWindowHandler ()
diff --git a/plugins/unityshell/src/minimizedwindowhandler.h b/plugins/unityshell/src/minimizedwindowhandler.h
index a7dcf9d98..ecfc1be9e 100644
--- a/plugins/unityshell/src/minimizedwindowhandler.h
+++ b/plugins/unityshell/src/minimizedwindowhandler.h
@@ -38,7 +38,7 @@ class MinimizedWindowHandler
{
public:
- MinimizedWindowHandler (Display *dpy, unsigned int xid);
+ MinimizedWindowHandler (Display *dpy, unsigned int xid, compiz::WindowInputRemoverLockAcquireInterface *lock_acquire);
virtual ~MinimizedWindowHandler ();
virtual void minimize ();
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 8a0e57c12..e85c32467 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -107,10 +107,8 @@ UnityScreen::UnityScreen(CompScreen* screen)
, screen(screen)
, cScreen(CompositeScreen::get(screen))
, gScreen(GLScreen::get(screen))
+ , debugger_(this)
, enable_shortcut_overlay_(true)
- , wt(nullptr)
- , panelWindow(nullptr)
- , debugger(nullptr)
, needsRelayout(false)
, _in_paint(false)
, relayoutSourceId(0)
@@ -219,25 +217,26 @@ UnityScreen::UnityScreen(CompScreen* screen)
PluginAdapter::Initialize(screen);
WindowManager::SetDefault(PluginAdapter::Default());
+ AddChild(PluginAdapter::Default());
StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());
nux::NuxInitialize(0);
#ifndef USE_GLES
- wt = nux::CreateFromForeignWindow(cScreen->output(),
- glXGetCurrentContext(),
- &UnityScreen::initUnity,
- this);
+ wt.reset(nux::CreateFromForeignWindow(cScreen->output(),
+ glXGetCurrentContext(),
+ &UnityScreen::initUnity,
+ this));
#else
- wt = nux::CreateFromForeignWindow(cScreen->output(),
- eglGetCurrentContext(),
- &UnityScreen::initUnity,
- this);
+ wt.reset(nux::CreateFromForeignWindow(cScreen->output(),
+ eglGetCurrentContext(),
+ &UnityScreen::initUnity,
+ this));
#endif
wt->RedrawRequested.connect(sigc::mem_fun(this, &UnityScreen::onRedrawRequested));
- unity_a11y_init(wt);
+ unity_a11y_init(wt.get());
/* i18n init */
bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
@@ -245,9 +244,6 @@ UnityScreen::UnityScreen(CompScreen* screen)
wt->Run(NULL);
uScreen = this;
-
- debugger = new unity::debug::DebugDBusInterface(this, this->screen);
-
_in_paint = false;
#ifndef USE_GLES
@@ -402,9 +398,7 @@ UnityScreen::~UnityScreen()
::unity::ui::IconRenderer::DestroyTextures();
QuicklistManager::Destroy();
- // We need to delete the launchers before the window thread.
- launcher_controller_.reset();
- delete wt;
+
reset_glib_logging();
}
@@ -1040,7 +1034,8 @@ void UnityScreen::leaveShowDesktopMode (CompWindow *w)
void UnityWindow::enterShowDesktop ()
{
if (!mShowdesktopHandler)
- mShowdesktopHandler = new ShowdesktopHandler (static_cast <ShowdesktopHandlerWindowInterface *> (this));
+ mShowdesktopHandler = new ShowdesktopHandler (static_cast <ShowdesktopHandlerWindowInterface *> (this),
+ static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (this));
window->setShowDesktopMode (true);
mShowdesktopHandler->FadeOut ();
@@ -1174,10 +1169,15 @@ void UnityWindow::DoDeleteHandler ()
window->updateFrameRegion ();
}
-compiz::WindowInputRemoverInterface::Ptr
+compiz::WindowInputRemoverLock::Ptr
UnityWindow::GetInputRemover ()
{
- return compiz::WindowInputRemoverInterface::Ptr (new compiz::WindowInputRemover (screen->dpy (), window->id ()));
+ if (!input_remover_.expired ())
+ return input_remover_.lock ();
+
+ compiz::WindowInputRemoverLock::Ptr ret (new compiz::WindowInputRemoverLock (new compiz::WindowInputRemover (screen->dpy (), window->id ())));
+ input_remover_ = ret;
+ return ret;
}
unsigned int
@@ -1732,7 +1732,7 @@ bool UnityScreen::altTabInitiateCommon(CompAction* action, switcher::ShowMode sh
auto results = launcher_controller_->GetAltTabIcons(show_mode == switcher::ShowMode::CURRENT_VIEWPORT);
- if (!(results.size() == 1 && results[0]->GetIconType() == AbstractLauncherIcon::IconType::TYPE_BEGIN))
+ if (!(results.size() == 1 && results[0]->GetIconType() == AbstractLauncherIcon::IconType::TYPE_DESKTOP))
switcher_controller_->Show(show_mode, switcher::SortMode::FOCUS_ORDER, false, results);
return true;
@@ -2284,7 +2284,7 @@ UnityWindow::minimize ()
if (!mMinimizeHandler)
{
- mMinimizeHandler.reset (new UnityMinimizedHandler (window));
+ mMinimizeHandler.reset (new UnityMinimizedHandler (window, this));
mMinimizeHandler->minimize ();
}
}
@@ -2643,9 +2643,12 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
launcher_options->icon_size = optionGetIconSize();
launcher_options->tile_size = optionGetIconSize() + 6;
- hud_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1;
+ hud_controller_->icon_size = launcher_options->icon_size();
+ hud_controller_->tile_size = launcher_options->tile_size();
+
/* The launcher geometry includes 1px used to draw the right margin
- * that must not be considered when drawing the dash */
+ * that must not be considered when drawing an overlay */
+ hud_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1;
dash_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1;
if (p)
@@ -2810,17 +2813,17 @@ void UnityScreen::OnDashRealized ()
void UnityScreen::initLauncher()
{
Timer timer;
- launcher_controller_.reset(new launcher::Controller(screen->dpy()));
+ launcher_controller_ = std::make_shared<launcher::Controller>(screen->dpy());
AddChild(launcher_controller_.get());
- switcher_controller_.reset(new switcher::Controller());
+ switcher_controller_ = std::make_shared<switcher::Controller>();
AddChild(switcher_controller_.get());
LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
/* Setup panel */
timer.Reset();
- panel_controller_.reset(new panel::Controller());
+ panel_controller_ = std::make_shared<panel::Controller>();
AddChild(panel_controller_.get());
panel_controller_->SetMenuShowTimings(optionGetMenusFadein(),
optionGetMenusFadeout(),
@@ -2830,20 +2833,22 @@ void UnityScreen::initLauncher()
LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";
/* Setup Places */
- dash_controller_.reset(new dash::Controller());
+ dash_controller_ = std::make_shared<dash::Controller>();
dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));
/* Setup Hud */
- hud_controller_.reset(new hud::Controller());
+ hud_controller_ = std::make_shared<hud::Controller>();
auto hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode();
hud_controller_->launcher_locked_out = (hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER);
hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0);
+ hud_controller_->icon_size = launcher_controller_->options()->icon_size();
+ hud_controller_->tile_size = launcher_controller_->options()->tile_size();
AddChild(hud_controller_.get());
LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
// Setup Shortcut Hint
InitHints();
- shortcut_controller_.reset(new shortcut::Controller(hints_));
+ shortcut_controller_ = std::make_shared<shortcut::Controller>(hints_);
AddChild(shortcut_controller_.get());
AddChild(dash_controller_.get());
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 8bcfed0ad..a648ed693 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -240,21 +240,23 @@ private:
GeisAdapter geis_adapter_;
internal::FavoriteStoreGSettings favorite_store_;
+ /* The window thread should be the last thing removed, as c++ does it in reverse order */
+ std::unique_ptr<nux::WindowThread> wt;
+
+ /* These must stay below the window thread, please keep the order */
launcher::Controller::Ptr launcher_controller_;
dash::Controller::Ptr dash_controller_;
panel::Controller::Ptr panel_controller_;
switcher::Controller::Ptr switcher_controller_;
hud::Controller::Ptr hud_controller_;
-
shortcut::Controller::Ptr shortcut_controller_;
+ debug::DebugDBusInterface debugger_;
+
std::list<shortcut::AbstractHint::Ptr> hints_;
bool enable_shortcut_overlay_;
std::unique_ptr<GestureEngine> gesture_engine_;
- nux::WindowThread* wt;
- nux::BaseWindow* panelWindow;
nux::Geometry lastTooltipArea;
- unity::debug::DebugDBusInterface* debugger;
bool needsRelayout;
bool _in_paint;
guint32 relayoutSourceId;
@@ -281,7 +283,7 @@ private:
nux::Property<nux::Geometry> primary_monitor_;
- unity::BGHash _bghash;
+ BGHash _bghash;
#ifdef USE_GLES
::GLFramebufferObject *oldFbo;
@@ -319,6 +321,7 @@ class UnityWindow :
public WindowInterface,
public GLWindowInterface,
public ShowdesktopHandlerWindowInterface,
+ public compiz::WindowInputRemoverLockAcquireInterface,
public BaseSwitchWindow,
public PluginClassHandler <UnityWindow, CompWindow>
{
@@ -418,7 +421,9 @@ private:
unsigned int GetNoCoreInstanceMask ();
- compiz::WindowInputRemoverInterface::Ptr GetInputRemover ();
+ compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
+
+ compiz::WindowInputRemoverLock::Weak input_remover_;
};
diff --git a/services/panel-service.c b/services/panel-service.c
index c39709959..b9d77704a 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -1720,8 +1720,9 @@ panel_service_show_entry_common (PanelService *self,
G_CALLBACK (on_active_menu_move_current), self);
gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, 0, CurrentTime);
- GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu));
+ gtk_menu_reposition (priv->last_menu);
+ GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu));
if (gdkwin != NULL)
{
gint left=0, top=0, width=0, height=0;
diff --git a/standalone-clients/CMakeLists.txt b/standalone-clients/CMakeLists.txt
index a098a70a3..9becefd26 100644
--- a/standalone-clients/CMakeLists.txt
+++ b/standalone-clients/CMakeLists.txt
@@ -206,6 +206,7 @@ add_executable (launcher
TestLauncher.cpp
${UNITY_SRC}/CairoBaseWindow.cpp
${UNITY_SRC}/AbstractLauncherIcon.h
+ ${UNITY_SRC}/AbstractLauncherIcon.cpp
${UNITY_SRC}/AbstractIconRenderer.h
${UNITY_SRC}/LauncherIcon.cpp
${UNITY_SRC}/LauncherIcon.h
@@ -221,6 +222,8 @@ add_executable (launcher
${UNITY_SRC}/DndData.h
${UNITY_SRC}/TrashLauncherIcon.cpp
${UNITY_SRC}/TrashLauncherIcon.h
+ ${UNITY_SRC}/Decaymulator.cpp
+ ${UNITY_SRC}/Decaymulator.h
${UNITY_SRC}/DesktopLauncherIcon.cpp
${UNITY_SRC}/DesktopLauncherIcon.h
${UNITY_SRC}/DNDCollectionWindow.cpp
@@ -231,12 +234,22 @@ add_executable (launcher
${UNITY_SRC}/DeviceLauncherSection.h
${UNITY_SRC}/DevicesSettings.cpp
${UNITY_SRC}/DevicesSettings.h
+ ${UNITY_SRC}/EdgeBarrierController.h
+ ${UNITY_SRC}/EdgeBarrierController.cpp
${UNITY_SRC}/FavoriteStore.cpp
${UNITY_SRC}/FavoriteStore.h
${UNITY_SRC}/FavoriteStoreGSettings.cpp
${UNITY_SRC}/FavoriteStoreGSettings.h
+ ${UNITY_SRC}/FavoriteStorePrivate.cpp
+ ${UNITY_SRC}/FavoriteStorePrivate.h
+ ${UNITY_SRC}/HudLauncherIcon.cpp
+ ${UNITY_SRC}/HudLauncherIcon.h
${UNITY_SRC}/IconLoader.cpp
${UNITY_SRC}/IconLoader.h
+ ${UNITY_SRC}/IconTextureSource.h
+ ${UNITY_SRC}/IconTextureSource.cpp
+ ${UNITY_SRC}/LauncherOptions.cpp
+ ${UNITY_SRC}/LauncherOptions.h
${UNITY_SRC}/LauncherEntryRemoteModel.cpp
${UNITY_SRC}/LauncherEntryRemoteModel.h
${UNITY_SRC}/LauncherEntryRemote.cpp
@@ -265,10 +278,16 @@ add_executable (launcher
${UNITY_SRC}/BackgroundEffectHelper.cpp
${UNITY_SRC}/StaticCairoText.cpp
${UNITY_SRC}/StaticCairoText.h
+ ${UNITY_SRC}/SingleMonitorLauncherIcon.cpp
+ ${UNITY_SRC}/SingleMonitorLauncherIcon.h
${UNITY_SRC}/SoftwareCenterLauncherIcon.cpp
${UNITY_SRC}/SoftwareCenterLauncherIcon.h
${UNITY_SRC}/Introspectable.cpp
${UNITY_SRC}/Introspectable.h
+ ${UNITY_SRC}/PanelStyle.cpp
+ ${UNITY_SRC}/PanelStyle.h
+ ${UNITY_SRC}/PointerBarrier.cpp
+ ${UNITY_SRC}/PointerBarrier.h
${UNITY_SRC}/QuicklistMenuItem.cpp
${UNITY_SRC}/QuicklistMenuItem.h
${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp
@@ -283,6 +302,8 @@ add_executable (launcher
${UNITY_SRC}/QuicklistView.h
${UNITY_SRC}/QuicklistManager.cpp
${UNITY_SRC}/QuicklistManager.h
+ ${UNITY_SRC}/TextureCache.cpp
+ ${UNITY_SRC}/TextureCache.h
${UNITY_SRC}/Timer.cpp
${UNITY_SRC}/Timer.h
${UNITY_SRC}/UBusMessages.h
@@ -290,6 +311,8 @@ add_executable (launcher
${UNITY_SRC}/UBusWrapper.h
${UNITY_SRC}/ubus-server.cpp
${UNITY_SRC}/ubus-server.h
+ ${UNITY_SRC}/UScreen.cpp
+ ${UNITY_SRC}/UScreen.h
)
add_dependencies (launcher unity-core-${UNITY_API_VERSION})
diff --git a/standalone-clients/TestLauncher.cpp b/standalone-clients/TestLauncher.cpp
index 5c76c8f18..cd83a4331 100644
--- a/standalone-clients/TestLauncher.cpp
+++ b/standalone-clients/TestLauncher.cpp
@@ -31,9 +31,12 @@
#include "NuxGraphics/GraphicsEngine.h"
#include <gtk/gtk.h>
+#include "BackgroundEffectHelper.h"
+#include "FavoriteStoreGSettings.h"
#include "LauncherController.h"
#include "Launcher.h"
-#include "BackgroundEffectHelper.h"
+#include "PanelStyle.h"
+
#include <dbus/dbus-glib.h>
using namespace unity;
@@ -56,6 +59,10 @@ int main(int argc, char** argv)
nux::NuxInitialize(0);
+ GeisAdapter geis_adapter;
+ panel::Style panel_style;
+ internal::FavoriteStoreGSettings favorite_store;
+
BackgroundEffectHelper::blur_type = BLUR_NONE;
nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Unity Switcher"), 300, 800, 0, &ThreadWidgetInit, 0);
diff --git a/tests/autopilot/autopilot/emulators/bamf.py b/tests/autopilot/autopilot/emulators/bamf.py
index 88553fbbd..b0901d50f 100644
--- a/tests/autopilot/autopilot/emulators/bamf.py
+++ b/tests/autopilot/autopilot/emulators/bamf.py
@@ -254,6 +254,16 @@ class BamfWindow(object):
return self._x_win
@property
+ def name(self):
+ """Get the window name.
+
+ Note: This may change according to the current locale. If you want a unique
+ string to match windows against, use the x_id instead.
+
+ """
+ return self._view_iface.Name()
+
+ @property
def title(self):
"""Get the window title.
diff --git a/tests/autopilot/autopilot/emulators/unity/__init__.py b/tests/autopilot/autopilot/emulators/unity/__init__.py
index c1d1b4cf6..63aac443d 100644
--- a/tests/autopilot/autopilot/emulators/unity/__init__.py
+++ b/tests/autopilot/autopilot/emulators/unity/__init__.py
@@ -9,6 +9,8 @@
from dbus import Interface
import logging
+from testtools.matchers import Equals
+from time import sleep
from autopilot.emulators.dbus_handler import session_bus
@@ -28,8 +30,9 @@ class StateNotFoundError(RuntimeError):
class IntrospectableObjectMetaclass(type):
"""Metaclass to insert appropriate classes into the object registry."""
- def __new__(self, classname, bases, classdict):
- class_object = type.__new__(self, classname, bases, classdict)
+ def __new__(cls, classname, bases, classdict):
+ """Add class name to type registry."""
+ class_object = type.__new__(cls, classname, bases, classdict)
_object_registry[classname] = class_object
return class_object
@@ -115,6 +118,11 @@ def log_unity_message(severity, message):
_introspection_iface.LogMessage(severity, message)
+def translate_state_keys(state_dict):
+ """Translates the state_dict passed in so the keys are usable as python attributes."""
+ return {k.replace('-','_'):v for k,v in state_dict.iteritems() }
+
+
class UnityIntrospectionObject(object):
"""A class that can be created using a dictionary of state from Unity."""
__metaclass__ = IntrospectableObjectMetaclass
@@ -130,11 +138,74 @@ class UnityIntrospectionObject(object):
"""
self.__state = {}
- for key, value in state_dict.iteritems():
+ for key, value in translate_state_keys(state_dict).iteritems():
# don't store id in state dictionary -make it a proper instance attribute
if key == 'id':
self.id = value
- self.__state[key.replace('-', '_')] = value
+ self.__state[key] = self._make_attribute(key, value)
+
+ def _make_attribute(self, name, value):
+ """Make an attribute for 'value', patched with the wait_for function."""
+
+ def wait_for(self, expected_value):
+ """Wait up to 10 seconds for our value to change to 'expected_value'.
+
+ expected_value can be a testtools.matcher.Matcher subclass (like
+ LessThan, for example), or an ordinary value.
+
+ This works by refreshing the value using repeated dbus calls.
+
+ Raises RuntimeError if the attribute was not equal to the expected value
+ after 10 seconds.
+
+ """
+ # It's guaranteed that our value is up to date, since __getattr__ calls
+ # refresh_state. This if statement stops us waiting if the value is
+ # already what we expect:
+ if self == expected_value:
+ return
+
+ # unfortunately not all testtools matchers derive from the Matcher
+ # class, so we can't use issubclass, isinstance for this:
+ match_fun = getattr(expected_value, 'match', None)
+ is_matcher = match_fun and callable(match_fun)
+ if not is_matcher:
+ expected_value = Equals(expected_value)
+
+ for i in range(11):
+ new_state = translate_state_keys(get_state_by_name_and_id(
+ self.parent.__class__.__name__,
+ self.parent.id)
+ )
+ new_value = new_state[self.name]
+ # Support for testtools.matcher classes:
+ mismatch = expected_value.match(new_value)
+ if mismatch:
+ failure_msg = mismatch.describe()
+ else:
+ self.parent.set_properties(new_state)
+ return
+
+ sleep(1)
+
+ raise AssertionError("After 10 seconds test on %s.%s failed: %s"
+ % (self.parent.__class__.__name__, self.name, failure_msg))
+
+ # This looks like magic, but it's really not. We're creating a new type
+ # on the fly that derives from the type of 'value' with a couple of
+ # extra attributes: wait_for is the wait_for method above. 'parent' and
+ # 'name' are needed by the wait_for method.
+ #
+ # We can't use traditional meta-classes here, since the type we're
+ # deriving from is only known at call time, not at parse time (we could
+ # override __call__ in the meta class, but that doesn't buy us anything
+ # extra).
+ #
+ # A better way to do this would be with functools.partial, which I tried
+ # initially, but doesn't work well with bound methods.
+ t = type(value)
+ attrs = {'wait_for': wait_for, 'parent':self, 'name':name}
+ return type(t.__name__, (t,), attrs)(value)
def _get_child_tuples_by_type(self, desired_type):
"""Get a list of (name,dict) pairs from children of the specified type.
diff --git a/tests/autopilot/autopilot/emulators/unity/dash.py b/tests/autopilot/autopilot/emulators/unity/dash.py
index d8e8b2cd9..fe51f3314 100644
--- a/tests/autopilot/autopilot/emulators/unity/dash.py
+++ b/tests/autopilot/autopilot/emulators/unity/dash.py
@@ -7,8 +7,6 @@
# by the Free Software Foundation.
#
-from time import sleep
-
from autopilot.emulators.unity import (
get_state_by_path,
make_introspection_object,
@@ -43,9 +41,10 @@ class Dash(KeybindingsHelper):
"""
Reveals the dash if it's currently hidden, hides it otherwise.
"""
+ old_state = self.visible
logger.debug("Toggling dash visibility with Super key.")
self.keybinding("dash/reveal", 0.1)
- sleep(1)
+ self.visible.wait_for(not old_state)
def ensure_visible(self, clear_search=True):
"""
@@ -53,7 +52,7 @@ class Dash(KeybindingsHelper):
"""
if not self.visible:
self.toggle_reveal()
- self._wait_for_visibility(expect_visible=True)
+ self.visible.wait_for(True)
if clear_search:
self.clear_search()
@@ -63,16 +62,7 @@ class Dash(KeybindingsHelper):
"""
if self.visible:
self.toggle_reveal()
- self._wait_for_visibility(expect_visible=False)
-
- def _wait_for_visibility(self, expect_visible):
- for i in range(11):
- if self.visible != expect_visible:
- sleep(1)
- else:
- return
- raise RuntimeError("Dash not %s after waiting for 10 seconds." %
- ("Visible" if expect_visible else "Hidden"))
+ self.visible.wait_for(False)
@property
def visible(self):
@@ -86,9 +76,10 @@ class Dash(KeybindingsHelper):
@property
def search_string(self):
- return self.get_searchbar().search_string
+ return self.searchbar.search_string
- def get_searchbar(self):
+ @property
+ def searchbar(self):
"""Returns the searchbar attached to the dash."""
return self.view.get_searchbar()
@@ -104,6 +95,7 @@ class Dash(KeybindingsHelper):
"""
self._keyboard.press_and_release("Ctrl+a")
self._keyboard.press_and_release("Delete")
+ self.search_string.wait_for("")
def reveal_application_lens(self, clear_search=True):
"""Reveal the application lense."""
@@ -129,7 +121,7 @@ class Dash(KeybindingsHelper):
self.keybinding_hold(binding_name)
self.keybinding_tap(binding_name)
self.keybinding_release(binding_name)
- self._wait_for_visibility(expect_visible=True)
+ self.visible.wait_for(True)
if clear_search:
self.clear_search()
@@ -260,7 +252,8 @@ class FilterBar(UnityIntrospectionObject):
return filter_label
return None
- def is_expanded(self):
+ @property
+ def expanded(self):
"""Return True if the filterbar on this lens is expanded, False otherwise.
"""
searchbar = self._get_searchbar()
@@ -268,34 +261,25 @@ class FilterBar(UnityIntrospectionObject):
def ensure_expanded(self):
"""Expand the filter bar, if it's not already."""
- if not self.is_expanded():
+ if not self.expanded:
searchbar = self._get_searchbar()
tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2)
ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2)
m = Mouse()
m.move(tx, ty)
m.click()
- self._wait_for_expansion(True)
+ self.expanded.wait_for(True)
def ensure_collapsed(self):
"""Collapse the filter bar, if it's not already."""
- if self.is_expanded():
+ if self.expanded:
searchbar = self._get_searchbar()
tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2)
ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2)
m = Mouse()
m.move(tx, ty)
m.click()
- self._wait_for_expansion(False)
-
- def _wait_for_expansion(self, expect_expanded):
- for i in range(11):
- if self.is_expanded() != expect_expanded:
- sleep(1)
- else:
- return
- raise RuntimeError("Filters not %s after waiting for 10 seconds." %
- ("expanded" if expect_expanded else "collapsed"))
+ self.expanded.wait_for(False)
def _get_searchbar(self):
"""Get the searchbar.
diff --git a/tests/autopilot/autopilot/emulators/unity/hud.py b/tests/autopilot/autopilot/emulators/unity/hud.py
index cdd7f6973..9cdb81990 100644
--- a/tests/autopilot/autopilot/emulators/unity/hud.py
+++ b/tests/autopilot/autopilot/emulators/unity/hud.py
@@ -26,15 +26,19 @@ class Hud(KeybindingsHelper):
"""Hides the hud if it's not already hidden."""
if self.visible:
self.toggle_reveal()
+ self.visible.wait_for(False)
def ensure_visible(self):
"""Shows the hud if it's not already showing."""
if not self.visible:
self.toggle_reveal()
+ self.visible.wait_for(True)
def toggle_reveal(self, tap_delay=0.1):
"""Tap the 'Alt' key to toggle the hud visibility."""
+ old_state = self.visible
self.keybinding("hud/reveal", tap_delay)
+ self.visible.wait_for(not old_state)
def get_embedded_icon(self):
"""Returns the HUD view embedded icon or None if is not shown."""
diff --git a/tests/autopilot/autopilot/emulators/unity/icons.py b/tests/autopilot/autopilot/emulators/unity/icons.py
index 09ec6b707..54d5153e9 100644
--- a/tests/autopilot/autopilot/emulators/unity/icons.py
+++ b/tests/autopilot/autopilot/emulators/unity/icons.py
@@ -40,10 +40,6 @@ class SimpleLauncherIcon(UnityIntrospectionObject):
return False
- def is_visible_on_monitor(self, monitor):
- """Returns True if the icon is visible in the defined monitor"""
- return self.visible and self.is_on_monitor(monitor)
-
class BFBLauncherIcon(SimpleLauncherIcon):
"""Represents the BFB button in the launcher."""
@@ -73,7 +69,7 @@ class SoftwareCenterLauncherIcon(BamfLauncherIcon):
"""Represents a launcher icon of a Software Center app."""
-class HudEmbeddedIcon(SimpleLauncherIcon):
+class HudEmbeddedIcon(UnityIntrospectionObject):
"""Proxy object for the hud embedded icon child of the view."""
@property
diff --git a/tests/autopilot/autopilot/emulators/unity/launcher.py b/tests/autopilot/autopilot/emulators/unity/launcher.py
index 4ea7ac097..a6b028972 100644
--- a/tests/autopilot/autopilot/emulators/unity/launcher.py
+++ b/tests/autopilot/autopilot/emulators/unity/launcher.py
@@ -9,6 +9,7 @@
import dbus
import logging
+from testtools.matchers import NotEquals
from time import sleep
from autopilot.emulators.dbus_handler import session_bus
@@ -40,9 +41,6 @@ class LauncherController(UnityIntrospectionObject):
assert(len(models) == 1)
return models[0]
- def key_nav_monitor(self):
- return self.key_nav_launcher_monitor
-
def add_launcher_item_from_position(self,name,icon,icon_x,icon_y,icon_size,desktop_file,aptdaemon_task):
""" Emulate a DBus call from Software Center to pin an icon to the launcher """
launcher_object = session_bus.get_object('com.canonical.Unity.Launcher',
@@ -92,6 +90,11 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper):
self.keybinding_release("launcher/switcher")
self.in_switcher_mode = False
+ def _get_controller(self):
+ """Get the launcher controller."""
+ [controller] = LauncherController.get_all_instances()
+ return controller
+
def move_mouse_to_right_of_launcher(self):
"""Places the mouse to the right of this launcher."""
self._screen.move_mouse_to_monitor(self.monitor)
@@ -127,84 +130,106 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper):
self._screen.move_mouse_to_monitor(self.monitor)
logger.debug("Revealing launcher with keyboard.")
self.keybinding_hold("launcher/reveal")
- sleep(1)
+ self.is_showing.wait_for(True)
def keyboard_unreveal_launcher(self):
"""Un-reveal this launcher using the keyboard."""
self._screen.move_mouse_to_monitor(self.monitor)
logger.debug("Un-revealing launcher with keyboard.")
self.keybinding_release("launcher/reveal")
- sleep(1)
+ # only wait if the launcher is set to autohide
+ if self.hidemode == 1:
+ self.is_showing.wait_for(False)
def key_nav_start(self):
"""Start keyboard navigation mode by pressing Alt+F1."""
self._screen.move_mouse_to_monitor(self.monitor)
logger.debug("Initiating launcher keyboard navigation with Alt+F1.")
self.keybinding("launcher/keynav")
+ self._get_controller().key_nav_is_active.wait_for(True)
self.in_keynav_mode = True
def key_nav_cancel(self):
"""End the key navigation."""
logger.debug("Cancelling keyboard navigation mode.")
self._perform_key_nav_exit_binding("launcher/keynav/exit")
+ self._get_controller().key_nav_is_active.wait_for(False)
def key_nav_activate(self):
"""Activates the selected launcher icon. In the current implementation
this also exits key navigation"""
logger.debug("Ending keyboard navigation mode, activating icon.")
self._perform_key_nav_exit_binding("launcher/keynav/activate")
+ self._get_controller().key_nav_is_active.wait_for(False)
def key_nav_next(self):
"""Moves the launcher keynav focus to the next launcher icon"""
logger.debug("Selecting next item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_key_nav_binding("launcher/keynav/next")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def key_nav_prev(self):
"""Moves the launcher keynav focus to the previous launcher icon"""
logger.debug("Selecting previous item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_key_nav_binding("launcher/keynav/prev")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def key_nav_enter_quicklist(self):
logger.debug("Opening quicklist for currently selected icon.")
self._perform_key_nav_binding("launcher/keynav/open-quicklist")
+ self.quicklist_open.wait_for(True)
def key_nav_exit_quicklist(self):
logger.debug("Closing quicklist for currently selected icon.")
self._perform_key_nav_binding("launcher/keynav/close-quicklist")
+ self.quicklist_open.wait_for(False)
def switcher_start(self):
"""Start the super+Tab switcher on this launcher."""
self._screen.move_mouse_to_monitor(self.monitor)
logger.debug("Starting Super+Tab switcher.")
self.keybinding_hold_part_then_tap("launcher/switcher")
+ self._get_controller().key_nav_is_active.wait_for(True)
self.in_switcher_mode = True
def switcher_cancel(self):
"""End the super+tab swithcer."""
logger.debug("Cancelling keyboard navigation mode.")
self._perform_switcher_exit_binding("launcher/switcher/exit")
+ self._get_controller().key_nav_is_active.wait_for(False)
def switcher_activate(self):
"""Activates the selected launcher icon. In the current implementation
this also exits the switcher"""
logger.debug("Ending keyboard navigation mode.")
self._perform_switcher_exit_binding("launcher/switcher")
+ self._get_controller().key_nav_is_active.wait_for(False)
def switcher_next(self):
logger.debug("Selecting next item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_switcher_binding("launcher/switcher/next")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def switcher_prev(self):
logger.debug("Selecting previous item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_switcher_binding("launcher/switcher/prev")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def switcher_up(self):
logger.debug("Selecting next item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_switcher_binding("launcher/switcher/up")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def switcher_down(self):
logger.debug("Selecting previous item in keyboard navigation mode.")
+ old_selection = self._get_controller().key_nav_selection
self._perform_switcher_binding("launcher/switcher/down")
+ self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
def click_launcher_icon(self, icon, button=1):
"""Move the mouse over the launcher icon, and click it.
@@ -255,15 +280,6 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper):
pin_item = quicklist.get_quicklist_item_by_text('Unlock from Launcher')
quicklist.click_item(pin_item)
- def is_quicklist_open(self):
- return self.quicklist_open
-
- def is_showing(self):
- return not self.hidden
-
- def are_shortcuts_showing(self):
- return self.shortcuts_shown
-
@property
def geometry(self):
"""Returns a tuple of (x,y,w,h) for the current launcher."""
@@ -285,6 +301,13 @@ class LauncherModel(UnityIntrospectionObject):
else:
return self.get_children_by_type(SimpleLauncherIcon)
+ def get_bamf_launcher_icons(self, visible_only=True):
+ """Get a list of bamf launcher icons in this launcher."""
+ if visible_only:
+ return self.get_children_by_type(BamfLauncherIcon, visible=True)
+ else:
+ return self.get_children_by_type(BamfLauncherIcon)
+
def get_launcher_icons_for_monitor(self, monitor, visible_only=True):
"""Get a list of launcher icons for provided monitor."""
icons = []
@@ -304,17 +327,6 @@ class LauncherModel(UnityIntrospectionObject):
return icon
return None
- def get_icon_by_desktop_file(self, desktop_file):
- """Gets a launcher icon with the specified desktop file.
-
- Returns None if there is no such launcher icon.
- """
- icons = self.get_children_by_type(SimpleLauncherIcon, desktop_file=desktop_file)
- if len(icons):
- return icons[0]
-
- return None
-
def get_icon_by_desktop_id(self, desktop_id):
"""Gets a launcher icon with the specified desktop id.
@@ -326,6 +338,23 @@ class LauncherModel(UnityIntrospectionObject):
return None
+ def get_icons_by_filter(self, **kwargs):
+ """Get a list of icons that satisfy the given filters.
+
+ For example:
+
+ >>> get_icons_by_filter(tooltip_text="My Application")
+ ... [...]
+
+ Returns an empty list if no icons matched the filter.
+
+ """
+ return self.get_children_by_type(SimpleLauncherIcon, **kwargs)
+
def num_launcher_icons(self):
"""Get the number of icons in the launcher model."""
return len(self.get_launcher_icons())
+
+ def num_bamf_launcher_icons(self, visible_only=True):
+ """Get the number of bamf icons in the launcher model."""
+ return len(self.get_bamf_launcher_icons(visible_only))
diff --git a/tests/autopilot/autopilot/emulators/unity/quicklist.py b/tests/autopilot/autopilot/emulators/unity/quicklist.py
index 40a8623be..8cb0280f1 100644
--- a/tests/autopilot/autopilot/emulators/unity/quicklist.py
+++ b/tests/autopilot/autopilot/emulators/unity/quicklist.py
@@ -23,7 +23,12 @@ class Quicklist(UnityIntrospectionObject):
@property
def items(self):
"""Individual items in the quicklist."""
- return self.get_children_by_type(QuicklistMenuItem)
+ return self.get_children_by_type(QuicklistMenuItem, visible=True)
+
+ @property
+ def selectable_items(self):
+ """Items that can be selected in the quicklist."""
+ return self.get_children_by_type(QuicklistMenuItem, visible=True, selectable=True)
def get_quicklist_item_by_text(self, text):
"""Returns a QuicklistMenuItemLabel object with the given text, or None."""
@@ -35,22 +40,60 @@ class Quicklist(UnityIntrospectionObject):
return matches[0] if matches else None
+ def get_quicklist_application_item(self, application_name):
+ """Returns the QuicklistMenuItemLabel for the given application_name"""
+ return self.get_quicklist_item_by_text("<b>"+application_name+"</b>")
+
def click_item(self, item):
"""Click one of the quicklist items."""
if not isinstance(item, QuicklistMenuItem):
raise TypeError("Item must be a subclass of QuicklistMenuItem")
- logger.debug("Clicking on quicklist item %r", item)
- mouse = Mouse()
- mouse.move(self.x + item.x + (item.width / 2),
- self.y + item.y + (item.height / 2))
- sleep(0.25)
- mouse.click()
+ item.mouse_click()
+
+ def move_mouse_to_right(self):
+ """Moves the mouse outside the quicklist"""
+ logger.debug("Moving mouse outside the quicklist %r", self)
+ target_x = self.x + self.width + 10
+ target_y = self.y + self.height / 2
+ Mouse().move(target_x, target_y, animate=False)
+
+ @property
+ def selected_item(self):
+ items = self.get_children_by_type(QuicklistMenuItem, selected=True)
+ assert(len(items) <= 1)
+ return items[0] if items else None
+
+ @property
+ def geometry(self):
+ """Returns a tuple of (x,y,w,h) for the quicklist."""
+ return (self.x, self.y, self.width, self.height)
class QuicklistMenuItem(UnityIntrospectionObject):
"""Represents a single item in a quicklist."""
+ def __init__(self, *args, **kwargs):
+ super(QuicklistMenuItem, self).__init__(*args, **kwargs)
+ self._mouse = Mouse()
+
+ @property
+ def geometry(self):
+ """Returns a tuple of (x,y,w,h) for the quicklist item."""
+ return (self.x, self.y, self.width, self.height)
+
+ def mouse_move_to(self):
+ assert(self.visible)
+ logger.debug("Moving mouse over quicklist item %r", self)
+ target_x = self.x + self.width / 2
+ target_y = self.y + self.height / 2
+ self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
+
+ def mouse_click(self, button=1):
+ logger.debug("Clicking on quicklist item %r", self)
+ self.mouse_move_to()
+ self._mouse.click()
+
class QuicklistMenuItemLabel(QuicklistMenuItem):
"""Represents a text label inside a quicklist."""
diff --git a/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py b/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py
index f7d82bd7e..f9d83965c 100644
--- a/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py
+++ b/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py
@@ -20,25 +20,32 @@ class ShortcutController(UnityIntrospectionObject, KeybindingsHelper):
"""ShortcutController proxy class."""
def show(self):
+ """Push the keys necessary to reveal the shortcut hint, but don't block."""
logger.debug("Revealing shortcut hint with keyboard.")
self.keybinding_hold("shortcuthint/reveal")
+ def ensure_visible(self):
+ """Block until the shortcut hint is visible."""
+ if not self.visible:
+ logger.debug("Revealing shortcut hint with keyboard.")
+ self.keybinding_hold("shortcuthint/reveal")
+ self.visible.wait_for(True)
+
def hide(self):
+ """Release the keys keeping the shortcut hint open, but don't block."""
logger.debug("Un-revealing shortcut hint with keyboard.")
self.keybinding_release("shortcuthint/reveal")
+ def ensure_hidden(self):
+ """Block until the shortcut hint is hidden."""
+ if self.visible:
+ logger.debug("Un-revealing shortcut hint with keyboard.")
+ self.keybinding_release("shortcuthint/reveal")
+ self.visible.wait_for(False)
+
def cancel(self):
logger.debug("Hide the shortcut hint with keyboard, without releasing the reveal key.")
self.keybinding("shortcuthint/cancel")
- def get_geometry(self):
- return (self.x, self.y, self.width, self.height)
-
def get_show_timeout(self):
return self.timeout_duration / 1000.0
-
- def is_enabled(self):
- return bool(self.enabled)
-
- def is_visible(self):
- return bool(self.visible)
diff --git a/tests/autopilot/autopilot/emulators/unity/window_manager.py b/tests/autopilot/autopilot/emulators/unity/window_manager.py
new file mode 100644
index 000000000..5e54bd06c
--- /dev/null
+++ b/tests/autopilot/autopilot/emulators/unity/window_manager.py
@@ -0,0 +1,22 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+# Copyright 2012 Canonical
+# Author: Marco Trevisan (Treviño)
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+
+import logging
+from autopilot.emulators.unity import UnityIntrospectionObject
+
+logger = logging.getLogger(__name__)
+
+
+class WindowManager(UnityIntrospectionObject):
+ """The WindowManager class."""
+
+ @property
+ def screen_geometry(self):
+ """Returns a tuple of (x,y,w,h) for the screen."""
+ return (self.x, self.y, self.width, self.height)
diff --git a/tests/autopilot/autopilot/keybindings.py b/tests/autopilot/autopilot/keybindings.py
index da9e0a2e2..1b43cedb9 100644
--- a/tests/autopilot/autopilot/keybindings.py
+++ b/tests/autopilot/autopilot/keybindings.py
@@ -56,7 +56,14 @@ _keys = {
"launcher/switcher/prev": "Shift+Tab",
"launcher/switcher/down": "Down",
"launcher/switcher/up": "Up",
- # Panel
+ # Quicklist:
+ "quicklist/keynav/first": "Home",
+ "quicklist/keynav/last": "End",
+ "quicklist/keynav/next": "Down",
+ "quicklist/keynav/prev": "Up",
+ "quicklist/keynav/activate": "Enter",
+ "quicklist/keynav/exit": "Escape",
+ # Panel:
"panel/show_menus": "Alt",
"panel/open_first_menu": ('unityshell', 'panel_first_menu'),
"panel/next_indicator": "Right",
@@ -65,12 +72,12 @@ _keys = {
"dash/reveal": "Super",
"dash/lens/next": "Ctrl+Tab",
"dash/lens/prev": "Ctrl+Shift+Tab",
- # Lenses
+ # Lenses:
"lens_reveal/command": ("unityshell", "execute_command"),
"lens_reveal/apps": "Super+a",
"lens_reveal/files": "Super+f",
"lens_reveal/music": "Super+m",
- # Hud
+ # Hud:
"hud/reveal": ("unityshell", "show_hud"),
# Switcher:
"switcher/reveal_normal": ("unityshell", "alt_tab_forward"),
@@ -96,7 +103,7 @@ _keys = {
"workspace/move_right": ("wall", "right_key"),
"workspace/move_up": ("wall", "up_key"),
"workspace/move_down": ("wall", "down_key"),
- # Window management
+ # Window management:
"window/show_desktop" : ("core", "show_desktop_key"),
"window/minimize": ("core", "minimize_window_key"),
"window/maximize": ("core", "maximize_window_key"),
@@ -105,6 +112,9 @@ _keys = {
# expo plugin:
"expo/start": ("expo", "expo_key"),
"expo/cancel": "Escape",
+ # spread (scale) plugin:
+ "spread/start": ("scale", "initiate_all_key"),
+ "spread/cancel": "Escape",
}
diff --git a/tests/autopilot/autopilot/matchers/__init__.py b/tests/autopilot/autopilot/matchers/__init__.py
new file mode 100644
index 000000000..f0ac66fbd
--- /dev/null
+++ b/tests/autopilot/autopilot/matchers/__init__.py
@@ -0,0 +1,31 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+# Copyright 2012 Canonical
+# Author: Thomi Richards
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+
+"Autopilot-specific matchers."
+
+from testtools.matchers import Matcher
+
+
+class Eventually(Matcher):
+ """Asserts that a value will eventually equal a given Matcher object."""
+
+ def __init__(self, matcher):
+ super(Eventually, self).__init__()
+ match_fun = getattr(matcher, 'match', None)
+ if match_fun is None or not callable(match_fun):
+ raise TypeError("Eventually must be called with a testtools matcher argument.")
+ self.matcher = matcher
+
+ def match(self, value):
+ wait_fun = getattr(value, 'wait_for', None)
+ if wait_fun is None or not callable(wait_fun):
+ raise TypeError("Eventually can only be used against autopilot attributes that have a wait_for funtion.")
+ wait_fun(self.matcher)
+
+ def __str__(self):
+ return "Eventually " + str(self.matcher)
diff --git a/tests/autopilot/autopilot/tests/__init__.py b/tests/autopilot/autopilot/tests/__init__.py
index d0dd91b4b..e8ed05af0 100644
--- a/tests/autopilot/autopilot/tests/__init__.py
+++ b/tests/autopilot/autopilot/tests/__init__.py
@@ -27,6 +27,7 @@ from autopilot.emulators.unity.hud import Hud
from autopilot.emulators.unity.launcher import LauncherController
from autopilot.emulators.unity.panel import PanelController
from autopilot.emulators.unity.switcher import Switcher
+from autopilot.emulators.unity.window_manager import WindowManager
from autopilot.emulators.unity.workspace import WorkspaceManager
from autopilot.emulators.X11 import ScreenGeometry, Keyboard, Mouse, reset_display
from autopilot.glibrunner import GlibRunner
@@ -223,6 +224,10 @@ class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
'desktop-file': 'remmina.desktop',
'process-name': 'remmina',
},
+ 'System Settings' : {
+ 'desktop-file': 'gnome-control-center.desktop',
+ 'process-name': 'gnome-control-center',
+ },
'Text Editor' : {
'desktop-file': 'gedit.desktop',
'process-name': 'gedit',
@@ -239,6 +244,7 @@ class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
self.launcher = self._get_launcher_controller()
self.panels = self._get_panel_controller()
self.switcher = Switcher()
+ self.window_manager = self._get_window_manager()
self.workspace = WorkspaceManager()
self.screen_geo = ScreenGeometry()
self.addCleanup(self.workspace.switch_to, self.workspace.current_workspace)
@@ -264,14 +270,14 @@ class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
app = self.KNOWN_APPS[app_name]
self.bamf.launch_application(app['desktop-file'], files)
apps = self.bamf.get_running_applications_by_desktop_file(app['desktop-file'])
- self.addCleanup(call, ["killall", app['process-name']])
+ self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True)
self.assertThat(len(apps), Equals(1))
return apps[0]
def close_all_app(self, app_name):
"""Close all instances of the app_name."""
app = self.KNOWN_APPS[app_name]
- call(["killall", app['process-name']])
+ self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True)
super(LoggedTestCase, self).tearDown()
def get_app_instances(self, app_name):
@@ -292,10 +298,10 @@ class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
keyboard layout bits are very unweildy. This seems like the best
solution, even a little bit brutish.
"""
- cmd = ['gsettings', command, schema] + args
+ cmd = ['gsettings', command, schema] + list(args)
# strip to remove the trailing \n.
- ret = check_output(cmd, shell=True).strip()
- time.sleep(1)
+ ret = check_output(cmd).strip()
+ time.sleep(5)
reset_display()
return ret
@@ -336,6 +342,11 @@ class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
self.assertThat(len(controllers), Equals(1))
return controllers[0]
+ def _get_window_manager(self):
+ managers = WindowManager.get_all_instances()
+ self.assertThat(len(managers), Equals(1))
+ return managers[0]
+
def assertVisibleWindowStack(self, stack_start):
"""Check that the visible window stack starts with the windows passed in.
diff --git a/tests/autopilot/autopilot/tests/test_command_lens.py b/tests/autopilot/autopilot/tests/test_command_lens.py
index 121a1b2c1..d142ee92a 100644
--- a/tests/autopilot/autopilot/tests/test_command_lens.py
+++ b/tests/autopilot/autopilot/tests/test_command_lens.py
@@ -9,16 +9,14 @@
from testtools.matchers import Equals
from time import sleep
-from autopilot.emulators.unity.dash import Dash
-from autopilot.emulators.X11 import Keyboard
from autopilot.tests import AutopilotTestCase
+from autopilot.matchers import Eventually
class CommandLensSearchTests(AutopilotTestCase):
"""Test the command lense search bahavior."""
def setUp(self):
- self.dash = Dash()
super(CommandLensSearchTests, self).setUp()
def tearDown(self):
@@ -27,36 +25,33 @@ class CommandLensSearchTests(AutopilotTestCase):
def test_no_results(self):
"""An empty string should get no results."""
- kb = Keyboard()
self.dash.reveal_command_lens()
command_lens = self.dash.get_current_lens()
- if self.dash.get_searchbar().search_string != "":
- kb.press_and_release("Delete")
+ if self.dash.search_string != "":
+ self.keyboard.press_and_release("Delete")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("")))
results_category = command_lens.get_category_by_name("Results")
- self.assertFalse(results_category.is_visible)
+ self.assertThat(results_category.is_visible, Eventually(Equals(False)))
def test_results_category_appears(self):
"""Results category must appear when there are some results."""
- kb = Keyboard()
self.dash.reveal_command_lens()
command_lens = self.dash.get_current_lens()
# lots of apps start with 'a'...
- kb.type("a")
- sleep(1)
+ self.keyboard.type("a")
+ self.assertThat(self.dash.search_string, Eventually(Equals("a")))
results_category = command_lens.get_category_by_name("Results")
- self.assertTrue(results_category.is_visible)
+ self.assertThat(results_category.is_visible, Eventually(Equals(True)))
def test_result_category_actually_contains_results(self):
"""With a search string of 'a', the results category must contain some results."""
- kb = Keyboard()
self.dash.reveal_command_lens()
command_lens = self.dash.get_current_lens()
# lots of apps start with 'a'...
- kb.type("a")
- sleep(1)
+ self.keyboard.type("a")
+ self.assertThat(self.dash.search_string, Eventually(Equals("a")))
results_category = command_lens.get_category_by_name("Results")
results = results_category.get_results()
self.assertTrue(results)
@@ -67,12 +62,11 @@ class CommandLensSearchTests(AutopilotTestCase):
self.close_all_app("Text Editor")
sleep(1)
- kb = Keyboard()
self.dash.reveal_command_lens()
- kb.type("g")
+ self.keyboard.type("g")
sleep(1)
- kb.type("edit", 0.1)
- kb.press_and_release("Enter", 0.1)
+ self.keyboard.type("edit", 0.1)
+ self.keyboard.press_and_release("Enter", 0.1)
self.addCleanup(self.close_all_app, "Text Editor")
app_found = self.bamf.wait_until_application_is_running("gedit.desktop", 5)
self.assertTrue(app_found)
@@ -81,12 +75,10 @@ class CommandLensSearchTests(AutopilotTestCase):
"""Pressing Ctrl+Tab after launching command lens must switch to Home lens."""
self.dash.reveal_command_lens()
self.keybinding("dash/lens/next")
- sleep(1)
- self.assertThat(self.dash.active_lens, Equals("home.lens"))
+ self.assertThat(self.dash.active_lens, Eventually(Equals("home.lens")))
def test_ctrl_shift_tab_switching(self):
"""Pressing Ctrl+Shift+Tab after launching command lens must switch to Video lens."""
self.dash.reveal_command_lens()
self.keybinding("dash/lens/prev")
- sleep(1)
- self.assertThat(self.dash.active_lens, Equals("video.lens"))
+ self.assertThat(self.dash.active_lens, Eventually(Equals("video.lens")))
diff --git a/tests/autopilot/autopilot/tests/test_dash.py b/tests/autopilot/autopilot/tests/test_dash.py
index 0ea1606ed..d2013af94 100644
--- a/tests/autopilot/autopilot/tests/test_dash.py
+++ b/tests/autopilot/autopilot/tests/test_dash.py
@@ -9,8 +9,9 @@
from time import sleep
from gtk import Clipboard
-from testtools.matchers import Equals
+from testtools.matchers import Equals, NotEquals
+from autopilot.matchers import Eventually
from autopilot.tests import AutopilotTestCase
@@ -36,37 +37,35 @@ class DashRevealTests(DashTestCase):
def test_application_lens_shortcut(self):
"""Application lense must reveal when Super+a is pressed."""
self.dash.reveal_application_lens()
- self.assertThat(self.dash.active_lens, Equals('applications.lens'))
+ self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens')))
def test_music_lens_shortcut(self):
"""Music lense must reveal when Super+w is pressed."""
self.dash.reveal_music_lens()
- self.assertThat(self.dash.active_lens, Equals('music.lens'))
+ self.assertThat(self.dash.active_lens, Eventually(Equals('music.lens')))
def test_file_lens_shortcut(self):
"""File lense must reveal when Super+f is pressed."""
self.dash.reveal_file_lens()
- self.assertThat(self.dash.active_lens, Equals('files.lens'))
+ self.assertThat(self.dash.active_lens, Eventually(Equals('files.lens')))
def test_command_lens_shortcut(self):
"""Run Command lens must reveat on alt+F2."""
self.dash.reveal_command_lens()
- self.assertThat(self.dash.active_lens, Equals('commands.lens'))
+ self.assertThat(self.dash.active_lens, Eventually(Equals('commands.lens')))
def test_alt_f4_close_dash(self):
"""Dash must close on alt+F4."""
self.dash.ensure_visible()
self.keyboard.press_and_release("Alt+F4")
- sleep(0.5)
- self.assertFalse(self.dash.visible)
+ self.assertThat(self.dash.visible, Eventually(Equals(False)))
class DashSearchInputTests(DashTestCase):
"""Test features involving input to the dash search"""
def assertSearchText(self, text):
- sleep(0.5)
- self.assertThat(self.dash.search_string, Equals(text))
+ self.assertThat(self.dash.search_string, Eventually(Equals(text)))
def test_search_keyboard_focus(self):
"""Dash must put keyboard focus on the search bar at all times."""
@@ -74,17 +73,15 @@ class DashSearchInputTests(DashTestCase):
self.keyboard.type("Hello")
self.assertSearchText("Hello")
+
class DashMultiKeyTests(DashSearchInputTests):
def setUp(self):
- def set_multi_key():
- """Binds Multi_key to caps lock"""
- old_value = "\"%s\"" % self.call_gsettings_cmd('get', 'org.gnome.libgnomekbd.keyboard', '"options"')
- self.addCleanup(self.call_gsettings_cmd, 'set', 'org.gnome.libgnomekbd.keyboard', '"options"', old_value)
- self.call_gsettings_cmd('set', 'org.gnome.libgnomekbd.keyboard', '"options"', "\"['Compose key\tcompose:caps']\"")
-
# set the multi key first so that we're not getting a new _DISPLAY while keys are held down.
- set_multi_key()
- super(DashMultiKeyTests, self).setUp()
+ old_value = self.call_gsettings_cmd('get', 'org.gnome.libgnomekbd.keyboard', 'options')
+ self.addCleanup(self.call_gsettings_cmd, 'set', 'org.gnome.libgnomekbd.keyboard', 'options', old_value)
+ self.call_gsettings_cmd('set', 'org.gnome.libgnomekbd.keyboard', 'options', "['Compose key\tcompose:caps']")
+
+ super(DashMultiKeyTests, self).setUp()
def test_multi_key(self):
"""Pressing 'Multi_key' must not add any characters to the search."""
@@ -128,7 +125,7 @@ class DashKeyNavTests(DashTestCase):
for i in range(self.dash.get_num_rows()):
self.keyboard.press_and_release("Down")
lensbar = self.dash.view.get_lensbar()
- self.assertIsNot(lensbar.focused_lens_icon, '')
+ self.assertThat(lensbar.focused_lens_icon, Eventually(NotEquals('')))
def test_lensbar_focus_changes(self):
"""Lensbar focused icon should change with Left and Right keypresses."""
@@ -137,13 +134,14 @@ class DashKeyNavTests(DashTestCase):
for i in range(self.dash.get_num_rows()):
self.keyboard.press_and_release("Down")
lensbar = self.dash.view.get_lensbar()
+
current_focused_icon = lensbar.focused_lens_icon
+
self.keyboard.press_and_release("Right");
- lensbar.refresh_state()
- self.assertNotEqual(lensbar.focused_lens_icon, current_focused_icon)
+ self.assertThat(lensbar.focused_lens_icon, Eventually(NotEquals(current_focused_icon)))
+
self.keyboard.press_and_release("Left")
- lensbar.refresh_state()
- self.assertEqual(lensbar.focused_lens_icon, current_focused_icon)
+ self.assertThat(lensbar.focused_lens_icon, Eventually(Equals(current_focused_icon)))
def test_lensbar_enter_activation(self):
"""Must be able to activate LensBar icons that have focus with an Enter keypress."""
@@ -155,64 +153,13 @@ class DashKeyNavTests(DashTestCase):
lensbar = self.dash.view.get_lensbar()
focused_icon = lensbar.focused_lens_icon
self.keyboard.press_and_release("Enter");
- lensbar.refresh_state()
- self.assertEqual(lensbar.active_lens, focused_icon)
+
+ self.assertThat(lensbar.active_lens, Eventually(Equals(focused_icon)))
# lensbar should lose focus after activation.
# TODO this should be a different test to make sure focus
# returns to the correct place.
- self.assertEqual(lensbar.focused_lens_icon, "")
-
- def test_category_header_keynav_autoscroll(self):
- """Tests that the dash scrolls a category header into view when scrolling via
- the keyboard.
-
- Test for lp:919563
- """
-
- reason = """
- False assumptions. Expanding the first category will not necessarily expand enough
- to force the next category header off screen.
- """
- self.skipTest(reason)
-
- self.dash.ensure_visible()
- lens = self.dash.get_current_lens()
-
- # Expand the first category
- self.keyboard.press_and_release("Down")
- self.keyboard.press_and_release("Enter")
- category = app_lens.get_focused_category()
-
- # Get the geometry of that category header.
- x = category.header_x
- y = category.header_y
- w = category.header_width
-
- # Manually scroll the dash.
- mouse.move(x+w+10, y+w+10, True)
- mouse.click(5)
- mouse.click(5)
- mouse.click(5)
-
- cached_y = y
-
- # Focus the search bar with the mouse
- searchbar = self.dash.get_searchbar()
- mouse.move(searchbar.x + 100,
- searchbar.y + searchbar.height / 2,
- True)
- mouse.click()
- sleep(2)
-
- # Then focus again the first category header
- self.keyboard.press_and_release("Down")
- self.keyboard.press_and_release("Enter")
- category = app_lens.get_focused_category()
- y = category.header_y
-
- # Make sure the dash autoscroll
- self.assertTrue(abs(y - cached_y) < 30)
+ self.assertThat(lensbar.focused_lens_icon, Eventually(Equals("")))
def test_category_header_keynav(self):
""" Tests that a category header gets focus when 'down' is pressed after the
@@ -231,28 +178,8 @@ class DashKeyNavTests(DashTestCase):
# Make sure that the category is highlighted.
self.assertTrue(category.header_is_highlighted)
- def test_maintain_highlight(self):
- # Get the geometry of that category header.
- self.skipTest('Not implemented at all. Broken out of another test but not reworked')
- mouse = Mouse()
-
- x = category.header_x
- y = category.header_y
- w = category.header_width
- h = category.header_height
-
- # Move the mouse close the view, and press down.
- mouse.move(x + w + 10,
- y + h / 2,
- True)
- sleep(1)
- self.keyboard.press_and_release("Down")
- lens = self.dash.get_current_lens()
- category = lens.get_focused_category()
- self.assertEqual(category, None)
-
def test_control_tab_lens_cycle(self):
- """ This test makes sure that Ctlr + Tab cycles lenses."""
+ """This test makes sure that Ctrl+Tab cycles lenses."""
self.dash.ensure_visible()
self.keyboard.press('Control')
@@ -268,8 +195,7 @@ class DashKeyNavTests(DashTestCase):
self.keyboard.release('Control')
self.keyboard.release('Shift')
- lensbar.refresh_state()
- self.assertEqual(lensbar.active_lens, u'home.lens')
+ self.assertThat(lensbar.active_lens, Eventually(Equals('home.lens')))
def test_tab_cycle_category_headers(self):
""" Makes sure that pressing tab cycles through the category headers"""
@@ -293,13 +219,12 @@ class DashKeyNavTests(DashTestCase):
self.keyboard.press_and_release('Tab')
self.keyboard.press_and_release('Tab')
- searchbar = self.dash.get_searchbar()
- self.assertTrue(searchbar.expander_has_focus)
+ self.assertThat(self.dash.searchbar.expander_has_focus, Eventually(Equals(True)))
filter_bar = lens.get_filterbar()
- if not searchbar.showing_filters:
+ if not self.dash.searchbar.showing_filters:
self.keyboard.press_and_release('Enter')
- self.assertTrue(searchbar.showing_filters)
+ self.assertThat(self.dash.searchbar.showing_filters, Eventually(Equals(True)))
self.addCleanup(filter_bar.ensure_collapsed)
for i in range(filter_bar.get_num_filters()):
@@ -315,10 +240,11 @@ class DashKeyNavTests(DashTestCase):
def test_alt_f1_disabled(self):
"""This test that Alt+F1 is disabled when the dash is opened."""
self.dash.ensure_visible()
-
- launcher = self.launcher.get_launcher_for_monitor(0)
- launcher.key_nav_start()
-
+ # can't use launcher emulator since we'll fail to start keynav:
+ self.keybinding("launcher/keynav")
+ # can't use Eventually here - sleep long enough for the launcher controller
+ # to react to the keypress (well, hopefully not)
+ sleep(5)
self.assertThat(self.launcher.key_nav_is_active, Equals(False))
@@ -330,41 +256,35 @@ class DashClipboardTests(DashTestCase):
self.dash.ensure_visible()
self.keyboard.type("SelectAll")
- sleep(1)
- self.assertThat(self.dash.search_string, Equals('SelectAll'))
+ self.assertThat(self.dash.search_string, Eventually(Equals("SelectAll")))
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Delete")
- self.assertThat(self.dash.search_string, Equals(''))
+ self.assertThat(self.dash.search_string, Eventually(Equals('')))
def test_ctrl_c(self):
""" This test if ctrl+c copies text into the clipboard """
self.dash.ensure_visible()
self.keyboard.type("Copy")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("Copy")))
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Ctrl+c")
cb = Clipboard(selection="CLIPBOARD")
-
- searchbar = self.dash.get_searchbar()
- self.assertEqual(searchbar.search_string, cb.wait_for_text())
+ self.assertThat(self.dash.search_string, Eventually(Equals(cb.wait_for_text())))
def test_ctrl_x(self):
""" This test if ctrl+x deletes all text and copys it """
self.dash.ensure_visible()
self.keyboard.type("Cut")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("Cut")))
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Ctrl+x")
- sleep(1)
-
- searchbar = self.dash.get_searchbar()
- self.assertEqual(searchbar.search_string, u'')
+ self.assertThat(self.dash.search_string, Eventually(Equals("")))
cb = Clipboard(selection="CLIPBOARD")
self.assertEqual(cb.wait_for_text(), u'Cut')
@@ -374,30 +294,28 @@ class DashClipboardTests(DashTestCase):
self.dash.ensure_visible()
self.keyboard.type("CopyPaste")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("CopyPaste")))
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Ctrl+c")
self.keyboard.press_and_release("Ctrl+v")
self.keyboard.press_and_release("Ctrl+v")
- searchbar = self.dash.get_searchbar()
- self.assertEqual(searchbar.search_string, u'CopyPasteCopyPaste')
+ self.assertThat(self.dash.search_string, Eventually(Equals('CopyPasteCopyPaste')))
def test_ctrl_x_v(self):
""" This test if ctrl+x and ctrl+v cuts and pastes text"""
self.dash.ensure_visible()
self.keyboard.type("CutPaste")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("CutPaste")))
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Ctrl+x")
self.keyboard.press_and_release("Ctrl+v")
self.keyboard.press_and_release("Ctrl+v")
- searchbar = self.dash.get_searchbar()
- self.assertEqual(searchbar.search_string, u'CutPasteCutPaste')
+ self.assertThat(self.dash.search_string, Eventually(Equals('CutPasteCutPaste')))
class DashKeyboardFocusTests(DashTestCase):
@@ -415,7 +333,7 @@ class DashKeyboardFocusTests(DashTestCase):
filter_bar.ensure_expanded()
self.addCleanup(filter_bar.ensure_collapsed)
self.keyboard.type(" world")
- self.assertThat(self.dash.search_string, Equals("hello world"))
+ self.assertThat(self.dash.search_string, Eventually(Equals("hello world")))
class DashLensResultsTests(DashTestCase):
@@ -425,48 +343,50 @@ class DashLensResultsTests(DashTestCase):
"""This tests a message is not shown when there is no text."""
self.dash.reveal_application_lens()
lens = self.dash.get_current_lens()
- self.assertFalse(lens.no_results_active)
+ self.assertThat(lens.no_results_active, Eventually(Equals(False)))
def test_results_message(self):
"""This test no mesage will be shown when results are there."""
self.dash.reveal_application_lens()
self.keyboard.type("Terminal")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("Terminal")))
lens = self.dash.get_current_lens()
- self.assertFalse(lens.no_results_active)
+ self.assertThat(lens.no_results_active, Eventually(Equals(False)))
def test_no_results_message(self):
"""This test shows a message will appear in the lens."""
self.dash.reveal_application_lens()
self.keyboard.type("qwerlkjzvxc")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("qwerlkjzvxc")))
lens = self.dash.get_current_lens()
- self.assertTrue(lens.no_results_active)
+ self.assertThat(lens.no_results_active, Eventually(Equals(True)))
def test_results_update_on_filter_changed(self):
"""This test makes sure the results change when filters change."""
self.dash.reveal_application_lens()
lens = self.dash.get_current_lens()
self.keyboard.type(" ")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals(" ")))
results_category = lens.get_category_by_name("Installed")
old_results = results_category.get_results()
-
+ # FIXME: This should be a method on the dash emulator perhaps, or
+ # maybe a proper method of this class. It should NOT be an inline
+ # function that is only called once!
def activate_filter(add_cleanup = False):
# Tabs to last category
for i in range(lens.get_num_visible_categories()):
self.keyboard.press_and_release('Tab')
self.keyboard.press_and_release('Tab')
- searchbar = self.dash.get_searchbar()
- self.assertTrue(searchbar.expander_has_focus)
+ self.assertThat(self.dash.searchbar.expander_has_focus, Eventually(Equals(True)))
filter_bar = lens.get_filterbar()
- if not searchbar.showing_filters:
+ if not self.dash.searchbar.showing_filters:
self.keyboard.press_and_release('Enter')
- self.assertTrue(searchbar.showing_filters)
- if add_cleanup: self.addCleanup(filter_bar.ensure_collapsed)
+ self.assertThat(self.dash.searchbar.showing_filters, Eventually(Equals(True)))
+ if add_cleanup:
+ self.addCleanup(filter_bar.ensure_collapsed)
# Tab to the "Type" filter in apps lens
self.keyboard.press_and_release('Tab')
@@ -482,7 +402,6 @@ class DashLensResultsTests(DashTestCase):
activate_filter(True)
self.addCleanup(activate_filter)
- sleep(1)
results_category = lens.get_category_by_name("Installed")
results = results_category.get_results()
self.assertIsNot(results, old_results)
@@ -509,8 +428,10 @@ class DashVisualTests(DashTestCase):
name_label_y = group.name_label_y + group.name_label_baseline
self.assertThat(expand_label_y, Equals(name_label_y))
+
class DashLensBarTests(DashTestCase):
"""Tests that the lensbar works well."""
+
def setUp(self):
super(DashLensBarTests, self).setUp()
self.dash.ensure_visible()
@@ -522,9 +443,47 @@ class DashLensBarTests(DashTestCase):
"""
app_icon = self.lensbar.get_icon_by_name(u'applications.lens')
- self.mouse.move(app_icon.x, app_icon.y)
+ self.mouse.move(app_icon.x + (app_icon.width / 2),
+ app_icon.y + (app_icon.height / 2))
+ self.mouse.click()
+
+ self.assertThat(self.lensbar.active_lens, Eventually(Equals('applications.lens')))
+
+
+class DashBorderTests(DashTestCase):
+ """Tests that the dash border works well.
+ """
+ def setUp(self):
+ super(DashBorderTests, self).setUp()
+ self.dash.ensure_visible()
+
+ def test_click_right_border(self):
+ """Clicking on the right dash border should do nothing,
+ *NOT* close the dash.
+ """
+ if (self.dash.view.form_factor != "desktop"):
+ self.skip("Not in desktop form-factor.")
+
+ x = self.dash.view.x + self.dash.view.width + self.dash.view.right_border_width / 2;
+ y = self.dash.view.y + self.dash.view.height / 2;
+
+ self.mouse.move(x, y)
+ self.mouse.click()
+
+ self.assertThat(self.dash.visible, Eventually(Equals(True)))
+
+ def test_click_bottom_border(self):
+ """Clicking on the bottom dash border should do nothing,
+ *NOT* close the dash.
+ """
+ if (self.dash.view.form_factor != "desktop"):
+ self.skip("Not in desktop form-factor.")
+
+ x = self.dash.view.x + self.dash.view.width / 2;
+ y = self.dash.view.y + self.dash.view.height + self.dash.view.bottom_border_height / 2;
+
+ self.mouse.move(x, y)
self.mouse.click()
- sleep(1)
+ self.assertThat(self.dash.visible, Eventually(Equals(True)))
- self.assertEqual(self.lensbar.active_lens, u'applications.lens')
diff --git a/tests/autopilot/autopilot/tests/test_home_lens.py b/tests/autopilot/autopilot/tests/test_home_lens.py
index 5c5e2c7e8..4509a3664 100644
--- a/tests/autopilot/autopilot/tests/test_home_lens.py
+++ b/tests/autopilot/autopilot/tests/test_home_lens.py
@@ -6,8 +6,10 @@
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
+from testtools.matchers import Equals
from time import sleep
+from autopilot.matchers import Eventually
from autopilot.tests import AutopilotTestCase
@@ -30,7 +32,7 @@ class HomeLensSearchTests(AutopilotTestCase):
kb = self.keyboard
self.dash.ensure_visible()
kb.type("g")
- sleep(1)
+ self.assertThat(self.dash.search_string, Eventually(Equals("g")))
kb.type("edit", 0.1)
kb.press_and_release("Enter", 0.1)
self.addCleanup(self.close_all_app, "Text Editor")
diff --git a/tests/autopilot/autopilot/tests/test_hud.py b/tests/autopilot/autopilot/tests/test_hud.py
index afe06da66..447d85cb9 100644
--- a/tests/autopilot/autopilot/tests/test_hud.py
+++ b/tests/autopilot/autopilot/tests/test_hud.py
@@ -7,13 +7,21 @@
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
-from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
+from os import remove
+from testtools.matchers import (
+ Equals,
+ EndsWith,
+ GreaterThan,
+ LessThan,
+ NotEquals,
+ )
from time import sleep
-from autopilot.emulators.X11 import ScreenGeometry
from autopilot.emulators.unity.icons import HudLauncherIcon
+from autopilot.emulators.X11 import ScreenGeometry
+from autopilot.matchers import Eventually
from autopilot.tests import AutopilotTestCase, multiply_scenarios
-from os import remove, path
+
def _make_monitor_scenarios():
@@ -45,14 +53,6 @@ class HudTestsBase(AutopilotTestCase):
num_active += 1
return num_active
- def reveal_hud(self):
- self.hud.toggle_reveal()
- for counter in range(10):
- sleep(1)
- if self.hud.visible:
- break
- self.assertTrue(self.hud.visible, "HUD did not appear.")
-
class HudBehaviorTests(HudTestsBase):
@@ -63,60 +63,64 @@ class HudBehaviorTests(HudTestsBase):
self.screen_geo.move_mouse_to_monitor(self.hud_monitor)
def test_no_initial_values(self):
- self.reveal_hud()
+ self.hud.ensure_visible()
self.assertThat(self.hud.num_buttons, Equals(0))
self.assertThat(self.hud.selected_button, Equals(0))
def test_check_a_values(self):
- self.reveal_hud()
+ self.hud.ensure_visible()
self.keyboard.type('a')
- # Give the HUD a second to get values.
- sleep(1)
- self.assertThat(self.hud.num_buttons, Equals(5))
- self.assertThat(self.hud.selected_button, Equals(1))
+ self.assertThat(self.hud.search_string, Eventually(Equals('a')))
+ self.assertThat(self.hud.num_buttons, Eventually(Equals(5)))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(1)))
def test_up_down_arrows(self):
- self.reveal_hud()
+ self.hud.ensure_visible()
self.keyboard.type('a')
- # Give the HUD a second to get values.
- sleep(1)
+ self.assertThat(self.hud.search_string, Eventually(Equals('a')))
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(2))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(2)))
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(3))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(3)))
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(4))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(4)))
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(5))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(5)))
# Down again stays on 5.
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(5))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(5)))
self.keyboard.press_and_release('Up')
- self.assertThat(self.hud.selected_button, Equals(4))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(4)))
self.keyboard.press_and_release('Up')
- self.assertThat(self.hud.selected_button, Equals(3))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(3)))
self.keyboard.press_and_release('Up')
- self.assertThat(self.hud.selected_button, Equals(2))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(2)))
self.keyboard.press_and_release('Up')
- self.assertThat(self.hud.selected_button, Equals(1))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(1)))
# Up again stays on 1.
self.keyboard.press_and_release('Up')
- self.assertThat(self.hud.selected_button, Equals(1))
+ self.assertThat(self.hud.selected_button, Eventually(Equals(1)))
def test_no_reset_selected_button(self):
- self.reveal_hud()
+ """Hud must not change selected button when results update over time."""
+ # TODO - this test doesn't test anything. Onmy system the results never update.
+ # ideally we'd send artificial results to the hud from the test.
+ self.hud.ensure_visible()
self.keyboard.type('is')
- sleep(1)
+ self.assertThat(self.hud.search_string, Eventually(Equals('is')))
self.keyboard.press_and_release('Down')
- self.assertThat(self.hud.selected_button, Equals(2))
- # long sleep to let the service send updated results
+ self.assertThat(self.hud.selected_button, Eventually(Equals(2)))
+ # long sleep to let the service send updated results
sleep(10)
self.assertThat(self.hud.selected_button, Equals(2))
def test_slow_tap_not_reveal_hud(self):
- self.hud.toggle_reveal(tap_delay=0.3)
- sleep(1)
- self.assertFalse(self.hud.visible)
+ """A slow tap must not reveal the HUD."""
+ self.keybinding("hud/reveal", 0.3)
+ # need a long sleep to ensure that we test after the hud controller has
+ # seen the keypress.
+ sleep(5)
+ self.assertThat(self.hud.visible, Equals(False))
def test_alt_f4_doesnt_show_hud(self):
self.start_app('Calculator')
@@ -127,71 +131,57 @@ class HudBehaviorTests(HudTestsBase):
self.assertFalse(self.hud.visible)
def test_reveal_hud_with_no_apps(self):
- """Hud must show even with no visible applications."""
+ """Hud must show even with no visible applications.
+
+ This used to cause unity to crash (hence the lack of assertion in this test).
+
+ """
self.keybinding("window/show_desktop")
self.addCleanup(self.keybinding, "window/show_desktop")
sleep(1)
- self.hud.toggle_reveal()
- sleep(1)
- self.assertTrue(self.hud.visible)
-
- self.hud.toggle_reveal()
- sleep(1)
- self.assertFalse(self.hud.visible)
+ self.hud.ensure_visible()
+ self.hud.ensure_hidden()
def test_restore_focus(self):
"""Ensures that once the hud is dismissed, the same application
- that was focused before hud invocation is refocused
+ that was focused before hud invocation is refocused.
"""
calc = self.start_app("Calculator")
# first ensure that the application has started and is focused
self.assertEqual(calc.is_active, True)
- self.hud.toggle_reveal()
- sleep(1)
- self.hud.toggle_reveal()
- sleep(1)
+ self.hud.ensure_visible()
+ self.hud.ensure_hidden()
# again ensure that the application we started is focused
self.assertEqual(calc.is_active, True)
- #test return
- self.hud.toggle_reveal()
- sleep(1)
-
- #test return
- self.hud.toggle_reveal()
- sleep(1)
+ self.hud.ensure_visible()
+ self.hud.ensure_hidden()
+ # why do we do this: ???
self.keyboard.press_and_release('Return')
sleep(1)
self.assertEqual(calc.is_active, True)
def test_gedit_undo(self):
- """Test undo in gedit"""
- """Type "0 1" into gedit."""
- """Activate the Hud, type "undo" then enter."""
- """Save the file in gedit and close gedit."""
- """Read the saved file. The content should be "0 "."""
+ """Test that the 'undo' action in the Hud works with GEdit."""
self.addCleanup(remove, '/tmp/autopilot_gedit_undo_test_temp_file.txt')
self.start_app('Text Editor', files=['/tmp/autopilot_gedit_undo_test_temp_file.txt'], locale='C')
- sleep(1)
self.keyboard.type("0")
self.keyboard.type(" ")
self.keyboard.type("1")
- self.hud.toggle_reveal()
- sleep(1)
+ self.hud.ensure_visible()
self.keyboard.type("undo")
- sleep(1)
+ self.assertThat(self.hud.search_string, Eventually(Equals("undo")))
self.keyboard.press_and_release('Return')
- sleep(.5)
-
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
self.keyboard.press_and_release("Ctrl+s")
sleep(1)
@@ -199,56 +189,49 @@ class HudBehaviorTests(HudTestsBase):
self.assertEqual("0 ", contents)
def test_disabled_alt_f1(self):
- """This test shows that Alt+F1 mode is disabled for the hud."""
- self.hud.toggle_reveal()
+ """Pressing Alt+F1 when the HUD is open must not start keyboard navigation mode."""
+ self.hud.ensure_visible()
- launcher = self.launcher.get_launcher_for_monitor(0)
- launcher.key_nav_start()
+ self.keybinding("launcher/keynav")
+ # we need a sleep here to ensure that the launcher has had time to start
+ # keynav before we check the key_nav_is_active attribute.
+ #
+ # Ideally we'd do 'key_nav_is_active, Eventually(Equals(True)' and expect a test
+ # failure.
+ sleep(1)
self.assertThat(self.launcher.key_nav_is_active, Equals(False))
def test_hud_to_dash_disabled_alt_f1(self):
"""When switching from the hud to the dash alt+f1 is disabled."""
- self.hud.toggle_reveal()
- sleep(1)
-
+ self.hud.ensure_visible()
self.dash.ensure_visible()
-
- launcher = self.launcher.get_launcher_for_monitor(0)
- launcher.key_nav_start()
-
- self.dash.ensure_hidden()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ self.keybinding("launcher/keynav")
self.assertThat(self.launcher.key_nav_is_active, Equals(False))
def test_hud_to_dash_has_key_focus(self):
"""When switching from the hud to the dash you don't lose key focus."""
self.hud.ensure_visible()
- sleep(1)
-
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
-
self.keyboard.type('focus1')
-
- self.assertEqual(self.dash.search_string, 'focus1')
+ self.assertThat(self.dash.search_string, Eventually(Equals('focus1')))
def test_dash_to_hud_has_key_focus(self):
"""When switching from the dash to the hud you don't lose key focus."""
self.dash.ensure_visible()
self.hud.ensure_visible()
- sleep(1)
-
self.keyboard.type('focus2')
-
- self.assertEqual(self.hud.search_string, 'focus2')
+ self.assertThat(self.hud.search_string, Eventually(Equals('focus2')))
def test_hud_closes_on_workspace_switch(self):
"""This test shows that when you switch to another workspace the hud closes."""
- self.hud.toggle_reveal()
- sleep(1)
-
+ self.hud.ensure_visible()
self.workspace.switch_to(1)
self.workspace.switch_to(2)
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
class HudLauncherInteractionsTests(HudTestsBase):
@@ -287,9 +270,7 @@ class HudLauncherInteractionsTests(HudTestsBase):
# reveal and hide hud several times over:
for i in range(3):
self.hud.ensure_visible()
- sleep(0.5)
self.hud.ensure_hidden()
- sleep(0.5)
# click application icons for running apps in the launcher:
icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop")
@@ -300,17 +281,13 @@ class HudLauncherInteractionsTests(HudTestsBase):
self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!")
def test_hud_does_not_change_launcher_status(self):
- """Tests if the HUD reveal keeps the launcher in the status it was"""
+ """Opening the HUD must not change the launcher visibility."""
launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor)
- launcher_shows_pre = launcher.is_showing()
- sleep(.25)
-
- self.reveal_hud()
- sleep(1)
-
- launcher_shows_post = launcher.is_showing()
+ launcher_shows_pre = launcher.is_showing
+ self.hud.ensure_visible()
+ launcher_shows_post = launcher.is_showing
self.assertThat(launcher_shows_pre, Equals(launcher_shows_post))
@@ -328,26 +305,26 @@ class HudLockedLauncherInteractionsTests(HudTestsBase):
sleep(0.5)
def test_hud_launcher_icon_hides_bfb(self):
- """Tests that the BFB icon is hidden when the HUD launcher icon is shown"""
+ """BFB icon must be hidden when the HUD launcher icon is shown."""
hud_icon = self.hud.get_launcher_icon()
bfb_icon = self.launcher.model.get_bfb_icon()
- self.assertTrue(bfb_icon.is_visible_on_monitor(self.hud_monitor))
- self.assertFalse(hud_icon.is_visible_on_monitor(self.hud_monitor))
- sleep(.25)
+ self.assertThat(bfb_icon.visible, Eventually(Equals(True)))
+ self.assertTrue(bfb_icon.is_on_monitor(self.hud_monitor))
+ self.assertThat(hud_icon.visible, Eventually(Equals(False)))
- self.reveal_hud()
- sleep(.5)
+ self.hud.ensure_visible()
- self.assertTrue(hud_icon.is_visible_on_monitor(self.hud_monitor))
- self.assertFalse(bfb_icon.is_visible_on_monitor(self.hud_monitor))
+ self.assertThat(hud_icon.visible, Eventually(Equals(True)))
+ self.assertTrue(hud_icon.is_on_monitor(self.hud_monitor))
+ # For some reason the BFB icon is always visible :-/
+ #bfb_icon.visible, Eventually(Equals(False)
def test_hud_desaturates_launcher_icons(self):
- """Tests that the launcher icons are desaturates when HUD is open"""
+ """Launcher icons must desaturate when the HUD is opened."""
- self.reveal_hud()
- sleep(.5)
+ self.hud.ensure_visible()
for icon in self.launcher.model.get_launcher_icons_for_monitor(self.hud_monitor):
if isinstance(icon, HudLauncherIcon):
@@ -355,6 +332,18 @@ class HudLockedLauncherInteractionsTests(HudTestsBase):
else:
self.assertTrue(icon.desaturated)
+ def test_hud_launcher_icon_click_hides_hud(self):
+ """Clicking the Hud Icon should hide the HUD"""
+
+ hud_icon = self.hud.get_launcher_icon()
+ self.hud.ensure_visible()
+
+ launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor)
+ launcher.click_launcher_icon(hud_icon)
+
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
+ self.assertThat(hud_icon.visible, Eventually(Equals(False)))
+
class HudVisualTests(HudTestsBase):
@@ -379,14 +368,14 @@ class HudVisualTests(HudTestsBase):
self.assertFalse(self.hud.visible)
def test_hud_is_on_right_monitor(self):
- """Tests if the hud is shown and fits the monitor where it should be"""
- self.reveal_hud()
- self.assertThat(self.hud_monitor, Equals(self.hud.monitor))
+ """HUD must be drawn on the monitor where the mouse is."""
+ self.hud.ensure_visible()
+ self.assertThat(self.hud.monitor, Eventually(Equals(self.hud_monitor)))
self.assertTrue(self.screen_geo.is_rect_on_monitor(self.hud.monitor, self.hud.geometry))
def test_hud_geometries(self):
- """Tests the HUD geometries for the given monitor and status"""
- self.reveal_hud()
+ """Tests the HUD geometries for the given monitor and status."""
+ self.hud.ensure_visible()
monitor_geo = self.screen_geo.get_monitor_geometry(self.hud_monitor)
monitor_x = monitor_geo[0]
monitor_w = monitor_geo[2]
@@ -402,76 +391,83 @@ class HudVisualTests(HudTestsBase):
self.assertThat(hud_w, Equals(monitor_w))
def test_hud_is_locked_to_launcher(self):
- """Tests if the HUD is locked to launcher as we expect or not"""
- self.reveal_hud()
- sleep(.25)
-
- self.assertThat(self.hud.is_locked_launcher, Equals(self.hud_locked))
+ """Tests if the HUD is locked to launcher as we expect or not."""
+ self.hud.ensure_visible()
+ self.assertThat(self.hud.is_locked_launcher, Eventually(Equals(self.hud_locked)))
def test_hud_icon_is_shown(self):
- """Tests that the correct HUD icon is shown"""
- self.reveal_hud()
- sleep(.5)
-
+ """Tests that the correct HUD icon is shown."""
+ self.hud.ensure_visible()
hud_launcher_icon = self.hud.get_launcher_icon()
hud_embedded_icon = self.hud.get_embedded_icon()
if self.hud.is_locked_launcher:
- self.assertTrue(hud_launcher_icon.is_visible_on_monitor(self.hud_monitor))
+ self.assertThat(hud_launcher_icon.visible, Eventually(Equals(True)))
+ self.assertTrue(hud_launcher_icon.is_on_monitor(self.hud_monitor))
self.assertTrue(hud_launcher_icon.active)
self.assertThat(hud_launcher_icon.monitor, Equals(self.hud_monitor))
self.assertFalse(hud_launcher_icon.desaturated)
self.assertThat(hud_embedded_icon, Equals(None))
else:
- self.assertFalse(hud_launcher_icon.is_visible_on_monitor(self.hud_monitor))
+ self.assertThat(hud_launcher_icon.visible, Eventually(Equals(False)))
self.assertFalse(hud_launcher_icon.active)
+ # the embedded icon has no visible property.
self.assertThat(hud_embedded_icon, NotEquals(None))
def test_hud_icon_shows_the_focused_application_emblem(self):
- """Tests that the correct HUD icon is shown"""
+ """Tests that the correct HUD icon is shown."""
self.close_all_app("Calculator")
calc = self.start_app("Calculator")
self.assertTrue(calc.is_active)
+ self.hud.ensure_visible()
- self.reveal_hud()
- sleep(.5)
-
- self.assertThat(self.hud.icon.icon_name, Equals(calc.icon))
+ self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon)))
def test_hud_icon_shows_the_ubuntu_emblem_on_empty_desktop(self):
+ """When in 'show desktop' mode the hud icon must be the BFB icon."""
self.keybinding("window/show_desktop")
self.addCleanup(self.keybinding, "window/show_desktop")
sleep(1)
+ self.hud.ensure_visible()
- self.reveal_hud()
- sleep(.5)
-
- self.assertThat(path.basename(self.hud.icon.icon_name), Equals("launcher_bfb.png"))
+ self.assertThat(self.hud.icon.icon_name, Eventually(EndsWith("launcher_bfb.png")))
def test_switch_dash_hud_does_not_break_the_focused_application_emblem(self):
- """Tests that the correct HUD icon is shown when switching from Dash to HUD"""
+ """Switching from Dash to HUD must still show the correct HUD icon."""
self.close_all_app("Calculator")
calc = self.start_app("Calculator")
self.assertTrue(calc.is_active)
self.dash.ensure_visible()
- self.reveal_hud()
- sleep(.5)
+ self.hud.ensure_visible()
- self.assertThat(self.hud.icon.icon_name, Equals(calc.icon))
+ self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon)))
def test_switch_hud_dash_does_not_break_the_focused_application_emblem(self):
- """Tests that the correct HUD icon is shown when switching from HUD to Dash and back"""
+ """Switching from HUD to Dash and back must still show the correct HUD icon."""
self.close_all_app("Calculator")
calc = self.start_app("Calculator")
self.assertTrue(calc.is_active)
- self.reveal_hud()
+ self.hud.ensure_visible()
self.dash.ensure_visible()
- self.reveal_hud()
- sleep(.5)
+ self.hud.ensure_visible()
+ self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon)))
+
+ def test_dash_hud_only_uses_icon_from_current_desktop(self):
+ """
+ Switching from the dash to Hud must pick an icon from applications
+ from the current desktop. As the Hud must go through the entire window
+ stack to find the top most window.
+ """
+ self.workspace.switch_to(0)
+ calc = self.start_app("Calculator")
+ self.assertTrue(calc.is_active)
+ self.workspace.switch_to(2)
+ self.dash.ensure_visible()
+ self.hud.ensure_visible()
- self.assertThat(self.hud.icon.icon_name, Equals(calc.icon))
+ self.assertThat(self.hud.icon.icon_name, Eventually(EndsWith("launcher_bfb.png")))
class HudAlternativeKeybindingTests(HudTestsBase):
@@ -481,19 +477,11 @@ class HudAlternativeKeybindingTests(HudTestsBase):
self.set_unity_option("show_hud", "<Super>h")
# Don't use reveal_hud, but be explicit in the keybindings.
self.keyboard.press_and_release("Super+h")
- for counter in range(10):
- sleep(1)
- if self.hud.visible:
- break
- self.assertTrue(self.hud.visible, "HUD did not appear.")
+ self.assertThat(self.hud.visible, Eventually(Equals(True)))
def test_ctrl_alt_h(self):
"""Test hud reveal on <Contrl><Alt>h."""
self.set_unity_option("show_hud", "<Control><Alt>h")
# Don't use reveal_hud, but be explicit in the keybindings.
self.keyboard.press_and_release("Ctrl+Alt+h")
- for counter in range(10):
- sleep(1)
- if self.hud.visible:
- break
- self.assertTrue(self.hud.visible, "HUD did not appear.")
+ self.assertThat(self.hud.visible, Eventually(Equals(True)))
diff --git a/tests/autopilot/autopilot/tests/test_ibus.py b/tests/autopilot/autopilot/tests/test_ibus.py
index 86dd839e7..b78a32d47 100644
--- a/tests/autopilot/autopilot/tests/test_ibus.py
+++ b/tests/autopilot/autopilot/tests/test_ibus.py
@@ -8,12 +8,13 @@
"""Tests to ensure unity is compatible with ibus input method."""
-from time import sleep
+from testtools.matchers import Equals, NotEquals
from autopilot.emulators.ibus import (
set_active_engines,
get_available_input_engines,
)
+from autopilot.matchers import Eventually
from autopilot.tests import AutopilotTestCase, multiply_scenarios
@@ -22,32 +23,68 @@ class IBusTests(AutopilotTestCase):
def setUp(self):
super(IBusTests, self).setUp()
- self._old_engines = None
def tearDown(self):
- if self._old_engines is not None:
- set_active_engines(self._old_engines)
super(IBusTests, self).tearDown()
- def activate_input_engine_or_skip(self, engine_name):
+ @classmethod
+ def setUpClass(cls):
+ cls._old_engines = None
+ cls.activate_input_engine_or_skip(cls.engine_name)
+
+ @classmethod
+ def tearDownClass(cls):
+ if cls._old_engines is not None:
+ set_active_engines(cls._old_engines)
+
+ @classmethod
+ def activate_input_engine_or_skip(cls, engine_name):
available_engines = get_available_input_engines()
if engine_name in available_engines:
- self._old_engines = set_active_engines([engine_name])
+ cls._old_engines = set_active_engines([engine_name])
else:
- self.skipTest("This test requires the '%s' engine to be installed." % (engine_name))
+ raise AutopilotTestCase.skipException("This test requires the '%s' engine to be installed." % (engine_name))
+
+ def activate_ibus(self, widget):
+ """Activate IBus, and wait till it's actived on 'widget'"""
+ self.assertThat(widget.im_active, Equals(False))
+ self.keyboard.press_and_release('Ctrl+Space', 0.05)
+ self.assertThat(widget.im_active, Eventually(Equals(True)))
- def activate_ibus(self):
- # it would be nice to be able to tell if it's currently active or not.
- self.keyboard.press_and_release('Ctrl+Space')
+ def deactivate_ibus(self, widget):
+ """Deactivate ibus, and wait till it's inactive on 'widget'"""
+ self.assertThat(widget.im_active, Equals(True))
+ self.keyboard.press_and_release('Ctrl+Space', 0.05)
+ self.assertThat(widget.im_active, Eventually(Equals(False)))
+
+ def do_dash_test_with_engine(self):
+ self.dash.ensure_visible()
+ self.addCleanup(self.dash.ensure_hidden)
+ self.activate_ibus(self.dash.searchbar)
+ self.keyboard.type(self.input)
+ commit_key = getattr(self, 'commit_key', None)
+ if commit_key:
+ self.keyboard.press_and_release(commit_key)
+ self.deactivate_ibus(self.dash.searchbar)
+ self.assertThat(self.dash.search_string, Eventually(Equals(self.result)))
- def deactivate_ibus(self):
- # it would be nice to be able to tell if it's currently active or not.
- self.keyboard.press_and_release('Ctrl+Space')
+ def do_hud_test_with_engine(self):
+ self.hud.ensure_visible()
+ self.addCleanup(self.hud.ensure_hidden)
+ self.activate_ibus(self.hud.searchbar)
+ self.keyboard.type(self.input)
+ commit_key = getattr(self, 'commit_key', None)
+ if commit_key:
+ self.keyboard.press_and_release(commit_key)
+ self.deactivate_ibus(self.hud.searchbar)
+ self.assertThat(self.hud.search_string, Eventually(Equals(self.result)))
class IBusTestsPinyin(IBusTests):
"""Tests for the Pinyin(Chinese) input engine."""
+ engine_name = "pinyin"
+
scenarios = [
('basic', {'input': 'abc1', 'result': u'\u963f\u5e03\u4ece'}),
('photo', {'input': 'zhaopian ', 'result': u'\u7167\u7247'}),
@@ -57,35 +94,17 @@ class IBusTestsPinyin(IBusTests):
]
def test_simple_input_dash(self):
- self.activate_input_engine_or_skip("pinyin")
- self.dash.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- dash_search_string = self.dash.search_string
- self.deactivate_ibus()
- self.dash.ensure_hidden()
-
- self.assertEqual(self.result, dash_search_string)
+ self.do_dash_test_with_engine()
def test_simple_input_hud(self):
- self.activate_input_engine_or_skip("pinyin")
- self.hud.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- hud_search_string = self.hud.search_string
- self.deactivate_ibus()
- self.hud.ensure_hidden()
-
- self.assertEqual(self.result, hud_search_string)
+ self.do_hud_test_with_engine()
class IBusTestsHangul(IBusTests):
"""Tests for the Hangul(Korean) input engine."""
+ engine_name = "hangul"
+
scenarios = [
('transmission', {'input': 'xmfostmaltus ', 'result': u'\ud2b8\ub79c\uc2a4\ubbf8\uc158 '}),
('social', {'input': 'httuf ', 'result': u'\uc18c\uc15c '}),
@@ -93,35 +112,17 @@ class IBusTestsHangul(IBusTests):
]
def test_simple_input_dash(self):
- self.activate_input_engine_or_skip("hangul")
- self.dash.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- dash_search_string = self.dash.search_string
- self.deactivate_ibus()
- self.dash.ensure_hidden()
-
- self.assertEqual(self.result, dash_search_string)
+ self.do_dash_test_with_engine()
def test_simple_input_hud(self):
- self.activate_input_engine_or_skip("hangul")
- self.hud.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- hud_search_string = self.hud.search_string
- self.deactivate_ibus()
- self.hud.ensure_hidden()
-
- self.assertEqual(self.result, hud_search_string)
+ self.do_hud_test_with_engine()
class IBusTestsAnthy(IBusTests):
"""Tests for the Anthy(Japanese) input engine."""
+ engine_name = "anthy"
+
scenarios = multiply_scenarios(
[
('system', {'input': 'shisutemu ', 'result': u'\u30b7\u30b9\u30c6\u30e0'}),
@@ -135,99 +136,68 @@ class IBusTestsAnthy(IBusTests):
)
def test_simple_input_dash(self):
- self.activate_input_engine_or_skip("anthy")
- self.dash.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- self.keyboard.press_and_release(self.commit_key)
- dash_search_string = self.dash.search_string
- self.deactivate_ibus()
- self.dash.ensure_hidden()
-
- self.assertEqual(self.result, dash_search_string)
+ self.do_dash_test_with_engine()
def test_simple_input_hud(self):
- self.activate_input_engine_or_skip("anthy")
- self.hud.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
- self.keyboard.type(self.input)
- self.keyboard.press_and_release(self.commit_key)
- hud_search_string = self.hud.search_string
- self.deactivate_ibus()
- self.hud.ensure_hidden()
-
- self.assertEqual(self.result, hud_search_string)
+ self.do_hud_test_with_engine()
class IBusTestsPinyinIgnore(IBusTests):
"""Tests for ignoring key events while the Pinyin input engine is active."""
+ engine_name = "pinyin"
+
def test_ignore_key_events_on_dash(self):
- self.activate_input_engine_or_skip("pinyin")
self.dash.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
+ self.addCleanup(self.dash.ensure_hidden)
+ self.activate_ibus(self.dash.searchbar)
self.keyboard.type("cipan")
self.keyboard.press_and_release("Tab")
self.keyboard.type(" ")
- dash_search_string = self.dash.get_searchbar().search_string
- self.deactivate_ibus()
- self.dash.ensure_hidden()
-
- self.assertNotEqual(" ", dash_search_string)
+ self.deactivate_ibus(self.dash.searchbar)
+ self.assertThat(self.dash.search_string, Eventually(NotEquals(" ")))
def test_ignore_key_events_on_hud(self):
- self.activate_input_engine_or_skip("pinyin")
self.hud.ensure_visible()
- sleep(0.5)
+ self.addCleanup(self.hud.ensure_hidden)
+
self.keyboard.type("a")
- self.activate_ibus()
- sleep(0.5)
+ self.activate_ibus(self.hud.searchbar)
self.keyboard.type("riqi")
old_selected = self.hud.selected_button
self.keyboard.press_and_release("Down")
new_selected = self.hud.selected_button
- self.deactivate_ibus()
- self.hud.ensure_hidden()
-
+ self.deactivate_ibus(self.hud.searchbar)
+
self.assertEqual(old_selected, new_selected)
class IBusTestsAnthyIgnore(IBusTests):
"""Tests for ignoring key events while the Anthy input engine is active."""
+ engine_name = "anthy"
+
def test_ignore_key_events_on_dash(self):
- self.activate_input_engine_or_skip("anthy")
self.dash.ensure_visible()
- sleep(0.5)
- self.activate_ibus()
- sleep(0.5)
+ self.addCleanup(self.dash.ensure_hidden)
+ self.activate_ibus(self.dash.searchbar)
self.keyboard.type("shisutemu ")
self.keyboard.press_and_release("Tab")
self.keyboard.press_and_release("Ctrl+j")
- dash_search_string = self.dash.get_searchbar().search_string
- self.deactivate_ibus()
- self.dash.ensure_hidden()
+ self.deactivate_ibus(self.dash.searchbar)
+ dash_search_string = self.dash.search_string
self.assertNotEqual("", dash_search_string)
def test_ignore_key_events_on_hud(self):
- self.activate_input_engine_or_skip("anthy")
self.hud.ensure_visible()
- sleep(0.5)
+ self.addCleanup(self.hud.ensure_hidden)
self.keyboard.type("a")
- self.activate_ibus()
- sleep(0.5)
+ self.activate_ibus(self.hud.searchbar)
self.keyboard.type("hiduke")
old_selected = self.hud.selected_button
self.keyboard.press_and_release("Down")
new_selected = self.hud.selected_button
- self.deactivate_ibus()
- self.hud.ensure_hidden()
+ self.deactivate_ibus(self.hud.searchbar)
self.assertEqual(old_selected, new_selected)
diff --git a/tests/autopilot/autopilot/tests/test_launcher.py b/tests/autopilot/autopilot/tests/test_launcher.py
index 2d07b4b25..24cd3a2c4 100644
--- a/tests/autopilot/autopilot/tests/test_launcher.py
+++ b/tests/autopilot/autopilot/tests/test_launcher.py
@@ -8,12 +8,16 @@
# by the Free Software Foundation.
import logging
+import os
+from subprocess import call
from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
from time import sleep
-from autopilot.tests import AutopilotTestCase, multiply_scenarios
-from autopilot.emulators.X11 import ScreenGeometry
+from autopilot.emulators.bamf import Bamf
from autopilot.emulators.unity.icons import BFBLauncherIcon
+from autopilot.emulators.X11 import ScreenGeometry
+from autopilot.matchers import Eventually
+from autopilot.tests import AutopilotTestCase, multiply_scenarios
logger = logging.getLogger(__name__)
@@ -33,6 +37,7 @@ def _make_scenarios():
('launcher on all', {'only_primary': False})]
return multiply_scenarios(monitor_scenarios, launcher_mode_scenarios)
+
class LauncherTestCase(AutopilotTestCase):
"""A base class for all launcher tests that uses scenarios to run on
each launcher (for multi-monitor setups).
@@ -62,9 +67,10 @@ class LauncherTestCase(AutopilotTestCase):
"""Get the launcher for the current scenario."""
return self.launcher.get_launcher_for_monitor(self.launcher_monitor)
+
class LauncherSwitcherTests(LauncherTestCase):
""" Tests the functionality of the launcher's switcher capability"""
-
+
def setUp(self):
super(LauncherSwitcherTests, self).setUp()
self.launcher_instance.switcher_start()
@@ -78,10 +84,12 @@ class LauncherSwitcherTests(LauncherTestCase):
def test_launcher_switcher_cancel(self):
"""Test that ending the launcher switcher actually works."""
self.launcher_instance.switcher_cancel()
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
def test_launcher_switcher_cancel_resume_focus(self):
"""Test that ending the launcher switcher resume the focus."""
+ # TODO either remove this test from the class or don't initiate the
+ # switcher in setup.
self.close_all_app("Calculator")
calc = self.start_app("Calculator")
self.assertTrue(calc.is_active)
@@ -96,58 +104,55 @@ class LauncherSwitcherTests(LauncherTestCase):
def test_launcher_switcher_starts_at_index_zero(self):
"""Test that starting the Launcher switcher puts the keyboard focus on item 0."""
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.launcher.key_nav_is_grabbed, Equals(False))
- self.assertThat(self.launcher.key_nav_selection, Equals(0))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(False)))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0)))
def test_launcher_switcher_next(self):
"""Moving to the next launcher item while switcher is activated must work."""
self.launcher_instance.switcher_next()
- sleep(0.5)
- logger.info("After next, keynav selection is %d", self.launcher.key_nav_selection)
# The launcher model has hidden items, so the keynav indexes do not
# increase by 1 each time. This test was failing because the 2nd icon
# had an index of 2, not 1 as expected. The best we can do here is to
# make sure that the index has increased. This opens us to the
# possibility that the launcher really is skipping forward more than one
# icon at a time, but we can't do much about that.
- self.assertThat(self.launcher.key_nav_selection, GreaterThan(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0)))
def test_launcher_switcher_prev(self):
"""Moving to the previous launcher item while switcher is activated must work."""
self.launcher_instance.switcher_prev()
- self.assertThat(self.launcher.key_nav_selection, NotEquals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(NotEquals(0)))
def test_launcher_switcher_down(self):
"""Pressing the down arrow key while switcher is activated must work."""
self.launcher_instance.switcher_down()
- sleep(.25)
# The launcher model has hidden items, so the keynav indexes do not
# increase by 1 each time. This test was failing because the 2nd icon
# had an index of 2, not 1 as expected. The best we can do here is to
# make sure that the index has increased. This opens us to the
# possibility that the launcher really is skipping forward more than one
# icon at a time, but we can't do much about that.
- self.assertThat(self.launcher.key_nav_selection, GreaterThan(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0)))
def test_launcher_switcher_up(self):
"""Pressing the up arrow key while switcher is activated must work."""
self.launcher_instance.switcher_up()
- self.assertThat(self.launcher.key_nav_selection, NotEquals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(NotEquals(0)))
def test_launcher_switcher_next_doesnt_show_shortcuts(self):
"""Moving forward in launcher switcher must not show launcher shortcuts."""
self.launcher_instance.switcher_next()
# sleep so that the shortcut timeout could be triggered
sleep(2)
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(False))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(False)))
def test_launcher_switcher_prev_doesnt_show_shortcuts(self):
"""Moving backward in launcher switcher must not show launcher shortcuts."""
self.launcher_instance.switcher_prev()
# sleep so that the shortcut timeout could be triggered
sleep(2)
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(False))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(False)))
def test_launcher_switcher_cycling_forward(self):
"""Launcher Switcher must loop through icons when cycling forwards"""
@@ -156,29 +161,24 @@ class LauncherSwitcherTests(LauncherTestCase):
logger.info("This launcher has %d icons", num_icons)
for icon in range(1, num_icons):
self.launcher_instance.switcher_next()
- sleep(.25)
# FIXME We can't directly check for selection/icon number equalty
# since the launcher model also contains "hidden" icons that aren't
# shown, so the selection index can increment by more than 1.
- self.assertThat(prev_icon, LessThan(self.launcher.key_nav_selection))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(prev_icon)))
prev_icon = self.launcher.key_nav_selection
- sleep(.5)
self.launcher_instance.switcher_next()
- self.assertThat(self.launcher.key_nav_selection, Equals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0)))
def test_launcher_switcher_cycling_backward(self):
"""Launcher Switcher must loop through icons when cycling backwards"""
self.launcher_instance.switcher_prev()
# FIXME We can't directly check for self.launcher.num_launcher_icons - 1
- self.assertThat(self.launcher.key_nav_selection, GreaterThan(1))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(1)))
def test_launcher_switcher_activate_keep_focus(self):
- """Activating a running launcher icon should focus it"""
+ """Activating a running launcher icon should focus the application."""
calc = self.start_app("Calculator")
- sleep(.5)
-
- self.close_all_app("Mahjongg")
mahjongg = self.start_app("Mahjongg")
self.assertTrue(mahjongg.is_active)
self.assertFalse(calc.is_active)
@@ -210,7 +210,8 @@ class LauncherSwitcherTests(LauncherTestCase):
sleep(.25)
self.keyboard.press_and_release("Escape")
sleep(.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
+
class LauncherShortcutTests(LauncherTestCase):
def setUp(self):
@@ -224,36 +225,30 @@ class LauncherShortcutTests(LauncherTestCase):
def test_launcher_keyboard_reveal_shows_shortcut_hints(self):
"""Launcher icons must show shortcut hints after revealing with keyboard."""
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True)))
def test_launcher_switcher_keeps_shorcuts(self):
"""Initiating launcher switcher after showing shortcuts must not hide shortcuts"""
- self.addCleanup(self.launcher_instance.switcher_cancel)
self.launcher_instance.switcher_start()
- sleep(.5)
+ self.addCleanup(self.launcher_instance.switcher_cancel)
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True)))
def test_launcher_switcher_next_keeps_shortcuts(self):
"""Launcher switcher next action must keep shortcuts after they've been shown."""
- self.addCleanup(self.launcher_instance.switcher_cancel)
self.launcher_instance.switcher_start()
- sleep(.5)
-
+ self.addCleanup(self.launcher_instance.switcher_cancel)
self.launcher_instance.switcher_next()
- sleep(.5)
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True)))
def test_launcher_switcher_prev_keeps_shortcuts(self):
"""Launcher switcher prev action must keep shortcuts after they've been shown."""
- self.addCleanup(self.launcher_instance.switcher_cancel)
self.launcher_instance.switcher_start()
- sleep(.5)
-
+ self.addCleanup(self.launcher_instance.switcher_cancel)
self.launcher_instance.switcher_prev()
- sleep(.5)
- self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True))
+ self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True)))
+
class LauncherKeyNavTests(LauncherTestCase):
"""Test the launcher key navigation"""
@@ -268,99 +263,87 @@ class LauncherKeyNavTests(LauncherTestCase):
def test_launcher_keynav_initiate(self):
"""Tests we can initiate keyboard navigation on the launcher."""
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.launcher.key_nav_is_grabbed, Equals(True))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(True)))
def test_launcher_keynav_cancel(self):
"""Test that we can exit keynav mode."""
self.launcher_instance.key_nav_cancel()
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
- self.assertThat(self.launcher.key_nav_is_grabbed, Equals(False))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
+ self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(False)))
def test_launcher_keynav_cancel_resume_focus(self):
"""Test that ending the launcher keynav resume the focus."""
- self.close_all_app("Calculator")
calc = self.start_app("Calculator")
self.assertTrue(calc.is_active)
self.launcher_instance.key_nav_start()
- sleep(.5)
self.assertFalse(calc.is_active)
self.launcher_instance.key_nav_cancel()
- sleep(.5)
self.assertTrue(calc.is_active)
def test_launcher_keynav_starts_at_index_zero(self):
"""Test keynav mode starts at index 0."""
- self.assertThat(self.launcher.key_nav_selection, Equals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0)))
def test_launcher_keynav_forward(self):
"""Must be able to move forwards while in keynav mode."""
self.launcher_instance.key_nav_next()
- sleep(.5)
# The launcher model has hidden items, so the keynav indexes do not
# increase by 1 each time. This test was failing because the 2nd icon
# had an index of 2, not 1 as expected. The best we can do here is to
# make sure that the index has increased. This opens us to the
# possibility that the launcher really is skipping forward more than one
# icon at a time, but we can't do much about that.
- self.assertThat(self.launcher.key_nav_selection, GreaterThan(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0)))
def test_launcher_keynav_prev_works(self):
"""Must be able to move backwards while in keynav mode."""
self.launcher_instance.key_nav_next()
- sleep(.5)
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0)))
self.launcher_instance.key_nav_prev()
- self.assertThat(self.launcher.key_nav_selection, Equals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0)))
def test_launcher_keynav_cycling_forward(self):
"""Launcher keynav must loop through icons when cycling forwards"""
prev_icon = 0
for icon in range(1, self.launcher.model.num_launcher_icons()):
self.launcher_instance.key_nav_next()
- sleep(.25)
# FIXME We can't directly check for selection/icon number equalty
# since the launcher model also contains "hidden" icons that aren't
# shown, so the selection index can increment by more than 1.
- self.assertThat(prev_icon, LessThan(self.launcher.key_nav_selection))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(prev_icon)))
prev_icon = self.launcher.key_nav_selection
- sleep(.5)
self.launcher_instance.key_nav_next()
- self.assertThat(self.launcher.key_nav_selection, Equals(0))
+ self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0)))
def test_launcher_keynav_cycling_backward(self):
"""Launcher keynav must loop through icons when cycling backwards"""
self.launcher_instance.key_nav_prev()
# FIXME We can't directly check for self.launcher.num_launcher_icons - 1
- self.assertThat(self.launcher.key_nav_selection, GreaterThan(1))
-
+ self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(1)))
+
def test_launcher_keynav_can_open_and_close_quicklist(self):
"""Tests that we can open and close a quicklist from keynav mode."""
self.launcher_instance.key_nav_next()
- sleep(.5)
self.launcher_instance.key_nav_enter_quicklist()
- self.assertThat(self.launcher_instance.is_quicklist_open(), Equals(True))
- sleep(.5)
+ self.assertThat(self.launcher_instance.quicklist_open, Eventually(Equals(True)))
self.launcher_instance.key_nav_exit_quicklist()
- self.assertThat(self.launcher_instance.is_quicklist_open(), Equals(False))
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.launcher.key_nav_is_grabbed, Equals(True))
+ self.assertThat(self.launcher_instance.quicklist_open, Eventually(Equals(False)))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(True)))
def test_launcher_keynav_mode_toggles(self):
"""Tests that keynav mode toggles with Alt+F1."""
# was initiated in setup.
- self.launcher_instance.key_nav_start()
- sleep(0.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
+ self.keybinding("launcher/keynav")
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
def test_launcher_keynav_activate_keep_focus(self):
"""Activating a running launcher icon should focus it"""
calc = self.start_app("Calculator")
- sleep(.5)
-
- self.close_all_app("Mahjongg")
mahjongg = self.start_app("Mahjongg")
self.assertTrue(mahjongg.is_active)
self.assertFalse(calc.is_active)
@@ -388,19 +371,15 @@ class LauncherKeyNavTests(LauncherTestCase):
"""Tests that alt+tab exits keynav mode."""
self.switcher.initiate()
- sleep(1)
- self.switcher.stop()
-
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
+ self.addCleanup(self.switcher.terminate)
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
def test_launcher_keynav_alt_grave_quits(self):
"""Tests that alt+` exits keynav mode."""
self.switcher.initiate_detail_mode()
- sleep(1)
- self.switcher.stop()
-
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
+ self.addCleanup(self.switcher.terminate)
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
class LauncherIconsBehaviorTests(LauncherTestCase):
@@ -469,7 +448,7 @@ class LauncherIconsBehaviorTests(LauncherTestCase):
class LauncherRevealTests(LauncherTestCase):
- """Test the launcher reveal bahavior when in autohide mode."""
+ """Test the launcher reveal behavior when in autohide mode."""
def setUp(self):
super(LauncherRevealTests, self).setUp()
@@ -477,26 +456,19 @@ class LauncherRevealTests(LauncherTestCase):
self.set_unity_option('launcher_capture_mouse', True)
self.set_unity_option('launcher_hide_mode', 1)
launcher = self.get_launcher()
- for counter in range(10):
- sleep(1)
- if launcher.hidemode == 1:
- break
- self.assertThat(launcher.hidemode, Equals(1),
- "Launcher did not enter auto-hide mode.")
+ self.assertThat(launcher.hidemode, Eventually(Equals(1)))
def test_launcher_keyboard_reveal_works(self):
"""Revealing launcher with keyboard must work."""
- self.addCleanup(self.launcher_instance.keyboard_unreveal_launcher)
-
self.launcher_instance.keyboard_reveal_launcher()
- sleep(0.5)
- self.assertThat(self.launcher_instance.is_showing(), Equals(True))
+ self.addCleanup(self.launcher_instance.keyboard_unreveal_launcher)
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True)))
def test_reveal_on_mouse_to_edge(self):
"""Tests reveal of launchers by mouse pressure."""
self.launcher_instance.move_mouse_to_right_of_launcher()
self.launcher_instance.mouse_reveal_launcher()
- self.assertThat(self.launcher_instance.is_showing(), Equals(True))
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True)))
def test_reveal_with_mouse_under_launcher(self):
"""Tests that the launcher hides properly if the
@@ -508,8 +480,7 @@ class LauncherRevealTests(LauncherTestCase):
self.keybinding_hold("launcher/reveal")
sleep(1)
self.keybinding_release("launcher/reveal")
- sleep(2)
- self.assertThat(self.launcher_instance.is_showing(), Equals(False))
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(False)))
def test_reveal_does_not_hide_again(self):
"""Tests reveal of launchers by mouse pressure to ensure it doesn't
@@ -517,8 +488,7 @@ class LauncherRevealTests(LauncherTestCase):
"""
self.launcher_instance.move_mouse_to_right_of_launcher()
self.launcher_instance.mouse_reveal_launcher()
- sleep(2)
- self.assertThat(self.launcher_instance.is_showing(), Equals(True))
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True)))
def test_launcher_does_not_reveal_with_mouse_down(self):
"""Launcher must not reveal if have mouse button 1 down."""
@@ -527,7 +497,24 @@ class LauncherRevealTests(LauncherTestCase):
self.addCleanup(self.mouse.release, 1)
#FIXME: This is really bad API. it says reveal but it's expected to fail. bad bad bad!!
self.launcher_instance.mouse_reveal_launcher()
- self.assertThat(self.launcher_instance.is_showing(), Equals(False))
+ # Need a sleep here otherwise this test would pass even if the code failed.
+ # THis test needs to be rewritten...
+ sleep(5)
+ self.assertThat(self.launcher_instance.is_showing, Equals(False))
+
+ def test_new_icon_has_the_shortcut(self):
+ """New icons should have an associated shortcut"""
+ if self.launcher.model.num_bamf_launcher_icons() >= 10:
+ self.skip("There are already more than 9 icons in the launcher")
+
+ desktop_file = self.KNOWN_APPS['Calculator']['desktop-file']
+ if self.launcher.model.get_icon_by_desktop_id(desktop_file) != None:
+ self.skip("Calculator icon is already on the launcher.")
+
+ self.start_app('Calculator')
+ icon = self.launcher.model.get_icon_by_desktop_id(desktop_file)
+ self.assertThat(icon.shortcut, GreaterThan(0))
+
class LauncherVisualTests(LauncherTestCase):
"""Tests for visual aspects of the launcher (icon saturation etc.)."""
@@ -548,7 +535,7 @@ class LauncherVisualTests(LauncherTestCase):
self.keybinding_tap("launcher/switcher/next")
for icon in self.launcher.model.get_launcher_icons():
- self.assertFalse(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
def test_opening_dash_desaturates_icons(self):
"""Opening the dash must desaturate all the launcher icons."""
@@ -557,9 +544,9 @@ class LauncherVisualTests(LauncherTestCase):
for icon in self.launcher.model.get_launcher_icons():
if isinstance(icon, BFBLauncherIcon):
- self.assertFalse(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
else:
- self.assertTrue(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(True)))
def test_opening_dash_with_mouse_over_launcher_keeps_icon_saturation(self):
"""Opening dash with mouse over launcher must not desaturate icons."""
@@ -570,7 +557,7 @@ class LauncherVisualTests(LauncherTestCase):
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
for icon in self.launcher.model.get_launcher_icons():
- self.assertFalse(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
def test_mouse_over_with_dash_open_desaturates_icons(self):
"""Moving mouse over launcher with dash open must saturate icons."""
@@ -582,7 +569,54 @@ class LauncherVisualTests(LauncherTestCase):
self.mouse.move(x + w/2, y + h/2)
sleep(.5)
for icon in self.launcher.model.get_launcher_icons():
- self.assertFalse(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
+
+class BamfDaemonTests(LauncherTestCase):
+ """Test interaction between the launcher and the BAMF Daemon."""
+
+ def start_test_apps(self):
+ """Starts some test applications."""
+ self.start_app("Calculator")
+ self.start_app("System Settings")
+
+ def get_test_apps(self):
+ """Return a tuple of test application instances.
+
+ We don't store these since when we kill the bamf daemon all references
+ to the old apps will die.
+
+ """
+ [calc] = self.get_app_instances("Calculator")
+ [sys_settings] = self.get_app_instances("System Settings")
+ return (calc, sys_settings)
+
+ def assertOnlyOneLauncherIcon(self, **kwargs):
+ """Asserts that there is only one launcher icon with the given filter."""
+ icons = self.launcher.model.get_icons_by_filter(**kwargs)
+ self.assertThat(len(icons), Equals(1))
+
+ def wait_for_bamf_daemon(self):
+ """Wait until the bamf daemon has been started."""
+ for i in range(10):
+ #pgrep returns 0 if it matched something:
+ if call(["pgrep", "bamfdaemon"]) == 0:
+ return
+ sleep(1)
+
+ def test_killing_bamfdaemon_does_not_duplicate_desktop_ids(self):
+ """Killing bamfdaemon should not duplicate any desktop ids in the model."""
+ self.start_test_apps()
+
+ call(["pkill", "bamfdaemon"])
+ sleep(1)
+
+ # trigger the bamfdaemon to be reloaded again, and wait for it to appear:
+ self.bamf = Bamf()
+ self.wait_for_bamf_daemon()
+
+ for test_app in self.get_test_apps():
+ self.assertOnlyOneLauncherIcon(desktop_id=test_app.desktop_file)
+
class LauncherCaptureTests(AutopilotTestCase):
"""Test the launchers ability to capture/not capture the mouse."""
@@ -591,12 +625,7 @@ class LauncherCaptureTests(AutopilotTestCase):
def setHideMode(self, mode):
launcher = self.launcher.get_launcher_for_monitor(0)
- for counter in range(10):
- sleep(1)
- if launcher.hidemode == mode:
- break
- self.assertThat(launcher.hidemode, Equals(mode),
- "Launcher did not enter revealed mode.")
+ self.assertThat(launcher.hidemode, Eventually(Equals(mode)))
def leftMostMonitor(self):
x1, y1, width, height = self.screen_geo.get_monitor_geometry(0)
diff --git a/tests/autopilot/autopilot/tests/test_panel.py b/tests/autopilot/autopilot/tests/test_panel.py
index ebdeab3b8..745ecc803 100644
--- a/tests/autopilot/autopilot/tests/test_panel.py
+++ b/tests/autopilot/autopilot/tests/test_panel.py
@@ -8,7 +8,7 @@
import logging
import os
-from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
+from testtools.matchers import Equals, GreaterThan, NotEquals
from time import sleep
from autopilot.emulators.X11 import ScreenGeometry
@@ -16,8 +16,10 @@ from autopilot.emulators.bamf import BamfWindow
from autopilot.emulators.unity.panel import IndicatorEntry
from autopilot.tests import AutopilotTestCase
+
logger = logging.getLogger(__name__)
+
def _make_monitor_scenarios():
num_monitors = ScreenGeometry().get_num_monitors()
scenarios = []
@@ -42,18 +44,16 @@ class PanelTestsBase(AutopilotTestCase):
self.addCleanup(self.panel.move_mouse_below_the_panel)
def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):
- """Opens a new instance of the requested application, ensuring
- that only one window is opened.
+ """Opens a new instance of the requested application, ensuring that only
+ one window is opened.
Returns the opened BamfWindow
-
+
"""
self.close_all_app(app_name)
app = self.start_app(app_name, locale="C")
- wins = app.get_windows()
- self.assertThat(len(wins), Equals(1))
- app_win = wins[0]
+ [app_win] = app.get_windows()
app_win.set_focus()
self.assertTrue(app.is_active)
@@ -92,7 +92,7 @@ class PanelTestsBase(AutopilotTestCase):
if restore_position:
self.addCleanup(self.screen_geo.drag_window_to_monitor, window, window.monitor)
-
+
self.screen_geo.drag_window_to_monitor(window, self.panel_monitor)
sleep(.25)
self.assertThat(window.monitor, Equals(self.panel_monitor))
@@ -117,7 +117,7 @@ class PanelTitleTests(PanelTestsBase):
scenarios = _make_monitor_scenarios()
def test_panel_title_on_empty_desktop(self):
- """Test that the title is set ot default when there are no windows shown"""
+ """With no windows shown, the panel must display the default title."""
self.keybinding("window/show_desktop")
# We need this sleep to give the time to showdesktop to properly resume
# the initial status without getting a false-negative result
@@ -128,14 +128,14 @@ class PanelTitleTests(PanelTestsBase):
self.assertTrue(self.panel.desktop_is_active)
def test_panel_title_with_restored_application(self):
- """Tests the title shown in the panel with a restored application"""
+ """Panel must display application name for a non-maximised application."""
calc_win = self.open_new_application_window("Calculator")
self.assertFalse(calc_win.is_maximized)
self.assertThat(self.panel.title, Equals(calc_win.application.name))
def test_panel_title_with_maximized_application(self):
- """Tests the title shown in the panel with a maximized application"""
+ """Panel must display application name for a maximised application."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
self.assertTrue(text_win.is_maximized)
@@ -143,7 +143,7 @@ class PanelTitleTests(PanelTestsBase):
def test_panel_title_with_maximized_window_restored_child(self):
"""Tests the title shown in the panel when opening the restored child of
- a maximized application
+ a maximized application.
"""
text_win = self.open_new_application_window("Text Editor", maximized=True)
@@ -156,7 +156,7 @@ class PanelTitleTests(PanelTestsBase):
self.assertThat(self.panel.title, Equals(text_win.application.name))
def test_panel_title_switching_active_window(self):
- """Tests the title shown in the panel with a maximized application"""
+ """Tests the title shown in the panel with a maximized application."""
# Locked Launchers on all monitors
self.set_unity_option('num_launchers', 0)
self.set_unity_option('launcher_hide_mode', 0)
@@ -179,7 +179,8 @@ class PanelTitleTests(PanelTestsBase):
def test_panel_title_updates_on_maximized_window_title_changes(self):
"""Tests that the title of a maximized application updates with
- window title changes"""
+ window title changes.
+ """
text_win = self.open_new_application_window("Text Editor", maximized=True)
self.assertThat(self.panel.title, Equals(text_win.title))
@@ -210,20 +211,20 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.set_unity_option('launcher_hide_mode', 0)
def test_window_buttons_dont_show_on_empty_desktop(self):
- """Tests that the window buttons are not shown on clean desktop"""
- # We need this sleep to give the time to showdesktop to properly resume
- # the initial status without getting a false-negative result
- self.addCleanup(sleep, 2)
- self.addCleanup(self.keybinding, "window/show_desktop")
-
+ """Tests that the window buttons are not shown on clean desktop."""
+ # THis initially used Show Desktop mode, but it's very buggy from within
+ # autopilot. We assume that workspace 2 is empty (which is safe for the
+ # jenkins runs at least.)
+ self.workspace.switch_to(2)
+ sleep(.5)
self.assertFalse(self.panel.window_buttons_shown)
self.panel.move_mouse_over_window_buttons()
sleep(self.panel.menus.fadein_duration / 1000.0)
self.assertFalse(self.panel.window_buttons_shown)
def test_window_buttons_dont_show_for_restored_window(self):
- """Tests that the window buttons are not shown for a restored window"""
- calc_win = self.open_new_application_window("Calculator")
+ """Tests that the window buttons are not shown for a restored window."""
+ self.open_new_application_window("Calculator")
self.assertFalse(self.panel.window_buttons_shown)
@@ -233,9 +234,9 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self):
"""Tests that the windows button arenot shown for a maximized window
- when the mouse is outside the panel
+ when the mouse is outside the panel.
"""
- text_win = self.open_new_application_window("Text Editor", maximized=True)
+ self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.discovery_duration)
sleep(self.panel.menus.discovery_fadein_duration / 1000.0)
@@ -244,9 +245,9 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_window_buttons_show_for_maximized_window_on_mouse_in(self):
"""Tests that the window buttons are shown when a maximized window
- is focused and the mouse is over the menu-view panel areas
+ is focused and the mouse is over the menu-view panel areas.
"""
- text_win = self.open_new_application_window("Text Editor", maximized=True)
+ self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.discovery_duration)
@@ -260,7 +261,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertFalse(button.overlay_mode)
def test_window_buttons_show_with_dash(self):
- """Tests that the window buttons are shown when opening the dash"""
+ """Tests that the window buttons are shown when opening the dash."""
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
sleep(.5)
@@ -272,7 +273,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(button.overlay_mode)
def test_window_buttons_show_with_hud(self):
- """Tests that the window buttons are shown when opening the HUD"""
+ """Tests that the window buttons are shown when opening the HUD."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
sleep(1)
@@ -284,7 +285,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(button.overlay_mode)
def test_window_buttons_update_visual_state(self):
- """Tests that the window button updates its visual state"""
+ """Tests that the window button updates its visual state."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
button = self.panel.window_buttons.close
@@ -304,7 +305,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_window_buttons_cancel(self):
"""Tests how the buttons ignore clicks when the mouse is pressed over
- them and released outside their area
+ them and released outside their area.
"""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
@@ -319,7 +320,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(self.hud.visible)
def test_window_buttons_close_button_works_for_window(self):
- """Tests that the window button 'Close' actually closes a window"""
+ """Tests that the window button 'Close' actually closes a window."""
text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False)
self.move_window_to_panel_monitor(text_win, restore_position=False)
self.keybinding("window/maximize")
@@ -331,14 +332,17 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(text_win.closed)
def test_window_buttons_close_follows_fitts_law(self):
- """Tests that the 'Close' button is conform to Fitts's Law. See bug #839690"""
+ """Tests that the 'Close' button is activated when clicking at 0,0.
+
+ See bug #839690
+ """
text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False)
self.move_window_to_panel_monitor(text_win, restore_position=False)
self.keybinding("window/maximize")
self.panel.move_mouse_over_window_buttons()
- screen = self.screen_geo.get_monitor_geometry(self.panel_monitor)
- self.mouse.move(screen[0], screen[1], rate=20, time_between_events=0.005)
+ screen_x, screen_y, _, _ = self.screen_geo.get_monitor_geometry(self.panel_monitor)
+ self.mouse.move(screen_x, screen_y, rate=20, time_between_events=0.005)
sleep(.5)
self.mouse.click(press_duration=.1)
sleep(1)
@@ -346,7 +350,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(text_win.closed)
def test_window_buttons_minimize_button_works_for_window(self):
- """Tests that the window button 'Minimize' actually minimizes a window"""
+ """Tests that the window button 'Minimize' actually minimizes a window."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
self.panel.window_buttons.minimize.mouse_click()
@@ -359,7 +363,10 @@ class PanelWindowButtonsTests(PanelTestsBase):
launcher.click_launcher_icon(icon)
def test_window_buttons_minimize_follows_fitts_law(self):
- """Tests that the 'Minimize' button is conform to Fitts's Law. See bug #839690"""
+ """Tests that the 'Minimize' button is conform to Fitts's Law.
+
+ See bug #839690
+ """
text_win = self.open_new_application_window("Text Editor", maximized=True)
button = self.panel.window_buttons.minimize
@@ -377,7 +384,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
launcher.click_launcher_icon(icon)
def test_window_buttons_unmaximize_button_works_for_window(self):
- """Tests that the window button 'Unmaximize' actually unmaximizes a window"""
+ """Tests that the window button 'Unmaximize' actually unmaximizes a window."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
self.panel.window_buttons.unmaximize.mouse_click()
@@ -389,7 +396,10 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertFalse(self.panel.window_buttons_shown)
def test_window_buttons_unmaximize_follows_fitts_law(self):
- """Tests that the 'Unmaximize' button is conform to Fitts's Law. See bug #839690"""
+ """Tests that the 'Unmaximize' button is conform to Fitts's Law.
+
+ See bug #839690
+ """
text_win = self.open_new_application_window("Text Editor", maximized=True)
button = self.panel.window_buttons.unmaximize
@@ -404,7 +414,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertFalse(text_win.is_maximized)
def test_window_buttons_close_button_works_for_hud(self):
- """Tests that the window 'Close' actually closes the HUD"""
+ """Tests that the window 'Close' actually closes the HUD."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
sleep(.5)
@@ -415,7 +425,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertFalse(self.hud.visible)
def test_window_buttons_minimize_button_disabled_for_hud(self):
- """Tests that the window 'Minimize' does nothing to the HUD"""
+ """Tests that the window 'Minimize' does nothing to the HUD."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
sleep(.5)
@@ -428,7 +438,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(self.hud.visible)
def test_window_buttons_maximize_button_disabled_for_hud(self):
- """Tests that the window 'Maximize' does nothing to the HUD"""
+ """Tests that the window 'Maximize' does nothing to the HUD."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
sleep(.5)
@@ -441,8 +451,8 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(self.hud.visible)
def test_window_buttons_maximize_in_hud_does_not_change_dash_form_factor(self):
- """Tests that clicking on the disabled 'Maximize' window button of the
- HUD, really does nothing and don't touch the dash form factor.
+ """Clicking on the 'Maximize' button of the HUD must do nothing.
+
See bug #939054
"""
inital_form_factor = self.dash.view.form_factor
@@ -456,7 +466,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertThat(self.dash.view.form_factor, Equals(inital_form_factor))
def test_window_buttons_close_button_works_for_dash(self):
- """Tests that the window 'Close' actually closes the Dash"""
+ """Tests that the window 'Close' actually closes the Dash."""
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
sleep(.5)
@@ -467,7 +477,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertFalse(self.dash.visible)
def test_window_buttons_minimize_button_disabled_for_dash(self):
- """Tests that the 'Minimize' button is disabled for the dash"""
+ """Tests that the 'Minimize' button is disabled for the dash."""
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
sleep(.5)
@@ -480,8 +490,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.assertTrue(self.dash.visible)
def test_window_buttons_maximization_buttons_works_for_dash(self):
- """Tests that the 'Maximize' and 'Unmaximize' buttons (when
- both enabled) work as expected"""
+ """'Maximize' and 'Restore' buttons (when both enabled) must work as expected."""
self.dash.ensure_visible()
self.addCleanup(self.panel.window_buttons.close.mouse_click)
sleep(.5)
@@ -564,7 +573,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_window_buttons_show_when_indicator_active_and_mouse_over_panel(self):
"""Tests that when an indicator is opened, and the mouse goes over the
- panel view, then the window buttons are revealed
+ panel view, then the window buttons are revealed.
"""
self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -601,7 +610,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
class PanelHoveringTests(PanelTestsBase):
- """Tests with the mouse pointer hovering the panel area"""
+ """Tests with the mouse pointer hovering the panel area."""
scenarios = _make_monitor_scenarios()
@@ -665,8 +674,9 @@ class PanelHoveringTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_hovering_indicators_open_menus(self):
- """This test checks that opening an indicator entry, and then
- hovering on all the others, opens them"""
+ """Opening an indicator entry, and then hovering on other entries must
+ open them.
+ """
self.open_new_application_window("Text Editor")
entries = self.panel.get_indicator_entries(include_hidden_menus=True)
@@ -679,12 +689,13 @@ class PanelHoveringTests(PanelTestsBase):
self.assertTrue(entry.active)
self.assertThat(entry.menu_y, NotEquals(0))
+
class PanelMenuTests(PanelTestsBase):
scenarios = _make_monitor_scenarios()
def test_menus_are_added_on_new_application(self):
- """Tests that menus are added when a new application is opened"""
+ """Tests that menus are added when a new application is opened."""
self.open_new_application_window("Calculator")
sleep(.5)
menu_entries = self.panel.menus.get_entries()
@@ -697,8 +708,11 @@ class PanelMenuTests(PanelTestsBase):
def test_menus_are_not_shown_if_the_application_has_no_menus(self):
"""Tests that if an application has no menus, then they are not
- shown or added
+ shown or added.
"""
+ # TODO: This doesn't test what it says on the tin. Setting MENUPROXY to ''
+ # just makes the menu appear inside the app. That's fine, but it's not
+ # what is described in the docstring or test id.
old_env = os.environ["UBUNTU_MENUPROXY"]
os.putenv("UBUNTU_MENUPROXY", "")
self.addCleanup(os.putenv, "UBUNTU_MENUPROXY", old_env)
@@ -712,7 +726,7 @@ class PanelMenuTests(PanelTestsBase):
self.assertThat(self.panel.title, Equals(calc_win.application.name))
def test_menus_shows_when_new_application_is_opened(self):
- """This tests the menu discovery feature on new application"""
+ """This tests the menu discovery feature on new application."""
self.open_new_application_window("Calculator")
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -725,7 +739,7 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_dont_show_if_a_new_application_window_is_opened(self):
- """This tests the menu discovery feature on new window for a know application"""
+ """This tests the menu discovery feature on new window for a know application."""
self.open_new_application_window("Calculator")
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -739,8 +753,8 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_dont_show_for_restored_window_on_mouse_out(self):
- """Tests that menus of a restored window are not shown when
- the mouse pointer is outside the panel menu area.
+ """Restored window menus must not show when the mouse is outside the
+ panel menu area.
"""
self.open_new_application_window("Calculator")
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -750,8 +764,8 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_show_for_restored_window_on_mouse_in(self):
- """Tests that menus of a restored window are shown only when
- the mouse pointer is over the panel menu area.
+ """Restored window menus must show only when the mouse is over the panel
+ menu area.
"""
self.open_new_application_window("Calculator")
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -763,8 +777,8 @@ class PanelMenuTests(PanelTestsBase):
self.assertTrue(self.panel.menus_shown)
def test_menus_dont_show_for_maximized_window_on_mouse_out(self):
- """Tests that menus of a maximized window are not shown when
- the mouse pointer is outside the panel menu area.
+ """Maximized window menus must not show when the mouse is outside the
+ panel menu area.
"""
self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -774,8 +788,8 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_show_for_maximized_window_on_mouse_in(self):
- """Tests that menus of a maximized window are shown only when
- the mouse pointer is over the panel menu area.
+ """Maximized window menus must only show when the mouse is over the
+ panel menu area.
"""
self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.fadein_duration / 1000.0)
@@ -787,7 +801,7 @@ class PanelMenuTests(PanelTestsBase):
self.assertTrue(self.panel.menus_shown)
def test_menus_dont_show_with_dash(self):
- """Tests that menus are not showing when opening the dash"""
+ """Tests that menus are not showing when opening the dash."""
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
sleep(1)
@@ -795,7 +809,7 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_dont_show_with_hud(self):
- """Tests that menus are not showing when opening the HUD"""
+ """Tests that menus are not showing when opening the HUD."""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
sleep(1)
@@ -803,9 +817,11 @@ class PanelMenuTests(PanelTestsBase):
self.assertFalse(self.panel.menus_shown)
def test_menus_show_after_closing_an_entry(self):
- """This test checks that opening a menu entry, and then
- hovering on all the others, opens them, plus we check that
- the menus are still drawn when closed"""
+ """Opening a menu entry, and then hovering on other entries must open them.
+
+ We also check that the menus are still drawn when closed.
+ """
+ # TODO - should be split into multiple tests.
self.open_new_application_window("Calculator")
entries = self.panel.menus.get_entries()
@@ -825,8 +841,8 @@ class PanelMenuTests(PanelTestsBase):
self.assertThat(last_entry.menu_y, Equals(0))
def test_menus_show_when_indicator_active_and_mouse_over_panel(self):
- """Tests that when an indicator is opened, and the mouse goes over the
- panel view, then the menus are revealed
+ """When an indicator is opened, and the mouse goes over the panel view,
+ the menus must be revealed.
"""
self.open_new_application_window("Calculator")
indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
@@ -862,12 +878,12 @@ class PanelMenuTests(PanelTestsBase):
class PanelIndicatorEntriesTests(PanelTestsBase):
- """Tests for the indicator entries, including both menu and indicators"""
+ """Tests for the indicator entries, including both menu and indicators."""
scenarios = _make_monitor_scenarios()
def test_menu_opens_on_click(self):
- """Tests that clicking on a menu entry, opens a menu"""
+ """Tests that clicking on a menu entry, opens a menu."""
self.open_new_application_window("Calculator")
sleep(.5)
@@ -879,9 +895,7 @@ class PanelIndicatorEntriesTests(PanelTestsBase):
self.assertThat(menu_entry.menu_y, Equals(self.panel.height))
def test_menu_opens_closes_on_click(self):
- """Tests that clicking on a menu entry, opens a menu, reclicking
- on it closes it
- """
+ """Clicking on an open menu entru must close it again."""
self.open_new_application_window("Calculator")
menu_entry = self.panel.menus.get_entries()[0]
@@ -894,7 +908,7 @@ class PanelIndicatorEntriesTests(PanelTestsBase):
self.assertThat(menu_entry.menu_y, Equals(0))
def test_menu_closes_on_click_outside(self):
- """Tests that clicking outside the menu area, closes a menu"""
+ """Clicking outside an open menu must close it."""
self.open_new_application_window("Calculator")
menu_entry = self.panel.menus.get_entries()[0]
@@ -917,9 +931,7 @@ class PanelKeyNavigationTests(PanelTestsBase):
scenarios = _make_monitor_scenarios()
def test_panel_first_menu_show_works(self):
- """Tests that pressing the open-menus keybinding, the first indicator
- is actually opened
- """
+ """Pressing the open-menus keybinding must open the first indicator."""
self.open_new_application_window("Calculator")
sleep(1)
self.keybinding("panel/open_first_menu")
@@ -1006,7 +1018,7 @@ class PanelKeyNavigationTests(PanelTestsBase):
class PanelGrabAreaTests(PanelTestsBase):
- """Panel grab area tests"""
+ """Panel grab area tests."""
scenarios = _make_monitor_scenarios()
@@ -1016,7 +1028,7 @@ class PanelGrabAreaTests(PanelTestsBase):
sleep(.1)
def test_unmaximize_from_grab_area_works(self):
- """Tests that dragging a window down from the panel, unmaximize it"""
+ """Dragging a window down from the panel must unmaximize it."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
self.move_mouse_over_grab_area()
@@ -1028,7 +1040,7 @@ class PanelGrabAreaTests(PanelTestsBase):
self.assertFalse(text_win.is_maximized)
def test_focus_the_maximized_window_works(self):
- """Tests that clicking on the grab area, put the maximized window to focus"""
+ """Clicking on the grab area must put a maximized window in focus."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
sleep(.5)
self.open_new_application_window("Calculator")
@@ -1041,7 +1053,7 @@ class PanelGrabAreaTests(PanelTestsBase):
self.assertTrue(text_win.is_focused)
def test_lower_the_maximized_window_works(self):
- """Tests that middle-clicking on the panel grab area, lower the maximized window"""
+ """Middle-clicking on the panel grab area must lower a maximized window."""
calc_win = self.open_new_application_window("Calculator")
sleep(.5)
self.open_new_application_window("Text Editor", maximized=True)
@@ -1055,7 +1067,7 @@ class PanelGrabAreaTests(PanelTestsBase):
class PanelCrossMonitorsTests(PanelTestsBase):
- """Multimonitor only tests"""
+ """Multimonitor panel tests."""
def setUp(self):
super(PanelCrossMonitorsTests, self).setUp()
@@ -1063,7 +1075,7 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.skipTest("This test requires a multimonitor setup")
def test_panel_title_updates_moving_window(self):
- """Tests the title shown in the panel, moving a restored window around them"""
+ """Tests the title shown in the panel, moving a restored window around them."""
calc_win = self.open_new_application_window("Calculator")
prev_monitor = -1
@@ -1083,10 +1095,10 @@ class PanelCrossMonitorsTests(PanelTestsBase):
prev_monitor = monitor
def test_window_buttons_dont_show_for_maximized_window_on_mouse_in(self):
- """Test that window buttons are not showing when the mouse is hovering
- the panel in other monitors
+ """Window buttons must not show when the mouse is hovering the panel in
+ other monitors.
"""
- text_win = self.open_new_application_window("Text Editor", maximized=True)
+ self.open_new_application_window("Text Editor", maximized=True)
sleep(self.panel.menus.discovery_duration)
@@ -1101,8 +1113,8 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertFalse(panel.window_buttons_shown)
def test_window_buttons_dont_show_in_other_monitors_when_dash_is_open(self):
- """Test that window buttons are not showing in the panels other than
- the one where the dash is opened
+ """Window buttons must not show on the panels other than the one where
+ the dash is opened.
"""
self.dash.ensure_visible()
self.addCleanup(self.dash.ensure_hidden)
@@ -1116,8 +1128,8 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertFalse(panel.window_buttons_shown)
def test_window_buttons_dont_show_in_other_monitors_when_hud_is_open(self):
- """Test that window buttons are not showing in the panels other than
- the one where the dash is opened
+ """Window buttons must not show on the panels other than the one where
+ the hud is opened.
"""
self.hud.ensure_visible()
self.addCleanup(self.hud.ensure_hidden)
@@ -1131,13 +1143,13 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertFalse(panel.window_buttons_shown)
def test_window_buttons_close_inactive_when_clicked_in_another_monitor(self):
- """Tests that clicking on the panel area where the window buttons
- are does not affect the active maximized window in another monitor.
+ """Clicking the close button must not affect the active maximized window on another monitor.
+
See bug #865701
"""
text_win = self.open_new_application_window("Text Editor", maximized=True)
- for monitor in range(0, self.screen_geo.get_num_monitors()):
+ for monitor in range(self.screen_geo.get_num_monitors()):
panel = self.panels.get_panel_for_monitor(monitor)
if monitor != text_win.monitor:
@@ -1146,13 +1158,13 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertFalse(text_win.closed)
def test_window_buttons_minimize_inactive_when_clicked_in_another_monitor(self):
- """Tests that clicking on the panel area where the window buttons
- are does not affect the active maximized window in another monitor.
+ """Clicking the minimise button must not affect the active maximized window on another monitor.
+
See bug #865701
"""
text_win = self.open_new_application_window("Text Editor", maximized=True)
- for monitor in range(0, self.screen_geo.get_num_monitors()):
+ for monitor in range(self.screen_geo.get_num_monitors()):
panel = self.panels.get_panel_for_monitor(monitor)
if monitor != text_win.monitor:
@@ -1161,8 +1173,8 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertFalse(text_win.is_hidden)
def test_window_buttons_unmaximize_inactive_when_clicked_in_another_monitor(self):
- """Tests that clicking on the panel area where the window buttons
- are does not affect the active maximized window in another monitor.
+ """Clicking the restore button must not affect the active maximized window on another monitor.
+
See bug #865701
"""
text_win = self.open_new_application_window("Text Editor", maximized=True)
@@ -1176,8 +1188,7 @@ class PanelCrossMonitorsTests(PanelTestsBase):
self.assertTrue(text_win.is_maximized)
def test_hovering_indicators_on_multiple_monitors(self):
- """This test checks that opening an indicator entry, and then
- hovering on all the others, opens them"""
+ """Opening an indicator entry and then hovering others entries must open them."""
text_win = self.open_new_application_window("Text Editor")
panel = self.panels.get_panel_for_monitor(text_win.monitor)
indicator = panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
diff --git a/tests/autopilot/autopilot/tests/test_quicklist.py b/tests/autopilot/autopilot/tests/test_quicklist.py
index cb4736879..c4349f24a 100644
--- a/tests/autopilot/autopilot/tests/test_quicklist.py
+++ b/tests/autopilot/autopilot/tests/test_quicklist.py
@@ -1,16 +1,19 @@
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
# Copyright 2012 Canonical
-# Author: Thomi Richards
+# Author: Thomi Richards,
+# Marco Trevisan (Treviño)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
import os.path
-from testtools.matchers import Not, Is, Contains
+from testtools.matchers import Contains, Equals, NotEquals
from xdg.DesktopEntry import DesktopEntry
+from time import sleep
from autopilot.emulators.unity.quicklist import QuicklistMenuItemLabel
+from autopilot.matchers import Eventually
from autopilot.tests import AutopilotTestCase
@@ -21,27 +24,31 @@ class QuicklistActionTests(AutopilotTestCase):
('remmina', {'app_name': 'Remmina'}),
]
+ def open_quicklist_for_icon(self, launcher_icon):
+ launcher = self.launcher.get_launcher_for_monitor(0)
+ launcher.click_launcher_icon(launcher_icon, button=3)
+ self.addCleanup(self.keyboard.press_and_release, "Escape")
+
def test_quicklist_actions(self):
"""Test that all actions present in the destop file are shown in the quicklist."""
self.start_app(self.app_name)
# load the desktop file from disk:
- desktop_file = os.path.join('/usr/share/applications',
- self.KNOWN_APPS[self.app_name]['desktop-file']
- )
+ desktop_id = self.KNOWN_APPS[self.app_name]['desktop-file']
+ desktop_file = os.path.join('/usr/share/applications', desktop_id)
de = DesktopEntry(desktop_file)
# get the launcher icon from the launcher:
- launcher_icon = self.launcher.model.get_icon_by_tooltip_text(de.getName())
- self.assertThat(launcher_icon, Not(Is(None)))
+ launcher_icon = self.launcher.model.get_icon_by_desktop_id(desktop_id)
+ self.assertThat(launcher_icon, NotEquals(None))
# open the icon quicklist, and get all the text labels:
- launcher = self.launcher.get_launcher_for_monitor(0)
- launcher.click_launcher_icon(launcher_icon, button=3)
+ self.open_quicklist_for_icon(launcher_icon)
ql = launcher_icon.get_quicklist()
ql_item_texts = [i.text for i in ql.items if type(i) is QuicklistMenuItemLabel]
# iterate over all the actions from the desktop file, make sure they're
# present in the quicklist texts.
+ # FIXME, this doesn't work using a locale other than English.
actions = de.getActions()
for action in actions:
key = 'Desktop Action ' + action
@@ -49,4 +56,274 @@ class QuicklistActionTests(AutopilotTestCase):
name = de.content[key]['Name']
self.assertThat(ql_item_texts, Contains(name))
+ def test_quicklist_application_item_focus_last_active_window(self):
+ """This tests shows that when you activate a quicklist application item
+ only the last focused instance of that application is rasied.
+
+ This is tested by opening 2 Mahjongg and a Calculator.
+ Then we activate the Calculator quicklist item.
+ Then we actiavte the Mahjongg launcher icon.
+ """
+ mahj = self.start_app("Mahjongg")
+ [mah_win1] = mahj.get_windows()
+ self.assertTrue(mah_win1.is_focused)
+
+ calc = self.start_app("Calculator")
+ [calc_win] = calc.get_windows()
+ self.assertTrue(calc_win.is_focused)
+
+ self.start_app("Mahjongg")
+ # Sleeping due to the start_app only waiting for the bamf model to be
+ # updated with the application. Since the app has already started,
+ # and we are just waiting on a second window, however a defined sleep
+ # here is likely to be problematic.
+ # TODO: fix bamf emulator to enable waiting for new windows.
+ sleep(1)
+ [mah_win2] = [w for w in mahj.get_windows() if w.x_id != mah_win1.x_id]
+ self.assertTrue(mah_win2.is_focused)
+
+ self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+
+ mahj_icon = self.launcher.model.get_icon_by_desktop_id(mahj.desktop_file)
+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
+
+ self.open_quicklist_for_icon(calc_icon)
+ calc_ql = calc_icon.get_quicklist()
+ calc_ql.get_quicklist_application_item(calc.name).mouse_click()
+ sleep(1)
+ self.assertTrue(calc_win.is_focused)
+ self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
+
+ self.open_quicklist_for_icon(mahj_icon)
+ mahj_ql = mahj_icon.get_quicklist()
+ mahj_ql.get_quicklist_application_item(mahj.name).mouse_click()
+ sleep(1)
+ self.assertTrue(mah_win2.is_focused)
+ self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+
+ def test_quicklist_application_item_initiate_spread(self):
+ """This tests shows that when you activate a quicklist application item
+ when an application window is focused, the spread is initiated.
+ """
+ calc = self.start_app("Calculator")
+ [calc_win1] = calc.get_windows()
+ self.assertTrue(calc_win1.is_focused)
+
+ self.start_app("Calculator")
+ # Sleeping due to the start_app only waiting for the bamf model to be
+ # updated with the application. Since the app has already started,
+ # and we are just waiting on a second window, however a defined sleep
+ # here is likely to be problematic.
+ # TODO: fix bamf emulator to enable waiting for new windows.
+ sleep(1)
+ [calc_win2] = [w for w in calc.get_windows() if w.x_id != calc_win1.x_id]
+
+ self.assertVisibleWindowStack([calc_win2, calc_win1])
+ self.assertTrue(calc_win2.is_focused)
+
+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
+
+ self.open_quicklist_for_icon(calc_icon)
+ calc_ql = calc_icon.get_quicklist()
+ app_item = calc_ql.get_quicklist_application_item(calc.name)
+
+ self.addCleanup(self.keybinding, "spread/cancel")
+ app_item.mouse_click()
+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
+ self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True)))
+
+
+class QuicklistKeyNavigationTests(AutopilotTestCase):
+ """Tests for the quicklist key navigation."""
+
+ def setUp(self):
+ super(QuicklistKeyNavigationTests, self).setUp()
+
+ self.ql_app = self.start_app("Text Editor")
+
+ self.ql_launcher_icon = self.launcher.model.get_icon_by_desktop_id(self.ql_app.desktop_file)
+ self.assertThat(self.ql_launcher_icon, NotEquals(None))
+
+ self.ql_launcher = self.launcher.get_launcher_for_monitor(0)
+
+ def open_quicklist_with_mouse(self):
+ """Opens a quicklist with the mouse."""
+ self.ql_launcher.click_launcher_icon(self.ql_launcher_icon, button=3)
+ self.addCleanup(self.keyboard.press_and_release, "Escape")
+ self.quicklist = self.ql_launcher_icon.get_quicklist()
+ self.assertThat(self.quicklist, NotEquals(None))
+ self.quicklist.move_mouse_to_right()
+ self.assertThat(self.quicklist.selected_item, Equals(None))
+
+ def open_quicklist_with_keyboard(self):
+ """Opens a quicklist using the keyboard."""
+ self.screen_geo.move_mouse_to_monitor(0)
+ self.ql_launcher.key_nav_start()
+ self.addCleanup(self.ql_launcher.key_nav_cancel)
+
+ for icon in self.launcher.model.get_launcher_icons():
+ if icon.tooltip_text != self.ql_app.name:
+ self.ql_launcher.key_nav_next()
+ else:
+ self.keybinding("launcher/keynav/open-quicklist")
+ self.addCleanup(self.keybinding, "launcher/keynav/close-quicklist")
+ break
+
+ self.quicklist = self.ql_launcher_icon.get_quicklist()
+ self.assertThat(self.quicklist, NotEquals(None))
+ self.assertThat(self.quicklist.selected_item, NotEquals(None))
+
+ def test_keynav_selects_first_item_when_unselected(self):
+ """Home key MUST select the first selectable item in a quicklist."""
+ self.open_quicklist_with_mouse()
+
+ self.keybinding("quicklist/keynav/first")
+
+ expected_item = self.quicklist.selectable_items[0]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_selects_first_item_when_selected(self):
+ """Home key MUST select the first selectable item in a quicklist when
+ another item is selected.
+ """
+ self.open_quicklist_with_mouse()
+ mouse_item = self.quicklist.selectable_items[-1]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ self.keybinding("quicklist/keynav/first")
+
+ expected_item = self.quicklist.selectable_items[0]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_next_selects_first_item_when_unselected(self):
+ """Down key MUST select the first valid item when nothing is selected."""
+ self.open_quicklist_with_mouse()
+
+ self.keybinding("quicklist/keynav/next")
+
+ expected_item = self.quicklist.selectable_items[0]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_selects_last_item_when_unselected(self):
+ """End key MUST select the last selectable item in a quicklist."""
+ self.open_quicklist_with_mouse()
+
+ self.keybinding("quicklist/keynav/last")
+
+ expected_item = self.quicklist.selectable_items[-1]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_selects_last_item_when_selected(self):
+ """End key MUST select the last selectable item in a quicklist when
+ another item is selected.
+ """
+ self.open_quicklist_with_mouse()
+ mouse_item = self.quicklist.selectable_items[0]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ self.keybinding("quicklist/keynav/last")
+
+ expected_item = self.quicklist.selectable_items[-1]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_prev_selects_last_item_when_unselected(self):
+ """Up key MUST select the last valid item when nothing is selected."""
+ self.open_quicklist_with_mouse()
+
+ self.keybinding("quicklist/keynav/prev")
+
+ expected_item = self.quicklist.selectable_items[-1]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_launcher_keynav_selects_first_item(self):
+ """The first selectable item of the quicklist must be selected when
+ opening the quicklist using the launcher key navigation.
+ """
+ self.open_quicklist_with_keyboard()
+
+ expected_item = self.quicklist.selectable_items[0]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_next_selection_works(self):
+ """Down key MUST select the next valid item."""
+ self.open_quicklist_with_mouse()
+
+ for item in self.quicklist.selectable_items:
+ self.keybinding("quicklist/keynav/next")
+ self.assertThat(item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
+
+ def test_keynav_prev_selection_works(self):
+ """Up key MUST select the previous valid item."""
+ self.open_quicklist_with_mouse()
+
+ for item in reversed(self.quicklist.selectable_items):
+ self.keybinding("quicklist/keynav/prev")
+ self.assertThat(item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
+
+ def test_keynav_prev_is_cyclic(self):
+ """Up key MUST select the last item, when the first one is selected."""
+ self.open_quicklist_with_mouse()
+
+ mouse_item = self.quicklist.selectable_items[0]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ self.keybinding("quicklist/keynav/prev")
+ expected_item = self.quicklist.selectable_items[-1]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_next_is_cyclic(self):
+ """Down key MUST select the first item, when the last one is selected."""
+ self.open_quicklist_with_mouse()
+
+ mouse_item = self.quicklist.selectable_items[-1]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ self.keybinding("quicklist/keynav/next")
+ expected_item = self.quicklist.selectable_items[0]
+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
+
+ def test_keynav_mouse_interaction(self):
+ """Tests that the interaction between key-navigation and mouse works as
+ expected. See bug #911561.
+ """
+ self.open_quicklist_with_mouse()
+ mouse_item = self.quicklist.selectable_items[-1]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ self.keybinding("quicklist/keynav/prev")
+ sleep(.1)
+ self.keybinding("quicklist/keynav/prev")
+
+ key_item = self.quicklist.selectable_items[-3]
+ self.assertThat(key_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
+
+ # Moving the mouse horizontally doesn't change the selection
+ self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2)
+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
+
+ # Moving the mouse outside doesn't change the selection
+ self.mouse.move(mouse_item.x + mouse_item.width + 50, mouse_item.y + mouse_item.height / 2)
+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
+ # Moving the mouse to another entry, changes the selection
+ mouse_item = self.quicklist.selectable_items[-2]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+ self.assertThat(self.quicklist.selected_item.id, Equals(mouse_item.id))
diff --git a/tests/autopilot/autopilot/tests/test_shortcut_hint.py b/tests/autopilot/autopilot/tests/test_shortcut_hint.py
index 8f5f4c45e..4715739a4 100644
--- a/tests/autopilot/autopilot/tests/test_shortcut_hint.py
+++ b/tests/autopilot/autopilot/tests/test_shortcut_hint.py
@@ -9,8 +9,10 @@
from testtools.matchers import Equals
from time import sleep
-from autopilot.tests import AutopilotTestCase
from autopilot.emulators.unity.shortcut_hint import ShortcutController
+from autopilot.matchers import Eventually
+from autopilot.tests import AutopilotTestCase
+
class BaseShortcutHintTests(AutopilotTestCase):
@@ -52,233 +54,155 @@ class BaseShortcutHintTests(AutopilotTestCase):
class ShortcutHintTests(BaseShortcutHintTests):
- """Test the shortcuthint."""
+ """Tests for the shortcut hint functionality in isolation."""
def test_shortcut_hint_reveal(self):
"""Test that the shortcut hint is shown."""
- sleep(.5)
self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
- sleep(2)
-
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True)))
def test_shortcut_hint_reveal_timeout(self):
- """Test that the shortcut hint is shown when it should."""
- sleep(.5)
+ """Shortcut hint must be shown after a sufficient timeout."""
timeout = self.shortcut_hint.get_show_timeout()
self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
sleep(timeout/2.0)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
-
- sleep(timeout/2.0)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.assertThat(self.shortcut_hint.visible, Equals(False))
+ # This should happen after 3/4 of 'timeout':
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True)))
def test_shortcut_hint_unreveal(self):
- """Test that the shortcut hint is hidden when it should."""
- sleep(.5)
- self.shortcut_hint.show()
- sleep(self.shortcut_hint.get_show_timeout())
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
- sleep(.25)
-
+ """Shortcut hint must hide when keys are released."""
+ self.shortcut_hint.ensure_visible()
self.shortcut_hint.hide()
- sleep(.25)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False)))
def test_shortcut_hint_cancel(self):
- """Test that the shortcut hint is shown when requested."""
- sleep(.5)
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
- sleep(self.shortcut_hint.get_show_timeout())
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
- sleep(.25)
-
+ """Shortcut hint must hide when cancelled."""
+ self.shortcut_hint.ensure_visible()
self.shortcut_hint.cancel()
- sleep(.25)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
- sleep(self.shortcut_hint.get_show_timeout())
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False)))
class ShortcutHintInteractionsTests(BaseShortcutHintTests):
"""Test the shortcuthint interactions with other Unity parts."""
def test_shortcut_hint_hide_using_unity_shortcuts(self):
- """Test that the shortcut hints is hidden pressing unity shortcuts."""
- sleep(.5)
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
- sleep(self.shortcut_hint.get_show_timeout())
+ """Unity shortcuts (like expo) must hide the shortcut hint."""
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
self.keybinding_tap("expo/start")
self.addCleanup(self.keybinding, "expo/cancel")
- sleep(.25)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
- sleep(.25)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False)))
def test_launcher_switcher_next_doesnt_show_shortcut_hint(self):
- """Moving forward in launcher switcher must not show the shortcut hint."""
- sleep(.5)
+ """Super+Tab switcher cycling forward must not show shortcut hint."""
switcher_timeout = self.shortcut_hint.get_show_timeout()
self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
-
- sleep(switcher_timeout * 0.2)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
self.keybinding("launcher/switcher/next")
- sleep(.25)
-
self.keybinding("launcher/switcher/next")
self.addCleanup(self.keyboard.press_and_release, "Escape")
sleep(switcher_timeout * 2)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.assertThat(self.shortcut_hint.visible, Equals(False))
def test_launcher_switcher_prev_doesnt_show_shortcut_hint(self):
- """Moving backward in launcher switcher must not show the shortcut hint."""
- sleep(.5)
+ """Super+Tab switcher cycling backwards must not show shortcut hint."""
switcher_timeout = self.shortcut_hint.get_show_timeout()
self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
-
- sleep(switcher_timeout * 0.2)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
self.keybinding("launcher/switcher/next")
self.addCleanup(self.keyboard.press_and_release, "Escape")
- sleep(.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
-
self.keybinding("launcher/switcher/next")
- sleep(.25)
-
self.keybinding("launcher/switcher/prev")
- sleep(switcher_timeout)
+ sleep(switcher_timeout * 2)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.assertThat(self.shortcut_hint.visible, Equals(False))
def test_launcher_switcher_next_keeps_shortcut_hint(self):
- """Moving forward in launcher switcher after the shortcut hint has been
- shown must keep the shortcuts there.
+ """Super+Tab switcher cycling forwards must not dispel an already-showing
+ shortcut hint.
"""
- sleep(.5)
show_timeout = self.shortcut_hint.get_show_timeout()
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
- sleep(show_timeout)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.keybinding("launcher/switcher/next")
+ self.addCleanup(self.keyboard.press_and_release, "Escape")
- launcher = self.get_launcher()
- launcher.switcher_start()
- self.addCleanup(launcher.switcher_cancel)
- sleep(.25)
self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- launcher.switcher_next()
- sleep(.25)
- launcher.switcher_next()
- sleep(show_timeout)
-
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.keybinding("launcher/switcher/next")
+ sleep(show_timeout * 2)
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
def test_launcher_switcher_prev_keeps_shortcut_hint(self):
- """Moving backward in launcher switcher after the shortcut hint has been
- shown must keep the shortcuts there.
+ """Super+Tab switcher cycling backwards must not dispel an already-showing
+ shortcut hint.
"""
- sleep(.5)
show_timeout = self.shortcut_hint.get_show_timeout()
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
-
- sleep(show_timeout)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_visible)
- launcher = self.get_launcher()
- launcher.switcher_start()
- self.addCleanup(launcher.switcher_cancel)
- sleep(.25)
+ self.keybinding("launcher/switcher/next")
+ self.addCleanup(self.keyboard.press_and_release, "Escape")
self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- launcher.switcher_prev()
- sleep(.25)
- launcher.switcher_prev()
- sleep(show_timeout)
-
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.keybinding("launcher/switcher/prev")
+ self.keybinding("launcher/switcher/prev")
+ sleep(show_timeout * 2)
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
def test_launcher_switcher_cancel_doesnt_hide_shortcut_hint(self):
- """Cancelling the launcher switcher (by Escape) should not hide the
+ """Cancelling the launcher switcher (by Escape) must not hide the
shortcut hint view.
"""
- sleep(.5)
- show_timeout = self.shortcut_hint.get_show_timeout()
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
- sleep(show_timeout)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.keybinding("launcher/switcher/next")
+ # NOTE: This will generate an extra Escape keypress if the test passes,
+ # but that's better than the alternative...
+ self.addCleanup(self.keybinding, "launcher/switcher/exit")
- launcher = self.get_launcher()
- launcher.switcher_start()
- self.addCleanup(launcher.switcher_cancel)
- sleep(.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
- launcher.switcher_next()
- sleep(.25)
self.keyboard.press_and_release("Escape")
- sleep(.25)
-
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
- sleep(.5)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
def test_launcher_switcher_and_shortcut_hint_escaping(self):
"""Cancelling the launcher switcher (by Escape) should not hide the
shortcut hint view, an extra keypress is needed.
"""
- sleep(.5)
- show_timeout = self.shortcut_hint.get_show_timeout()
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
- sleep(show_timeout)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.keybinding("launcher/switcher/next")
- launcher = self.get_launcher()
- launcher.switcher_start()
- self.addCleanup(launcher.switcher_cancel)
- sleep(.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(True))
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True)))
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
- launcher.switcher_next()
- sleep(.25)
self.keyboard.press_and_release("Escape")
- sleep(.25)
- self.assertThat(self.launcher.key_nav_is_active, Equals(False))
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
- sleep(.25)
+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
- self.shortcut_hint.cancel()
- sleep(.25)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(False))
+ self.keyboard.press_and_release("Escape")
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False)))
def test_launcher_icons_hints_show_with_shortcut_hint(self):
"""When the shortcut hint is shown also the launcer's icons hints should
@@ -286,13 +210,11 @@ class ShortcutHintInteractionsTests(BaseShortcutHintTests):
"""
launcher = self.get_launcher()
- self.shortcut_hint.show()
- self.addCleanup(self.shortcut_hint.hide)
- sleep(self.shortcut_hint.get_show_timeout())
-
+ self.shortcut_hint.ensure_visible()
+ self.addCleanup(self.shortcut_hint.ensure_hidden)
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
- self.assertThat(launcher.are_shortcuts_showing(), Equals(True))
+ self.assertThat(self.shortcut_hint.visible, Equals(True))
+ self.assertThat(launcher.shortcuts_shown, Equals(True))
def test_shortcut_hint_shows_with_launcher_icons_hints(self):
"""When the launcher icons hints are shown also the shortcut hint should
@@ -302,7 +224,6 @@ class ShortcutHintInteractionsTests(BaseShortcutHintTests):
launcher = self.get_launcher()
launcher.keyboard_reveal_launcher()
self.addCleanup(launcher.keyboard_unreveal_launcher)
- sleep(1)
- self.assertThat(launcher.are_shortcuts_showing(), Equals(True))
- self.assertThat(self.shortcut_hint.is_visible(), Equals(True))
+ self.assertThat(launcher.shortcuts_shown, Eventually(Equals(True)))
+ self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True)))
diff --git a/tests/test-gesture-engine/CMakeLists.txt b/tests/test-gesture-engine/CMakeLists.txt
index 3cfdf0a11..4405c9e80 100644
--- a/tests/test-gesture-engine/CMakeLists.txt
+++ b/tests/test-gesture-engine/CMakeLists.txt
@@ -34,7 +34,7 @@ if (GTEST_SRC_DIR)
)
target_link_libraries(test-gesture-engine gtest ${TEST_GESTURE_ENGINE_DEPS_LIBRARIES} -lcompiz_core)
add_test(UnityGTestGestureEngine test-gesture-engine)
- add_dependencies(test-gesture-engine gtest)
+ add_dependencies(test-gesture-engine gtest unity-core-${UNITY_API_VERSION})
add_custom_target (check-gesture-engine COMMAND ./test-gesture-engine DEPENDS test-gesture-engine)
endif (GTEST_SRC_DIR)
diff --git a/tests/test-gesture-engine/compiz_mock/core/screen.h b/tests/test-gesture-engine/compiz_mock/core/screen.h
index 8b786b139..38795db15 100644
--- a/tests/test-gesture-engine/compiz_mock/core/screen.h
+++ b/tests/test-gesture-engine/compiz_mock/core/screen.h
@@ -31,6 +31,8 @@ typedef std::vector<CompWindowMock*> CompWindowMockVector;
class CompScreenMock {
public:
+ CompScreenMock() : _grab_count(0) {}
+
typedef int GrabHandle;
int width() const {return _width;}
@@ -47,8 +49,13 @@ public:
Window root() {return _root;}
- GrabHandle pushGrab(Cursor cursor, const char *name) {return 0;}
- void removeGrab(GrabHandle handle, CompPoint *restorePointer) {}
+ GrabHandle pushGrab(Cursor cursor, const char *name) {
+ _grab_count++;
+ return 0;
+ }
+ void removeGrab(GrabHandle handle, CompPoint *restorePointer) {
+ _grab_count--;
+ }
Cursor invisibleCursor() {return 1;}
@@ -58,6 +65,7 @@ public:
CompWindowMockVector _client_list;
CompWindowMockVector _client_list_stacking;
Window _root;
+ int _grab_count;
};
extern CompScreenMock *screen_mock;
diff --git a/tests/test-gesture-engine/test_gesture_engine.cpp b/tests/test-gesture-engine/test_gesture_engine.cpp
index f2a18d19f..1c009bd55 100644
--- a/tests/test-gesture-engine/test_gesture_engine.cpp
+++ b/tests/test-gesture-engine/test_gesture_engine.cpp
@@ -220,6 +220,27 @@ TEST_F(GestureEngineTest, MinimalThreeFingersPinchDoesNothing)
ASSERT_EQ(0, middle_window->_maximize_count);
}
+/* Regression test for lp:979418, where the grab is not removed if the gesture
+ * id is 0. */
+TEST_F(GestureEngineTest, DragGrabCheck)
+{
+ screen_mock->_grab_count = 0;
+
+ GestureEngine gesture_engine(screen_mock);
+
+ GeisAdapterMock::GeisDragData drag_data;
+ drag_data.id = 0;
+ drag_data.touches = 3;
+ drag_data.window = 123;
+ drag_data.focus_x = 100; /* hits the middle window */
+ drag_data.focus_y = 100;
+ gesture_engine.OnDragStart(&drag_data);
+
+ gesture_engine.OnDragFinish(&drag_data);
+
+ ASSERT_EQ(0, screen_mock->_grab_count);
+}
+
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
diff --git a/tests/test-minimize-window-handler/test-minimize-handler.cpp b/tests/test-minimize-window-handler/test-minimize-handler.cpp
index d45c5012b..e73dbc225 100644
--- a/tests/test-minimize-window-handler/test-minimize-handler.cpp
+++ b/tests/test-minimize-window-handler/test-minimize-handler.cpp
@@ -35,7 +35,8 @@
#include <x11-window-read-transients.h>
class X11WindowFakeMinimizable :
- public X11WindowReadTransients
+ public X11WindowReadTransients,
+ public compiz::WindowInputRemoverLockAcquireInterface
{
public:
@@ -50,9 +51,23 @@ class X11WindowFakeMinimizable :
private:
+ compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
+
+ compiz::WindowInputRemoverLock::Weak input_remover_;
compiz::MinimizedWindowHandler::Ptr mMinimizedHandler;
};
+compiz::WindowInputRemoverLock::Ptr
+X11WindowFakeMinimizable::GetInputRemover ()
+{
+ if (!input_remover_.expired ())
+ return input_remover_.lock ();
+
+ compiz::WindowInputRemoverLock::Ptr ret (new compiz::WindowInputRemoverLock (new compiz::WindowInputRemover (mDpy, mXid)));
+ input_remover_ = ret;
+ return ret;
+}
+
X11WindowFakeMinimizable::X11WindowFakeMinimizable (Display *d, Window id) :
X11WindowReadTransients (d, id)
{
@@ -74,7 +89,7 @@ X11WindowFakeMinimizable::minimize ()
if (!mMinimizedHandler)
{
printf ("Fake minimize window 0x%x\n", (unsigned int) mXid);
- mMinimizedHandler = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (mDpy, mXid));
+ mMinimizedHandler = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (mDpy, mXid, this));
mMinimizedHandler->minimize ();
}
}
diff --git a/tests/test_showdesktop_handler.cpp b/tests/test_showdesktop_handler.cpp
index 42600507e..0936d350a 100644
--- a/tests/test_showdesktop_handler.cpp
+++ b/tests/test_showdesktop_handler.cpp
@@ -39,13 +39,19 @@ public:
ShowdesktopHandler::animating_windows.clear ();
}
- template <class T, class U> static typename T::Ptr makeShared () { return typename T::Ptr (new U); }
+ template <class T, class A1> static typename T::Ptr makeShared1 (A1 *a) { T * t = new T (a); return (typename T::Ptr) (t); }
+ template <class T> static compiz::WindowInputRemoverLock::Ptr getLock ()
+ {
+ T *r = new T ();
+ return makeShared1<compiz::WindowInputRemoverLock, compiz::WindowInputRemoverInterface> (r);
+ }
};
class MockUnityShowdesktopHandlerWindow :
- public ShowdesktopHandlerWindowInterface
+ public ShowdesktopHandlerWindowInterface,
+ public compiz::WindowInputRemoverLockAcquireInterface
{
public:
@@ -63,7 +69,7 @@ class MockUnityShowdesktopHandlerWindow :
ON_CALL (*this, DoHandleAnimations (_)).WillByDefault (Return (ShowdesktopHandlerWindowInterface::PostPaintAction::Damage));
ON_CALL (*this, GetNoCoreInstanceMask ()).WillByDefault (Return (1));
- ON_CALL (*this, GetInputRemover ()).WillByDefault (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemover>));
+ ON_CALL (*this, GetInputRemover ()).WillByDefault (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemover>));
}
MOCK_METHOD0 (DoEnableFocus, void ());
@@ -86,7 +92,7 @@ class MockUnityShowdesktopHandlerWindow :
MOCK_METHOD1 (DoHandleAnimations, ShowdesktopHandlerWindowInterface::PostPaintAction (unsigned int));
MOCK_METHOD0 (DoAddDamage, void ());
MOCK_METHOD0 (GetNoCoreInstanceMask, unsigned int ());
- MOCK_METHOD0 (GetInputRemover, compiz::WindowInputRemoverInterface::Ptr ());
+ MOCK_METHOD0 (GetInputRemover, compiz::WindowInputRemoverLock::Ptr ());
MOCK_METHOD0 (DoDeleteHandler, void ());
};
@@ -94,9 +100,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestNoORWindowsSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ()).WillOnce (Return (true));
EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
@@ -106,9 +110,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestNoUnmanagedWindowsSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ()).WillOnce (Return (false));
@@ -119,9 +121,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestNoGrabbedWindowsSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -133,9 +133,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestNoDesktopOrDockWindowsSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -148,9 +146,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestNoSkipTaskbarOrPagerWindowsSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -164,9 +160,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndShadedWindowsNoSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -183,9 +177,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndShadedWindowsNoSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -197,13 +189,29 @@ TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndShadedWindowsNoSD)
EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
}
-TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD)
+TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndMinimizedWindowsNoSD)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ());
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
+
+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
+ EXPECT_CALL (mMockWindow, IsManaged ());
+ EXPECT_CALL (mMockWindow, IsGrabbed ());
+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
+ EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (false));
+ EXPECT_CALL (mMockWindow, IsMinimized ()).WillOnce (Return (true));
+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
+}
+
+TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD)
+{
+ MockUnityShowdesktopHandlerWindow mMockWindow;
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
EXPECT_CALL (mMockWindow, IsManaged ());
@@ -213,6 +221,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD)
EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (false));
+ EXPECT_CALL (mMockWindow, IsMinimized ()).WillOnce (Return (false));
EXPECT_TRUE (ShowdesktopHandler::ShouldHide (&mMockWindow));
}
@@ -229,6 +238,7 @@ class MockWindowInputRemoverTestFadeOut :
EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
+ EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true));
}
MOCK_METHOD0 (saveInput, bool ());
@@ -240,9 +250,9 @@ TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindow)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOut>));
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -274,9 +284,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestFadeOutOnHiddenDoesntHideWindow)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
@@ -289,9 +297,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestFadeOutAlreadyFadedDoesntHideWindow)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOut>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -307,9 +314,7 @@ TEST_F(UnityShowdesktopHandlerTest, TestFadeInNonFadedDoesntShowWindow)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
mMockHandler.FadeIn ();
@@ -341,9 +346,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindowFadeInShowsWindow)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -363,9 +367,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestAnimationPostPaintActions)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -405,9 +408,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestAnimationOpacity)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -462,9 +464,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestAnimationPaintMasks)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
@@ -518,9 +519,8 @@ TEST_F(UnityShowdesktopHandlerTest, TestShapeEvent)
{
MockUnityShowdesktopHandlerWindow mMockWindow;
- EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent>));
-
- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent>));
+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
EXPECT_CALL (mMockWindow, IsHidden ());
EXPECT_CALL (mMockWindow, DoHide ());
diff --git a/tests/unit/TestQuicklistMenuitems.cpp b/tests/unit/TestQuicklistMenuitems.cpp
index 4f9132df8..1d29f0c08 100644
--- a/tests/unit/TestQuicklistMenuitems.cpp
+++ b/tests/unit/TestQuicklistMenuitems.cpp
@@ -94,6 +94,7 @@ TestMenuItemCheckmark()
g_assert_cmpstr(qlCheckmarkItem->GetLabel(), == , "Unchecked");
g_assert_cmpint(qlCheckmarkItem->GetEnabled(), == , false);
g_assert_cmpint(qlCheckmarkItem->GetActive(), == , false);
+ g_assert_cmpint(qlCheckmarkItem->GetSelectable(), == , false);
g_assert_cmpint(qlCheckmarkItem->IsMarkupEnabled(), == , false);
//qlCheckmarkItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
@@ -129,6 +130,7 @@ TestMenuItemLabel()
g_assert_cmpstr(qlLabelItem->GetLabel(), == , "A Label");
g_assert_cmpint(qlLabelItem->GetEnabled(), == , true);
+ g_assert_cmpint(qlLabelItem->GetSelectable(), == , true);
g_assert_cmpint(qlLabelItem->IsMarkupEnabled(), == , true);
//qlLabelItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
@@ -169,6 +171,7 @@ TestMenuItemRadio()
g_assert_cmpstr(qlRadioItem->GetLabel(), == , "Radio Active");
g_assert_cmpint(qlRadioItem->GetEnabled(), == , true);
g_assert_cmpint(qlRadioItem->GetActive(), == , true);
+ g_assert_cmpint(qlRadioItem->GetSelectable(), == , true);
g_assert_cmpint(qlRadioItem->IsMarkupEnabled(), == , true);
//qlRadioItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
@@ -198,6 +201,7 @@ TestMenuItemSeparator()
qlSeparatorItem = new QuicklistMenuItemSeparator(item, true);
g_assert_cmpint(qlSeparatorItem->GetEnabled(), == , true);
+ g_assert_cmpint(qlSeparatorItem->GetSelectable(), == , false);
qlSeparatorItem->Dispose();
g_object_unref(item);
diff --git a/tools/unity.cmake b/tools/unity.cmake
index 579aee4b9..3b7767d16 100755
--- a/tools/unity.cmake
+++ b/tools/unity.cmake
@@ -122,7 +122,7 @@ def process_and_start_unity (verbose, debug_mode, compiz_args, log_file):
print("ERROR: you don't have gdb in your system. Please install it to run in advanced debug mode.")
sys.exit(1)
elif debug_mode == 1:
- cli.extend(['gdb', '-ex', 'run', '-ex', 'bt', '--batch', '--args'])
+ cli.extend(['gdb', '-ex', 'run', '-ex', '"bt full"', '--batch', '--args'])
elif 'DESKTOP_SESSION' in os.environ:
print("ERROR: it seems you are under a graphical environment. That's incompatible with executing advanced-debug option. You should be in a tty.")
sys.exit(1)