diff -Nru unity-5.6.0/AUTHORS unity-5.8.0/AUTHORS --- unity-5.6.0/AUTHORS 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/AUTHORS 2012-03-23 11:53:16.000000000 +0000 @@ -2,6 +2,7 @@ agateau alanbell@ubuntu.com Alejandro Piñeiro + Alexandros Frantzis Alexandros Frantzis , Marc Ordinas i Llopis , Jay Taoko Alex Launi Alex Launi , Allan LeSage @@ -13,7 +14,9 @@ Bilal Akhtar Brandon Schaefer + Brandon Schaefer Brandon Schaefer + Brandon Schaefer , Thomi Richards Brandon Schaefer Chase Douglas Chris Coulson @@ -24,6 +27,7 @@ David Gomes David Planella Didier Roche + foxoman Gabor Kelemen Gordon Allott Henri De Veene @@ -38,9 +42,11 @@ jassmith@gmail.com Jay Ó Broin Jay Taoko + Jay Taoko , Robert Carr Jeremy Bicha Lars Uebernickel Loïc Molinari + Lorenzo Mattei Luke Yelavich Marco Biscaro Marco Biscaro , Rick Spencer @@ -49,9 +55,12 @@ Marco Trevisan (Treviño) Marco Trevisan (Treviño) , 3v1n0 Marco Trevisan (Treviño) , Andrea Cimitan + Marco Trevisan (Treviño) , Michal Hruby Marco Trevisan (Treviño) , Thomi Richards Marius Gedminas Martin Albisetti + Martin Mrazik + Michael Rawson Michael Terry Michael Terry Michal Hruby @@ -62,12 +71,15 @@ Nico van der Walt Oliver Sauder Omer Akram + Paolo Rotolo Paul Sladen + Paul Sladen , Andrea Cimitan Rafał Cieślak Ricardo Mendoza Robert Carr Robert Carr Rodrigo Moya + Ryan Lortie Sam Spilsbury Sam Spilsbury , Daniel van Vugt Sebastien Bacher @@ -85,6 +97,7 @@ Thomi Richards , Jason Smith Thomi Richards , Ted Gould Thomi Richards , Thomi Richards + Thomi Richards , Tim Penhey Tim Penhey Tim Penhey , Gordon Allott Tim Penhey , Jason Smith diff -Nru unity-5.6.0/ChangeLog unity-5.8.0/ChangeLog --- unity-5.6.0/ChangeLog 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/ChangeLog 2012-03-23 11:53:16.000000000 +0000 @@ -1,3 +1,2960 @@ +2012-03-23 Marco Trevisan (Treviño) + + BamfLauncherIcon: implement WindowsOnViewport to get only windows on visible VP + + This function doesn't take account of the monitors. + Rewritten also BamfLauncherIcon::Windows and ::WindowsForMonitor + to remove code duplication, using the new GetWindows function to perform + filtering via the WindowFilterMask.. Fixes: https://bugs.launchpad.net/bugs/961977. Approved by Thomi Richards, Jason Smith. + +2012-03-23 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-23 Marco Trevisan (Treviño) + + manual-tests, Launcher: improved the launcher multimonitor/workspace tests + +2012-03-22 Marco Trevisan (Treviño) + + manual-tests: added a Launcher manual test to check the "pips" changes + +2012-03-22 Marco Trevisan (Treviño) + + BamfLauncherIcon: implement WindowsOnViewport to get only windows on visible VP + + This function doesn't take account of the monitors. + + Redesigned also BamfLauncherIcon::Windows and ::WindowsForMonitor + to remove code duplication, using the new GetWindows function to perform + filtering via the WindowFilterMask. + +2012-03-22 Tim Penhey + + Make the panel more aware of open overlays, and make sure that all launchers resaturate the icons when overlays (the dash or hud) are closed.. Fixes: https://bugs.launchpad.net/bugs/961844, https://bugs.launchpad.net/bugs/962720. Approved by Thomi Richards. + +2012-03-23 Tim Penhey + + Manual test for the launcher icon saturation. + +2012-03-23 Tim Penhey + + The panel was assuming that you would get a close before an open if switching from the dash to the hud, but they come in the other order. + +2012-03-23 Tim Penhey + + Purely a redraw issue with the resaturation. + +2012-03-22 Brandon Schaefer + + Added extra tests for the ibus Anthy engine: we now test both Ctrl+J and Enter as a commit key.. Fixes: . Approved by Brandon Schaefer. + +2012-03-23 Thomi Richards + + Use multiple_scenarios from testscenarios to generate a dot-product for scenarios that need it. If the version of testscenarios is too old, we provide our own implementation. + +2012-03-22 Brandon Schaefer + + * Added to the ibus_anthy test using Enter to commit preedit + +2012-03-22 Tim Penhey + + Make sure the decay function callback is removed on object destruction.. Fixes: https://bugs.launchpad.net/bugs/962693. Approved by Marco Trevisan (Treviño). + +2012-03-23 Tim Penhey + + Add a destructor to the Decaymulator to remove the on timeout function call. + +2012-03-22 Marco Trevisan (Treviño) + + Open the Menus Indicators on ButtonPress avoiding flickers + + Now the indicator menus shows once Alt+F10 keybinding has been pressed, and is not anymore needed to release the Alt key. + Also, fixed the panel issue reported in bug #948522 that could happen when using menus. To avoid it we use now a timeout to filter the events that we can ignore not to make unity-panel-service crazy.. Fixes: https://bugs.launchpad.net/bugs/943223, https://bugs.launchpad.net/bugs/948522. Approved by Tim Penhey. + +2012-03-22 Marco Trevisan (Treviño) + + PanelIndicators: added Alt+F10 manual test + +2012-03-22 Marco Trevisan (Treviño) + + UnityShell: show First indicator menu on key-down, also remove the flickering issue + +2012-03-22 Thomi Richards + + Removed one manual test that was impossible to run, and another that existed in two separate places. + + UNBLOCK. Fixes: . Approved by Alex Launi. + +2012-03-22 Thomi Richards + + Removed the antialiasing text manual tests, as it's impossible to verify. + +2012-03-22 Thomi Richards + + Removed duplicate manual tests. + +2012-03-22 Thomi Richards + + Fix autopilot tests for launcher keynav mode and super+tab switcher.. Fixes: . Approved by Alex Launi. + +2012-03-22 Thomi Richards + + Fixed launcher keynav tests. + +2012-03-22 Michal Hruby + + Set proper view_type on lenses when they're activated by shortcut. Fixes: https://bugs.launchpad.net/bugs/961338. Approved by Gord Allott, Mikkel Kamstrup Erlandsen. + +2012-03-22 Michal Hruby + + Make the test cleanup itself + +2012-03-22 Michal Hruby + + Add AP test + +2012-03-22 Michal Hruby + + Set proper view_type on lenses when they're activated by shortcut + +2012-03-22 Thomi Richards + + Fixed the shortcut_hint autopilot tests. These were broken after the launcher emulator was changed.. Fixes: . Approved by Tim Penhey. + +2012-03-22 Thomi Richards + + Fixed shortcut hint auitopilot tests. + +2012-03-21 Andrea Cimitan + + Reduces opacity of the blur effect in the dash icons from 50% to 15%, as requested by design. Fixes: . Approved by Andrea Azzarone. + +2012-03-21 Andrea Cimitan + + Less opacity for the blurred effect on icons in the dash + +2012-03-21 Andrea Cimitan + + Trunk uses 100% opacity for search bar border opacity, should be 80%. Fixes: . Approved by Andrea Azzarone. + +2012-03-21 Andrea Cimitan + + Fix regression of search bar border opacity + +2012-03-21 Marco Trevisan (Treviño) + + LauncherController: show a launcher in the primary monitor if set + + This ensures that the launcher is shown only on the primary one, not on the one at the left.. Fixes: https://bugs.launchpad.net/bugs/961281. Approved by Andrea Azzarone. + +2012-03-21 Marco Trevisan (Treviño) + + LauncherController: ensures we have a valid launchers[0] + + It shouldn't ever happen, btw. + +2012-03-21 Marco Trevisan (Treviño) + + LauncherController: ensure that the primary monitor is used when using only one launcher + +2012-03-21 Marco Trevisan (Treviño) + + Launcher manual test: added test to check the launcher monitors. + +2012-03-21 Marco Trevisan (Treviño) + + LauncherController: be aware of the primary monitor. + + Only show the launcher in the primary monitor if set. + +2012-03-21 Andrea Azzarone + + Fixing current dash layout which doesn't match the wanted design. + + Moreover the dash code is full of magic number.. Fixes: . Approved by Andrea Cimitan, Marco Trevisan (Treviño). + +2012-03-21 Andrea Cimitan + + Spacing + +2012-03-21 Andrea Cimitan + + Readd the const& to the variable + +2012-03-21 Andrea Cimitan + + Merge trunk + +2012-03-21 Marco Trevisan (Treviño) + + Re-Remerge trunk + +2012-03-21 Marco Trevisan (Treviño) + + Re-merging with trunk. + +2012-03-21 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-21 Andrea Azzarone + + Update paddin value. + +2012-03-21 Andrea Azzarone + + Fix search bar height in hud. + +2012-03-20 Andrea Azzarone + + Fixes dash layout bugs. Moves padding values in dash::style. + +2012-03-21 Michal Hruby + + Fix incorrect signal connections for handling global search finished. Fixes: . Approved by . + +2012-03-21 Michal Hruby + + Merge trunk + +2012-03-21 Michal Hruby + + Fix incorrect signal connections for handling global search finished + +2012-03-21 Gord Allott + + Hud wasn't sending its monitor with the OVERLAY_HIDDEN message, corrects that, fixes lp:961169. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-21 Gord Allott + + ensured that the hud hide method sends the correct monitor in its ubus signal + +2012-03-21 Didier Roche + + gord has a fix, reverting the revert + +2012-03-21 Didier Roche + + revert lp:~thumper/unity/lock-out-hud. Causing bug #961169 + +2012-03-21 Gord Allott + + Fixes the incorrect item count in See x more results. see lp:934944. Fixes: https://bugs.launchpad.net/bugs/934944. Approved by Mirco Müller. + +2012-03-21 Gord Allott + + remove debug + +2012-03-21 Gord Allott + + fix rare case when there are less items shown than they should + +2012-03-21 Gord Allott + + merged trunk, resolved criss-cross merge + +2012-03-19 Gord Allott + + clarified manual test + +2012-03-06 Gord Allott + + Ensures PlacesGroup corrects the number of visible results depending on the result view it is using + +2012-03-06 Gord Allott + + depend on standalone dash fix branch + +2012-03-21 Gord Allott + + Removes the focus forcing hack in the HUD.. Fixes: . Approved by Gord Allott, Alex Launi, Marco Trevisan (Treviño), Michal Hruby. + +2012-03-21 Gord Allott + + resolved conflict with trunk + +2012-03-07 Gord Allott + + fix conflict with trunk + +2012-02-15 Gord Allott + + remove the bad timeout + +2012-03-21 Daniel van Vugt + + Fix the autoscroll timer waking up 50 times per sec when no scrolling needs to be done (LP: #917210). Fixes: https://bugs.launchpad.net/bugs/917210. Approved by Marco Trevisan (Treviño). + +2012-03-14 Daniel van Vugt + + manual-tests/Wakeups.txt: Add test case for bug LP: #917210 + +2012-03-14 Daniel van Vugt + + Merged latest lp:unity + +2012-01-24 Daniel van Vugt + + Fix the autoscroll timer waking up 50 times per sec when no scrolling needs + to be done (LP: #917210) + + Also removed some unused variables. + +2012-03-21 Marco Trevisan (Treviño) + + unity-panel-service: don't crash if the parsed a11y indicator entry is not valid + + Entries with invalid parent_object have been removed from the indicator + so we shouldn't really care about them.. Fixes: https://bugs.launchpad.net/bugs/937119. Approved by Didier Roche. + +2012-03-21 Marco Trevisan (Treviño) + + Manual Test: Added Panel Service test + +2012-03-20 Marco Trevisan (Treviño) + + PanelindicatorEntryAccessible: don't crash if the parsed entry is not valid + + Entries with invalid parent_object have been removed from the indicator + so we shouldn't really care about them. + +2012-03-21 Daniel van Vugt + + Don't respond to "Confirm" actions in showLauncherKeyTerminate, which come + from pressing Enter during any action (holding Alt). Those calls are spurious + (a long-standing design bug in compiz) and do not come with a valid options[] + vector. So accessing options[] would crash (LP: #960957) + . Fixes: https://bugs.launchpad.net/bugs/960957. Approved by Marco Trevisan (Treviño), Gord Allott. + +2012-03-21 Daniel van Vugt + + Don't respond to "Confirm" actions in showLauncherKeyTerminate, which come + from pressing Enter during any action (holding Alt). Those calls are spurious + (a long-standing design bug in compiz) and do not come with a valid options[] + vector. So accessing options[] would crash (LP: #960957) + +2012-03-21 Tim Penhey + + Adapt the HUD visuals to look nice with a locked out launcher.. Fixes: https://bugs.launchpad.net/bugs/921506. Approved by Gord Allott, Marco Trevisan (Treviño). + +2012-03-21 Tim Penhey + + Add some sleeps to allow unity time to work things out. + +2012-03-21 Tim Penhey + + Update the hud autopilot tests to run with both the launcher hide settings. + +2012-03-21 Tim Penhey + + Make the HUD and BFB launcher icons not switch visibility if the launcher is not locked out. + +2012-03-21 Tim Penhey + + Trim trailing whitespace. + +2012-03-21 Tim Penhey + + Make the launcher realise when the hud is open. + +2012-03-21 Tim Penhey + + Hook up the BFB and HUD launcher icons to the hide_mode changed signal. + +2012-03-21 Tim Penhey + + Fix the enum declarations. + +2012-03-21 Tim Penhey + + Merge trunk. + +2012-03-16 Gord Allott + + added manual test for hud lock out behaviour as there is no AP mechanism for ensuring the launchers locked out state + +2012-03-16 Gord Allott + + fixed wrong highlight + +2012-03-15 Gord Allott + + update hud/launcher visuals for design change + +2012-03-21 Brandon Schaefer + + * Fixes the icon getting frozen and producing a duplicate icon.. Fixes: https://bugs.launchpad.net/bugs/918753. Approved by Tim Penhey. + +2012-03-20 Brandon Schaefer + + * DRY - Dont Repeat Yourself + +2012-03-20 Brandon Schaefer + + * Lose mouse control now + +2012-03-19 Brandon Schaefer + + * Fixes the icon getting frozen and producing a duplicate icon. + +2012-03-20 Andrea Azzarone + + Remove obsolete manual tests.. Fixes: . Approved by Tim Penhey. + +2012-03-20 Andrea Azzarone + + Removes obsolete manual tests. + +2012-03-20 Alexandros Frantzis + + ubus: Ensure the GType system has been initialized before using any GTypes. + + The unity plugin doesn't explicitly call g_type_init(), although it uses a + GObject for UBusServer. This currently works because the ccp plugin, which + gets loaded before the unity plugin, calls g_type_init(), but this is fragile. + If ccp is not used, g_type_init() is not called by the time UBusServer gets + initialized, leading to a crash. This patch ensures that the GType system + has been initialized before using UBusServer (it is safe to call g_type_init() + multiple times).. Fixes: . Approved by Marco Trevisan (Treviño), Jay Taoko. + +2012-03-16 Alexandros Frantzis + + ubus: Ensure the GType system has been initialized before using any GTypes. + + The unity plugin doesn't explicitly call g_type_init(), although it uses a + GObject for UBusServer. This currently works because the ccp plugin, which + gets loaded before the unity plugin, calls g_type_init(), but this is fragile. + If ccp is not used, g_type_init() is not called by the time UBusServer gets + initialized, leading to a crash. This patch ensures that the GType system + has been initialized before using UBusServer (it is safe to call g_type_init() + multiple times). + +2012-03-20 Gord Allott + + Fixes issue with hud not emitting a signal when results change. Fixes: https://bugs.launchpad.net/bugs/956480. Approved by Marco Trevisan (Treviño). + +2012-03-16 Gord Allott + + emit signal (1 line) and tests (about a billion lines) + +2012-03-20 Ryan Lortie + + don't store average-bg-color in GSettings + + This is now exported by libgnome-desktop as an X property on the root window. Interested applications can pick it up from there.. Fixes: https://bugs.launchpad.net/bugs/949277. Approved by Ryan Lortie, Mirco Müller. + +2012-03-09 Ryan Lortie + + don't store average-bg-color in GSettings + + This is now exported by libgnome-desktop as an X property on the root + window. Interested applications can pick it up from there. + +2012-03-20 Alexandros Frantzis + + gles2: Reference compiz's GLFramebufferObject class using a global namespace. + + We need to do this to differentiate from the class of the same name provided + in the Nux namespace.. Fixes: . Approved by Jay Taoko. + +2012-02-23 Alexandros Frantzis + + gles2: Reference compiz's GLFramebufferObject class using a global namespace. + + We need to do this to differentiate from the class of the same name provided + in the Nux namespace. + +2012-03-20 Jay Taoko + + * Fix for bug #956878: + The hud is designed such that the first valid option is always selected. When the activated signal is detected early in hud::View::FindKeyFocusArea, the selected button signal is emitted, and the text entry is still selected as the focus area. Therefore, the hud should not reacted to the search_bar_->activated signal since it alreacdy acted in hud::View::FindKeyFocusArea.. Fixes: . Approved by Gord Allott. + +2012-03-20 Jay Taoko + + * Removed empty lines in manual test file. + +2012-03-20 Jay Taoko + + * Make sure the the Enter key is processesd when it is down. + * Changed temporary file name for test. Added "autopilot_" prefix. + +2012-03-19 Jay Taoko + + * Added test. + +2012-03-19 Jay Taoko + + * Added a manual test. + * Reverted a previous change that breaks the functionality. + +2012-03-19 Jay Taoko + + * Reset the state of activated_signal_sent_, following a test in search_bar_->activated.connect(). This let the SearchBar act on the activated signals again and requires the Enter key to be pressed for activated_signal_sent_ to be set by a button. + +2012-03-16 Jay Taoko + + * Monitor the state of activated_signal_sent_ and use it to decide if the activated signal should be sent. + +2012-03-16 Jay Taoko + + * Fix for bug #956878: + The hud is designed such that if the first valid option is always selected. When the activated signal is detected early in hud::View::FindKeyFocusArea, the selected button is emitted, and the text entry is still selected as the focus area. Therefore, the hud should not reacted to the search_bar_->activated signal since it alreacdy acted in hud::View::FindKeyFocusArea. + +2012-03-20 Marco Trevisan (Treviño) + + Unity panel service: fix a small memory leak, the duplicated keystr should be free'd. Fixes: . Approved by Michal Hruby. + +2012-03-20 Marco Trevisan (Treviño) + + PanelService: fix keystr memory leak + +2012-03-20 Marco Trevisan (Treviño) + + tests: added gtests for the unity::indicator::Indicators class. Fixes: . Approved by Tim Penhey. + +2012-03-20 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/dbus-indicators-proxy + +2012-03-15 Marco Trevisan (Treviño) + + Indicators: emit a null on_entry_activated signal if the entry is not valid. + + This fixes a regression, tests updated. + +2012-03-15 Marco Trevisan (Treviño) + + UnityCore/Indicators: be simpler in GetEntry + +2012-03-15 Marco Trevisan (Treviño) + + test_indicators: Moving SetupTestIndicators to MockIndicators::SetupTestChildren + + Reducing some more code duplication + +2012-03-15 Marco Trevisan (Treviño) + + test_indicators: Splitted IndicatorEntriesEvents into smaller tests. + + Adding SetupTestIndicators to fill the indicators with values. + +2012-03-15 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-15 Marco Trevisan (Treviño) + + tests: added a test suite for the unity::indicator::Indicators class + + This class is an abstract class that redirects the events from the indicators to the + service and back, and was not tested at all. + + Added tests to check that is really doing what it was supposed to do. + +2012-03-15 Marco Trevisan (Treviño) + + DBusIndicators: emit the on_entry_activated signal only if the entry has really been found. + +2012-03-15 Marco Trevisan (Treviño) + + Indicators: don't re-add an indicator if already present. Just return the known one. + +2012-03-20 Marco Trevisan (Treviño) + + DBusIndicators code rewritten to use glib::DBusProxy instead of raw gdbus calls. Fixes: . Approved by Michal Hruby. + +2012-03-20 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/indicators-p (and trunk) + +2012-03-19 Marco Trevisan (Treviño) + + Merging with Michal's branch + + lp:~mhr3/unity/connected-state-without-watch-name + +2012-03-19 Michal Hruby + + Make sure we keep correct connection state + +2012-03-14 Marco Trevisan (Treviño) + + Indicators: move to std::unique_ptr based pimpl + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: Use safer idle and move to glib::Variant in CallData + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: avoid to run the reconnect timeout twice. + +2012-03-14 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/dbus-proxy-name-owner-watch changes + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: sync against DBusProxy changes, add reconnection support here + +2012-03-14 Marco Trevisan (Treviño) + + GLibDBusProxy: fix pimpl, and use "notify::g-name-owner" to check the connection status. + + This avoids that a disconnected signal is emitted when the proxy has not been fully disconnected yet. + + Also, remove the autoconnection support, this can be now done easily by clients. + +2012-03-14 Marco Trevisan (Treviño) + + Reverting changes of the latest two revisions, putting them on a different branch. + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: sync against DBusProxy changes, add reconnection support here + + Plus, when clearing the indicators, we also clear the cached entries locations. + +2012-03-14 Marco Trevisan (Treviño) + + GLibDBusProxy: fix pimpl, and use "notify::g-name-owner" to check the connection status. + + This avoids that a disconnected signal is emitted when the proxy has not been fully disconnected yet. + + Also, remove the autoconnection support, this can be now done easily by clients. + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: cleaning up + +2012-03-14 Marco Trevisan (Treviño) + + DBusIndicators: code rewritten to make it use glib::DBusProxy + + Code cleanup and usage of the utilty gdbus proxy class that allows to improve the code + and reduce the usage of C-code. + Also, improved the pimpl idiom, using the std::unique_ptr and setting everything private + +2012-03-14 Marco Trevisan (Treviño) + + GLibDBusProxy: add support for auto-reconnection + + If enabling the auto_reconnect value, the proxy tries to reconnect to the service when the + connection is lost. + +2012-03-20 Marco Trevisan (Treviño) + + Updated unity-panel-service and libunity-core against the libindicator API changes. Fixes: https://bugs.launchpad.net/bugs/878492, https://bugs.launchpad.net/bugs/926330, https://bugs.launchpad.net/bugs/938890, https://bugs.launchpad.net/bugs/938895. Approved by Thomi Richards, Tim Penhey, Andrea Azzarone, Michal Hruby. + +2012-03-20 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-19 Marco Trevisan (Treviño) + + Oops, resetting back the exec property to autopilot + +2012-03-13 Marco Trevisan (Treviño) + + DBusIndicators: use glib::Object to handle the dbus proxy, so we have ref-counting for free + +2012-03-13 Marco Trevisan (Treviño) + + DBusIndicators: ref/unref proxy when using idle... + +2012-03-13 Marco Trevisan (Treviño) + + PanelService: remove unneeded include + +2012-03-13 Marco Trevisan (Treviño) + + PanelService: make sure we don't try to show an entry that is not shown on the panel using the key navigation. + + Or at least, an entry with not synced geometries. + +2012-03-13 Marco Trevisan (Treviño) + + Indicators: avoid to cast the AppmenuIndicator when not needed. + +2012-03-13 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: c_str() is not needed in GetName + +2012-03-12 Marco Trevisan (Treviño) + + PanelService: close the menu if the related entry has been removed. + +2012-03-12 Marco Trevisan (Treviño) + + PanelIndicatorsView: don't activate invisible views on mouse movement. + +2012-03-10 Marco Trevisan (Treviño) + + PanelService: removed the workaround to look for wrongly-removed entries + +2012-03-10 Marco Trevisan (Treviño) + + AppmenuIndicator: removing the LIM-related code + +2012-03-09 Marco Trevisan (Treviño) + + IndicatorEntry: add also the ShowMenu method with no Xid parameter as fallback + +2012-03-09 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-25 Marco Trevisan (Treviño) + + PanelService: store a keycode instead of a keysym. + +2012-02-25 Marco Trevisan (Treviño) + + Reverting changes wrongly pushed to lp:~3v1n0/unity/lim + + They come from the lim-panel branch... Sorry for that. + +2012-02-25 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: increase the mouse-down timeout to 150ms + +2012-02-25 Marco Trevisan (Treviño) + + PanelView: On opacity toggle redraw the panel on expo changes + + Fixes bug #940683 + +2012-02-25 Marco Trevisan (Treviño) + + PanelService: merging with lp:~3v1n0/lim fixes + +2012-02-25 Marco Trevisan (Treviño) + + PanelService: don't hardcode F10 keybinding to hide the menus, use the gconf key value. + + Also hide them on KeyPress + +2012-02-25 Marco Trevisan (Treviño) + + Panelservice: Fixed coverity warning + +2012-02-24 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: add a workaround to disable the menus only on few cases + + Right now it's better to stop the false-negatives more than the false-positives + +2012-02-24 Marco Trevisan (Treviño) + + PanelView: fix the evil red panel + + It happened with bluish backgrounds... Damned double/float conversion! ;) + +2012-02-24 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/lim + +2012-02-24 Marco Trevisan (Treviño) + + Merging with upstream + +2012-02-24 Marco Trevisan (Treviño) + + PanelService: update the entry_activated callback signature to fix a crash + +2012-02-22 Marco Trevisan (Treviño) + + Merging with trunk. + +2012-02-23 Marco Trevisan (Treviño) + + PanelIndicatorsView: don't activate an unfocused entry on keyboard Alt+F10 + +2012-02-23 Marco Trevisan (Treviño) + + unityshell: Alt+F10 should be triggeted on ButtonPress. + +2012-02-23 Marco Trevisan (Treviño) + + PanelView: always set the monitor. + +2012-02-23 Marco Trevisan (Treviño) + + Merging trunk + +2012-02-23 Marco Trevisan (Treviño) + + PanelView: add monitor getter. + +2012-02-22 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: don't try to draw an invalid flair, and re-draw it + + Flair wasn't drawn anymore... Fixing it, and possible glitches. + +2012-02-22 Marco Trevisan (Treviño) + + PanelMenuView: removing unneeded includes + +2012-02-22 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-22 Marco Trevisan (Treviño) + + PanelView -> PanelIndicatorAppmenu: don't always open menus on keyboard shortcuts + + We need to check that the current appmenu is actually focused. + +2012-02-22 Marco Trevisan (Treviño) + + PanelMenuView: use geometry in DrawText + +2012-02-22 Marco Trevisan (Treviño) + + PanelMenuView: no need to register interest for dash status, let's use the parent + +2012-02-22 Marco Trevisan (Treviño) + + PanelView: some more cleanup + +2012-02-22 Marco Trevisan (Treviño) + + PanelView: move to UBusWrapper + +2012-02-22 Marco Trevisan (Treviño) + + PanelView: no need to resync on remote synced signal, entries will notify the panel + +2012-02-22 Marco Trevisan (Treviño) + + PanelView: cleanup the API + +2012-02-22 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: sync geometries also for unfocused items. + + It could gives wrong results when opening an unfocused menu. + +2012-02-22 Marco Trevisan (Treviño) + + PanelIndicators: don't activate them if unfocused or invisible on mouse-over + +2012-02-22 Marco Trevisan (Treviño) + + WindowButton: no need to add an extra _enabled variable, ViewEnabled can be enough + + We need the nux branch lp:~3v1n0/nux/view-enable-logic-fix to be merged + as well. + +2012-02-22 Marco Trevisan (Treviño) + + WindowButtons: if the managed window is not minimizable, disable the minimize button + +2012-02-22 Marco Trevisan (Treviño) + + WindowManager: add getter to check if a window is minimizable. + +2012-02-22 Marco Trevisan (Treviño) + + PanelMenuView: make the WindowButtons handle their operation, just update their xid + +2012-02-21 Marco Trevisan (Treviño) + + WindowButtons: add one more button for restore state, and swap it with the maximize one + + Also handle internally the maximization / restore of the dash. + +2012-02-21 Marco Trevisan (Treviño) + + WindowButtons: improved a lot the code, using more the WindowButtons container + +2012-02-20 Marco Trevisan (Treviño) + + PanelMenuView: restore a grabbed window, handling it in a position relative to the panel size + + So this is shared between integrated and global modes. + +2012-02-18 Marco Trevisan (Treviño) + + PanelStyle: fallback buttons, make them smaller, except for HighContrast themes + +2012-02-18 Marco Trevisan (Treviño) + + PanelMenuView: update the layout padding on sytle changes, according to buttons size + +2012-02-18 Marco Trevisan (Treviño) + + PanelStyle: fallback-buttons, handle the case of an unfocused close button + +2012-02-18 Marco Trevisan (Treviño) + + Unione con il tronco... [cit. Jason] + +2012-02-18 Marco Trevisan (Treviño) + + Panel*.h classes, move introspection methods in protect field. + +2012-02-18 Marco Trevisan (Treviño) + + PanelMenuView: Make the grabbing of a maximized window from the panel better. + + - The window is be restored as soon as the mouse pointer drags content outside + the panel area. + - Once a window is restored it is not placed outside the desktop area, + unless it fits into it, also it is never below the launcher (when visible). + In the case that the window is bigger than the available space, + the top and left borders should be always visible anyway. + - The just restored window, is grabbed on a point of the top decoration + that is proportional to the x-offset grabbed on the panel, so if you start + dragging at the left of the panel, the window is handled by the top-left + corner, if you start dragging on the right of the panel, the window is + proportionally handled on the right; this applies only with LIM enabled. + When LIMs are disabled, we just prefer the decoration middle point. + + Added also misc improvements to the PanelMenuView code. + +2012-02-18 Marco Trevisan (Treviño) + + WindowManager: add some utility functions to handle window geometries + + GetWindowSavedGeometry: returns the window saved geometry, that it doesn't + consider if the window is maximized or not. + MoveResizeWindow: the name should say what it does ;) + GetWorkAreaGeometry: returns the size of the work-area for the given + window of for the current output (if xid = 0), + It considers the struts geometries. + RestoreAt: restores a window and move it at the given x, y position + keeping the standard geometry. + +2012-02-17 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: use the Cimi's cairo flair instead of the asset + + Thanks + +2012-02-17 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: ignore the grabs if during the timeout we got a small movement + + Adding movement tolerance to the grab, if we have a grab of just few pixels + during the first timeout duration, let's just ignore them. + + As design wanted. + +2012-02-17 Marco Trevisan (Treviño) + + PanelStyle: add myself as author. + +2012-02-17 Marco Trevisan (Treviño) + + PanelStyle: make GetFallbackWindowButton public + + It was GetWindowButtonForTheme before. + +2012-02-17 Marco Trevisan (Treviño) + + PanelStyle: implement unfocused/disabled state on GetWindowButtonForTheme + +2012-02-16 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: fixed compiler warning + +2012-02-16 Marco Trevisan (Treviño) + + Merging with LIM fixes from lp:~3v1n0/unity/lim + +2012-02-16 Marco Trevisan (Treviño) + + services/CMakeLists: fixed typo. + +2012-02-14 Marco Trevisan (Treviño) + + PanelService renamed the *_actually_show_entry* function to something better + +2012-02-13 Marco Trevisan (Treviño) + + PanelService: fixed dbus parameter name + +2012-02-11 Marco Trevisan (Treviño) + + Some code cleanup requested by andyrock + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: avoid to get an invalid maximized window + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: fix the items padding values according to the design specs + + Making the panel pixel-perfect as well! ;) + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: setting the right padding value to 7 pixels + + The value has been computed using design mokups + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: add support for left/right padding protected parameters + +2012-02-13 Marco Trevisan (Treviño) + + unityshell, resources: added the LIM flair assets from design + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: Consider the entry with when drawing the flair + + When an entry is smaller than the opened menu, we have to draw a smaller flair. + + Also using cairo_translate to correctly draw without being dependent on the source geometry. + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: make sure that the window buttons are middle-aligned on the panel. + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: including the has_menu property to the introspect. + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: reduced the spacing to 2px + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: allow to define the spacing per each view. + +2012-02-13 Marco Trevisan (Treviño) + + UnityCore, Variant: added wrappers for long long types as well. + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: remove the right layout padding + + Otherwise there would be a small area at the right of the menus that won't be grabbable. + +2012-02-13 Marco Trevisan (Treviño) + + WindowButtons: don't leak memory when allocating the textures. + + We need to use the ObjectPtr's Adopt facility here. + +2012-02-13 Marco Trevisan (Treviño) + + unityshell: always draw the destkop shadow when integrated menus are enabled. + +2012-02-13 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-13 Marco Trevisan (Treviño) + + PluginAdapter: Consider window in showdesktop mode when checking for visibility or obscured + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: check if the target window has a menu, when setting the window xid. + + If a window has not menus we don't need to draw the indicator entry icon. + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: implement IsLabelSensitive and IsIconSensitive + + The they should be both sensitive unless there's a window that exports the ubuntu menus atoms. + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: add new getters (overridable) to define the label/icon status + + Also, draw an unfocused icon as insensitive + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: added some comments to explain how we manage the events of the integrated menus + +2012-02-13 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: implement the Activate method. + +2012-02-13 Marco Trevisan (Treviño) + + PanelMenuView: use the new PanelTitlebarGrabArea features to handle the panel grabbing / signals + + Maximized windows are now handled using the new code, no more cursor change when not needed! :) + +2012-02-13 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: keep track of the mouse-down button, to check it while dragging. + + Also add restore_request signal on double-click. + +2012-02-13 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: redesigned, to getter grabbed event using a timeout + + If the grab area get a mouse-down event, if we get a mouse-up event before a defined timeout + (set to 120ms now) occurs, then we consider that a click. Otherwise we send the grab_started event + + This allows to improve the way we handle the grab event in the panel, and allow to avoid to + change the mouse cursor if not needed. + +2012-02-11 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: implement the DrawEntryPrelight method to draw the menu flair + + When an appmenu is active, we draw this small shadow, using the design-provided assets. + +2012-02-11 Marco Trevisan (Treviño) + + UnityWindow: don't draw the panel shadow over a window if the integrated menus are enabled. + +2012-02-11 Marco Trevisan (Treviño) + + PanelStyle: Add a integrated_menus property to get the current panel status + +2012-02-11 Marco Trevisan (Treviño) + + Indicators: Updating the geometry before than the active status! + +2012-02-11 Marco Trevisan (Treviño) + + UnityCore, Indicators: set the geometry before than the active status. + +2012-02-11 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/lim changes + +2012-02-11 Marco Trevisan (Treviño) + + UnityCore, IndicatorEntry: add support for entry geometry. + +2012-02-11 Marco Trevisan (Treviño) + + UnityCore: add first basic support to the geometry on EntryActivated + +2012-02-11 Marco Trevisan (Treviño) + + PanelSerivice: Emit EntryActivated signal including the opened menu geometries + +2012-02-11 Marco Trevisan (Treviño) + + Use everywhere on the panel land the panel::Style's panel_height. + +2012-02-11 Marco Trevisan (Treviño) + + Merging with thomi's branch from trunk that adds the panel-height to panel::style + +2012-02-11 Marco Trevisan (Treviño) + + Merging with thomi's cleanup branch from trunk + +2012-02-11 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: as first stage, activate the related window on click. + +2012-02-11 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/lim changes + +2012-02-11 Marco Trevisan (Treviño) + + PanelService: avoid to do unneeded loops when looking for an entry + +2012-02-10 Marco Trevisan (Treviño) + + Panel-Service: added workaround to check if a removed entry is really invalid + + This is needed due to an indicator-appmenu issue, I hope to remove this soon. + +2012-02-09 Marco Trevisan (Treviño) + + PanelService: resetg the static service on finalize. + +2012-02-08 Marco Trevisan (Treviño) + + Panel-service: Merging with changes from lp:~3v1n0/unity/lim-panel + +2012-02-08 Marco Trevisan (Treviño) + + panel-service: fixed a typo + + Eeekk! It caused menus not to swtich on keypress! + +2012-02-08 Marco Trevisan (Treviño) + + panel-service: don't use the "evil hack" to get the entry value... Going back to HashTable + + Using IO could lead to unexpected troubles and is slower, Hashtables + are better :) + +2012-02-11 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: don't activate during expo and scale and cut with fade long entries + + This will apply to both APPMENU entry and other entries, even if with + different values. + +2012-02-11 Marco Trevisan (Treviño) + + PanelMenuView: set the maximum space that the child entries can use + + So applications with a lot of menu entries can be drawn correctly. + +2012-02-11 Marco Trevisan (Treviño) + + PanelIndicatorsView: allow to define the maximum area to be used by entries + +2012-02-11 Marco Trevisan (Treviño) + + PanelMenuView: Add a setter and geter for the integrated mode + + Plus, add right padding to the layout to avoid drawing issues and + cleanup the methods types newlin + +2012-02-11 Marco Trevisan (Treviño) + + PanelMenuView: remove the extra layout, use the parent layout. + + Even if we need to remove it from the main view not to make it draw + using all its space. + Removed the post-layout computation, and added a small pre-layout computation + to adjust the grab area size. + +2012-02-10 Marco Trevisan (Treviño) + + PanelMenuView: avoid to do unnededed computation if the integrated menus are enabled + +2012-02-10 Marco Trevisan (Treviño) + + PanelMenuView: correctly handle unmapped windows, using Bamf + + Compiz doesn't give us the right xid when a window is closed, we need + to use compiz view-closed signal to get the xid, remove it from + our sets and redraw the panel (without this, when closing unfocused + windows, this was never happening). + +2012-02-10 Marco Trevisan (Treviño) + + PanelMenuView: on restored, immediately update _maximized_set + + Otherwise we get the wrong maximized window. + +2012-02-09 Marco Trevisan (Treviño) + + PanelMenuView: fill the decoration set on init, make the window to activate before being retsored + +2012-02-09 Marco Trevisan (Treviño) + + PanelMenuView: Make the menus / label show when they really are needed + + Never showing the menus on dash-open or when expo or scale are active + Plus, improve the code to avoid the title to be redrawn when not needed. + + Also, use BAMF again to get the application name. + +2012-02-08 Marco Trevisan (Treviño) + + PanelMenuView: Use the window title for maximized windows in integrated menus too + + Fallback to application name if it's not available. + +2012-02-08 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: neve draw appmenu entry as prelighted + +2012-02-08 Marco Trevisan (Treviño) + + PanelMenuView: update the integrated menu focused state according to the current status + +2012-02-08 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: add support for focused state. + + The entries marked as unfcoused will use the gtk style contex state + GTK_STATE_FLAG_BACKDROP + +2012-02-08 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: use new PanelStyle features, draw differently APPMENU entries + +2012-02-08 Marco Trevisan (Treviño) + + PanelMenuView: use PanelStyle to get the font settings, fix crash on distroy + + And other various fixes... + +2012-02-08 Marco Trevisan (Treviño) + + PanelStyle: allow to get text for each panel entry type and monitor title changes + + PanelStyle now monitors also gconf changes to the title key and allow + to easily get the theme for each panel entry + +2012-02-07 Marco Trevisan (Treviño) + + PanelMenuView: First working stub of integrated menus + + The logic is all here, we need to improve the design. + However, now when integrated menus are enabled, when adding an entry to + the panel, we just consider it as the integrated-menu and we create a new + PanelIndicatorAppmenuView that will handle that. + The view is also updated everytime the panel title or the active window + changes. + +2012-02-07 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: added indicator-entry subclass to store the Appmenu Entry + + This is a special entry used for locally integrated menu, it has a xid + window associated and a label to make sure we're showing a menu for + that given window. + +2012-02-07 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: Improve the class to make it usable as base for our Appmenu entry + +2012-02-07 Marco Trevisan (Treviño) + + PanelIndicatorsView: add more versatile functions for protected guests + + So it's possible to add an entry by its view, not only by indicator::Entry + +2012-02-07 Marco Trevisan (Treviño) + + Variant: added more int wrappers + +2012-02-07 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: removing the evil define's + +2012-02-07 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/lim updates (and with trunk too) + +2012-02-07 Marco Trevisan (Treviño) + + Panel-service: Fix dispose errors. + +2012-02-07 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-07 Marco Trevisan (Treviño) + + PanelMenuView: added preliminary code for LIM, support for integrated window buttons + + The panel title now reflects the currently maximized window (even if not + shown yet) or the desktop name. + The Window buttons code should be final instead, the buttons now reflects + the status of the most maximized window and are linked to that, so + when pressing them the changes are applied to the maximized window + in top of the stack. Also they are correctly draw as active or inactive. + +2012-02-07 Marco Trevisan (Treviño) + + WindowButtons: addSupport for focused/unfocused buttons. + +2012-02-07 Marco Trevisan (Treviño) + + PanelStyle: fix a typo to get unfocused button texture + +2012-02-07 Marco Trevisan (Treviño) + + PanelStyle: add support for unfocused window buttons style + +2012-02-07 Marco Trevisan (Treviño) + + WindowButtons: use more wrapper classes to be safer and cleaner + +2012-02-07 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-06 Marco Trevisan (Treviño) + + PanelMenuView: fill the maximized set once that the monitor has been set + +2012-02-06 Marco Trevisan (Treviño) + + PanelMenuView: override Add/Remove indicator methods to connect to Appmenu signals + + Used to update the _is_integrated value + +2012-02-06 Marco Trevisan (Treviño) + + PanelIndicatorsView: added IsAppmenu method. + +2012-02-06 Marco Trevisan (Treviño) + + PanelMenuView: added more private or protected members + +2012-02-06 Marco Trevisan (Treviño) + + PanelMenuView: using UBusManager for handling events + +2012-02-06 Marco Trevisan (Treviño) + + PanelStyle: emit the changed singal also when the text dpi changed + + So, when the scaling factor value is changed the panel gets immediately + updated. + +2012-02-06 Marco Trevisan (Treviño) + + PanelMenuView: don't re-draw the panel text if it's not needed + + If the geometry, the text or the style have not changed, there's + no need re-draw the cairo text layout. + +2012-02-06 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: don't listen to font changes + + Also, no need to disconnect to signals connected with sigc::mem_fun + +2012-02-06 Marco Trevisan (Treviño) + + PanelStyle: emit the changed signal also when the font has changed. + +2012-02-05 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: avoid to use unneeded memory to store a TextureLayer + +2012-02-05 Marco Trevisan (Treviño) + + PanelMenuView: don't use a TextureLayer, we can just use a BaseTexture + +2012-02-05 Marco Trevisan (Treviño) + + PanelMenuView: cleanup the DrawText code + +2012-02-05 Marco Trevisan (Treviño) + + Panel-Service: Some indentation fixes. + +2012-02-05 Marco Trevisan (Treviño) + + Panel-Service: If the gometries of the current opened entry have changed, we need to update the menu postion + + This fixes some issues with menu entries that changes the label while the menu is showing. + +2012-02-04 Marco Trevisan (Treviño) + + PanelMenuView: Move GetActiveViewName to std::string + +2012-02-04 Marco Trevisan (Treviño) + + PanelMenuView: first slot of code cleanup... Moving out pointers + +2012-02-04 Marco Trevisan (Treviño) + + PanelStyle: Cleanup the code, and use the new wrappers + +2012-02-04 Marco Trevisan (Treviño) + + No commit message +2012-02-04 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: the indicators aren't blurred anymore when dash is opened :( + + By design... I really loved them! + +2012-02-04 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: merging with some code refactoring I did few weeks ago. + + Coming from the "legendary" lp:~3v1n0/unity/dash-glow branch... + +2012-02-04 Marco Trevisan (Treviño) + + DBusIndicators: Removing debug code + +2012-02-04 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: if an entry is not visible, don't draw it and set it as invisible. + + This fixes bug #926330 + +2012-02-04 Marco Trevisan (Treviño) + + IndicatorEntry: the image_type should be valid as well to make an entry visible + +2012-02-04 Marco Trevisan (Treviño) + + panel-service: check if we know the parent indicator and reduce writes... + +2012-02-04 Marco Trevisan (Treviño) + + IndicatorEntry: remove the UNUSED_ID support, and add the visible property + + The Unused flag is deprecated since last cycle. No need to use it. + We can use the visible flag otherwise, also to notify when an entry is actually shown. + + An entry is visible when has valid label or valid image. + +2012-02-03 Marco Trevisan (Treviño) + + UnityCore, AppmenuIndicator: don't emit a signal on ShowAppmenu if the indicator is not integrated + +2012-02-03 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-03 Marco Trevisan (Treviño) + + PanelService: added a g_warning message if we try to parse an invalid IndicatorEntryObject + +2012-02-01 Marco Trevisan (Treviño) + + tests, IndicatorAppmenu, added one more construction test. + +2012-02-01 Marco Trevisan (Treviño) + + tests, TestAppmenuIndicator: added ShowAppmenu signal test. + +2012-02-01 Marco Trevisan (Treviño) + + tests, IndicatorAppmenu, testing gsettings changes. + +2012-02-01 Marco Trevisan (Treviño) + + tests: add preliminary test for IndicatorAppmenu + +2012-02-01 Marco Trevisan (Treviño) + + tests: Added a test for checking the Indicator class + + Plus, moving indicator-entry tests to xless, they don't need DBus. + +2012-02-01 Marco Trevisan (Treviño) + + UnityCore, Indicator: disconnect from entry signals when they are removed from an indicator. + + Otherwise a removed entry was able to emit a signal through the old indicator. + +2012-01-31 Marco Trevisan (Treviño) + + Merging with trunk fixes + +2012-01-30 Marco Trevisan (Treviño) + + Merging with upstream + +2012-01-28 Marco Trevisan (Treviño) + + AppmenuIndicator: using the changed:: signal + +2012-01-28 Marco Trevisan (Treviño) + + AppmenuIndicator: keys/values names updated to the final ones + +2012-01-28 Marco Trevisan (Treviño) + + DBusIndicators, using unsigned int for button too. + +2012-01-28 Marco Trevisan (Treviño) + + AppmenuIndicator: update to use the real key, not the supposed one. + +2012-01-28 Marco Trevisan (Treviño) + + Indicators: Oops, inverted logic. + +2012-01-25 Marco Trevisan (Treviño) + + AppmenuIndicator: correctly emit the integrated_changed signal + +2012-01-25 Marco Trevisan (Treviño) + + Merging with remote branch + +2012-01-25 Marco Trevisan (Treviño) + + UnityCore: Implement OnShowAppMenu on DBusIndicators + + When the signal is emitted by an AppmenuIndicator, a dbus call is made to ShowAppMenu + +2012-01-25 Marco Trevisan (Treviño) + + UnityCore: Implement OnShowAppMenu on DBusIndicators + + When the signal is emitted by an AppmenuIndicator, a dbus call is made to ShowAppMenu + +2012-01-25 Marco Trevisan (Treviño) + + Indicators: add ShowAppMenu virtual function and call it when AppmenuIndicator is added. + + Only AppmenuIndicator's are connected to that function. + +2012-01-25 Marco Trevisan (Treviño) + + AppmenuIndicator: Update ShowAppmenu to emit a signal when called. + +2012-01-25 Marco Trevisan (Treviño) + + PanelView: use IsAppmenu to check the nature of the indicator. + +2012-01-25 Marco Trevisan (Treviño) + + UnityCore: Added AppmenuIndicator class, subclass of Indicator to keep track of setting changes + + Modified also Indicator, to get the type of the indicator. + +2012-01-25 Marco Trevisan (Treviño) + + PanelView, PanelIndicatorEntry: update against the new Indicator API + +2012-01-25 Marco Trevisan (Treviño) + + DBusIndicators: updated also the on_entry_show_menu signal. + +2012-01-25 Marco Trevisan (Treviño) + + Tests, PanelService: re-enabled the test and fixed the compilation and execution. + +2012-01-25 Marco Trevisan (Treviño) + + tests: Updated IndicatorEntry test against new API + +2012-01-25 Marco Trevisan (Treviño) + + UnityCore: update Entry ShowMenu related methods against the services changes. + +2012-01-25 Marco Trevisan (Treviño) + + PanelService: reordering the ShowEntry parameters + +2012-01-25 Marco Trevisan (Treviño) + + PanelService: using unsigned int for sending the button + +2012-01-25 Marco Trevisan (Treviño) + + panel-service: implemented the method ShowAppMenu + + Plus some code cleanup, factorizing the show-menu function in + panel_service_actually_show_entry + +2012-01-25 Marco Trevisan (Treviño) + + PanelService: don't close the pipe's read fd, or also writing will fail. + +2012-01-25 Marco Trevisan (Treviño) + + PanelService: add xid parameter to ShowEntry + +2012-01-25 Marco Trevisan (Treviño) + + panel-service: make sure we remove invalid entries when syncing the geometry hash. + +2012-01-25 Marco Trevisan (Treviño) + + panel-service: get_indicator_entry_by_id must be static, improving the comments. + +2012-01-25 Marco Trevisan (Treviño) + + panel-service: remove the entry2indicator_hash, moving using the entry parent_object field + + Also improved the get_indicator_entry_by_id function to make it really check if the entry we've found + is really a valid pointer to an IndicatorObjectEntry without crashing. + to do that, we use an hack that uses the low-level write function to read from the pointer to a valid + fds (we use a pipe for convenience). Write will fail if we try to read from an invalid pointer without + crashing, so we can finally be pretty sure if the pointed entry is an IndicatorObjectEntry if it has a + valid parent IndicatorObject + +2012-01-25 Marco Trevisan (Treviño) + + Unity: Depends on newer indicator3-0.4 0.4.90 + +2012-03-20 foxoman + + change Dash Home tooltip to use header capitalization from "Dash home" to "Dash Home" lp:924354. Fixes: https://bugs.launchpad.net/bugs/924354. Approved by Tim Penhey, Thomi Richards. + +2012-02-12 foxoman + + change Dash Home tooltip to use header capitalization from "Dash home" to "Dash Home" + +2012-03-20 Jay Taoko + + Implement new dash blending algorithm on cards with GLSL support.. Fixes: https://bugs.launchpad.net/bugs/865239. Approved by Robert Carr, Tim Penhey, Jay Taoko. + +2012-03-12 Jay Taoko + + * Renamed nux::GraphicsEngine::BlendMode to nux::LayerBlendMode. + +2012-03-09 Jay Taoko + + * Merged with Unity trunk. + +2012-02-25 Robert Carr + + + Update to use new Nux CompositionLayer API + +2012-02-23 Robert Carr + + + Remove questioning comment + +2012-02-23 Robert Carr + + + Fix some logic errors in new blending + +2012-02-23 Robert Carr + + + PanelView.cpp: When we have GLSL use the new blending heuristic + +2012-02-23 Robert Carr + + + OverlayRenderer.cpp: Use the new blending heuristic when we have GLSL + +2012-02-23 Robert Carr + + + Launcher.cpp: Implement the new blending heuristics when we have GLSL + +2012-02-23 Robert Carr + + + Some color tweaks courtesy of Cimi + +2012-02-23 Robert Carr + + + UnityWindowView.cpp: When GLSL is available use overlay blending for colorization + +2012-02-23 Robert Carr + + + BGHash.cpp: Drop the 0.7 multiplier on computed background color + +2012-03-20 Tim Penhey + + Refactor a number of autopilot tests to reduce the likelihood of timing based failures.. Fixes: . Approved by Thomi Richards, Marco Trevisan (Treviño). + +2012-03-20 Tim Penhey + + Use the new tap_duration local + +2012-03-20 Tim Penhey + + Merge trunk + +2012-03-20 Tim Penhey + + Don't debug dash. + +2012-03-20 Tim Penhey + + More whitespace killed. + +2012-03-20 Tim Penhey + + PEP-257 comment tweaks, removing whitespace, and reformatting a test. + +2012-03-20 Tim Penhey + + More dash test tweaks. + +2012-03-20 Tim Penhey + + Clean up the dash tests. + +2012-03-20 Tim Penhey + + Add some logging for the tests to report on failure. + +2012-03-20 Tim Penhey + + Add simple property for the dash search string. + +2012-03-20 Tim Penhey + + Revert the dash reveal timeout. + +2012-03-19 Tim Penhey + + Sometimes incoming results stop the dash from hiding. + +2012-03-19 Tim Penhey + + More timing issues with the dash + +2012-03-19 Tim Penhey + + Fix the hud tests to wait for the hud a little more. + +2012-03-19 Tim Penhey + + Make sure to the best of our ability that the launcher does actually enter autohide mode. + +2012-03-19 Daniel van Vugt + + Use more accurate timing to detect key taps (for Super or Alt).. Fixes: https://bugs.launchpad.net/bugs/953089. Approved by Marco Trevisan (Treviño), Mirco Müller. + +2012-03-17 Daniel van Vugt + + Add test case for the Super tap timing problem (LP: #953089) + +2012-03-16 Daniel van Vugt + + Use more accurate timing to detect key taps (for Super or Alt). The previous + timing methods were failing on slow or busy systems, causing taps to be + misdetected and ignored. Instead use the timestamps that come with each + keypress/release event. (LP: #953089) + +2012-03-19 Tim Penhey + + Fix shutdown crashes and memory leaks. Fixes: . Approved by Sam Spilsbury. + +2012-03-19 Tim Penhey + + Fix the crash around the uninitialised pointer by making them all smartpointers. + +2012-03-19 Tim Penhey + + Make extra textures that were created be destroyed. + +2012-03-19 Tim Penhey + + Stop the panel menu from sinking the grab area causing it not to be deleted. + +2012-03-19 Tim Penhey + + The disabled dash texture wasn't being unrefed if it existed before being overwritten + +2012-03-19 Tim Penhey + + We need to remove the redraw request if there is one in progress, and we must reset the glib logging as we shutdown. + +2012-03-18 Didier Roche + + Add xfixes dependency.. Fixes: . Approved by Tim Penhey. + +2012-03-13 Didier Roche + + Xfixes.h is used by plugins/unityshell/src/PointerBarrier* but wasn't listed in the pc file configuration. It was picked by chance by another dep + +2012-03-18 Thomi Richards + + Remove calls to c_str() where they're not needed.. Fixes: . Approved by Tim Penhey. + +2012-03-16 Thomi Richards + + Removed lots of calls to std::string.c_str() where we didn't need to call it. + +2012-03-18 Tim Penhey + + Make sure the launchers are cleaned up appropriately on shutdown.. Fixes: . Approved by Mirco Müller. + +2012-03-16 Tim Penhey + + Clean up the launchers. + +2012-03-16 Brandon Schaefer + + * Fixes the problem where Alt+F1 wouldn't quit key nav mode. Now it toggles. Fixes: https://bugs.launchpad.net/bugs/885304. Approved by Thomi Richards. + +2012-03-15 Brandon Schaefer + + * new line needed + +2012-03-15 Brandon Schaefer + + * Added test for alt+tab and alt+` + +2012-03-15 Brandon Schaefer + + * Added autopilot test for toggling alt+f1 mode + +2012-03-15 Brandon Schaefer + + * Allows toggling of Alt+F1 mode + * Now Alt + will close the keynav mode + +2012-03-16 Gord Allott + + Fixes the HUD AP keynav tests, tests were expecting 5 items but got 6. Fixes: . Approved by Michal Hruby. + +2012-03-16 Gord Allott + + fixes issue with 6 items being displayed in hud instead of 5, covered by AP test + +2012-03-16 Paul Sladen + + Remove internal UnityWindow shadow and use new 5px nux mask - requires new nux!. Fixes: https://bugs.launchpad.net/bugs/940493. Approved by Jay Taoko. + +2012-03-16 Andrea Cimitan + + Fixes 940493 with new assets and new nux corner mask + +2012-03-01 Paul Sladen + + Switcher/Shortcut outline re-cut from fresh border: with shadow, without background + +2012-02-26 Paul Sladen + + Switcher border: Remove external shadow (may need tweaking/reverting depending on review) + +2012-02-26 Paul Sladen + + Switcher border: Remove internal dots per Cimi + +2012-02-24 Paul Sladen + + No glow: Switcher border: Nuke inner aubergine to avoid double edge + +2012-02-24 Paul Sladen + + No glow: Alt-tab switcher and Switcher border edge (LP: #940493) + +2012-03-16 Sebastien Bacher + + list LensView.cpp to translate. Fixes: . Approved by Tim Penhey. + +2012-03-15 Sebastien Bacher + + list LensView.cpp to translate + +2012-03-15 Alex Launi + + Refactors the launcher emulator to clean up the API. Fixes: . Approved by Thomi Richards. + +2012-03-15 Alex Launi + + Go back to raising a runtime error if trying to use keynav/switcher functions outside of keynav or switcher mode + +2012-03-15 Alex Launi + + Refactor the launcher emulator + + Removes duplicated code, and cleans up some API. + +2012-03-15 Alex Launi + + merge trunk + +2012-03-14 Alex Launi + + add file + +2012-03-15 Mirco Müller + + Fix alignment and padding of scrollbars. Fixes: https://bugs.launchpad.net/bugs/608124. Approved by Andrea Cimitan. + +2012-03-15 Mirco Müller + + fixed bloody anjuta-induced spacing issues + +2012-03-14 Mirco Müller + + Clean up and remove debug-rects + +2012-03-13 Mirco Müller + + Added andyrock's suggestion regarding the Min/Max-size for the VScrollBar to fix the issue with the right scrollbar (when filters are expanded) + +2012-03-13 Mirco Müller + + Fixed horizontal padding between scrollbar of results-view and expanded filters... also made sure the right edge of search-bar right-aligns with this + +2012-03-12 Mirco Müller + + Still hunting for the right spot to tweak the padding for dash-scollbars... added debug-rects again + +2012-03-14 Bilal Akhtar + + This is a one-line change to fix SC launcher integration (bug #761851). + + Since SC Launcher integration phase 1 landed before Unity 5.2.0, this change doesn't need a UIFe. This branch merely fixes the integration. Please ensure it lands before Unity 5.6.0.. Fixes: https://bugs.launchpad.net/bugs/932280. Approved by Alex Launi. + +2012-03-02 Bilal Akhtar + + Merge from trunk + +2012-02-20 Bilal Akhtar + + Fix software center launcher integration. + +2012-03-14 Alex Launi + + Refactors the dash tests to remove duplicated setup/tear down code, and generally helps make the tests more correct.. Fixes: . Approved by Thomi Richards, Alex Launi. + +2012-03-14 Alex Launi + + Change dash emulator view attribute to a property. + + Prevents the dash emulator from throwing an exception during construction + by not actually loading the dash view until requested by a test. By this + point the dash will have been opened, and the views created. + +2012-03-14 Alex Launi + + fix python error in test from refactoring. all dash tests now pass + +2012-03-14 Alex Launi + + Fix '..' typo + +2012-03-14 Alex Launi + + fix conflicts with trunk + +2012-03-12 Alex Launi + + Add AltR key translation + +2012-03-12 Alex Launi + + Add a dash member to AutopilotTestCase + +2012-03-12 Alex Launi + + merge trunk + +2012-03-12 Alex Launi + + Refactor the dash tests + +2012-03-09 Alex Launi + + do some work on fixing up the dash tests + +2012-03-14 Thomi Richards + + Fix AutoPilotTestCase class so launcher tests pass again.. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-15 Thomi Richards + + Fix autopilot test case class, so launcher tests pass again. + +2012-03-14 Andrea Azzarone + + Don't add the hseparator for the final dash category. It's a kind of regression due to the new message displayed when there are no results. + + Test + ==== + Already in trunk.. Fixes: https://bugs.launchpad.net/bugs/955296. Approved by Marco Trevisan (Treviño). + +2012-03-14 Andrea Azzarone + + Fix bug #955296 + +2012-03-14 Andrea Azzarone + + Fix a stupid regression. . Fixes: https://bugs.launchpad.net/bugs/955160. Approved by Mirco Müller. + +2012-03-14 Andrea Azzarone + + Fix stupid regression. + +2012-03-14 Jason Smith + + == The Problem == + Someone (me) made a simple coding error that slipped through review + + == The Solution == + Fix minor coding error (use min instead of max) + + == Testing == + Fixes existing tests that now fail. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-14 Jason Smith + + fix minor snafu with min/max + +2012-03-14 Didier Roche + + remove workaround that is now properly fixed in compiz, as it resulted in bug #953783 + Added a manual test as an autopilot one will require more pocking (firefox API) + + Please poke me before merging it, I need to revert this to the package (it's already + published as a distro-patch). Fixes: . Approved by Daniel van Vugt, Marco Trevisan (Treviño). + +2012-03-14 Didier Roche + + better test case + +2012-03-13 Didier Roche + + remove workaround that is now propery fixed in compiz resulting in bug #953783 + +2012-03-13 Didier Roche + + add a manual test + +2012-03-14 Daniel van Vugt + + Don't absorb Alt+ArrowKey (et al) events if you're not doing anything with + them. Ensures unused events get sent to the active window. (LP: #953783) + . Fixes: https://bugs.launchpad.net/bugs/953783. Approved by Didier Roche. + +2012-03-14 Daniel van Vugt + + Don't absorb Alt+ArrowKey (et al) events if you're not doing anything with + them. Ensures unused events get sent to the active window. (LP: #953783) + +2012-03-14 Thomi Richards + + Update the unity logging tests to use the updated autopilot API.. Fixes: . Approved by Michal Hruby. + +2012-03-14 Thomi Richards + + Fixed new unity logging tests. + +2012-03-14 Thomi Richards + + Autopilot tests can now produce unity logs for a failing autopilot test.. Fixes: . Approved by Jason Smith, Tim Penhey. + +2012-03-14 Thomi Richards + + Trim trailing whitespace. + +2012-03-14 Thomi Richards + + Changed from review. + +2012-03-14 Thomi Richards + + Merged trunk. + +2012-03-14 Thomi Richards + + Merged trunk. + +2012-03-14 Thomi Richards + + Fixed typo. + +2012-03-14 Thomi Richards + + Logging now reset after each test is complete. + +2012-03-14 Thomi Richards + + Launcher tests now make the launcher log debug-level log messages. + +2012-03-14 Thomi Richards + + Renamed StopLoggingToFile -> ResetLogging. Added infrastructure to test case class. + +2012-03-13 Thomi Richards + + Now attaches unity log to tests. + +2012-03-13 Thomi Richards + + Added more tests to ensure the logging framework is running correctly. + +2012-03-13 Thomi Richards + + Merged Tim's branch that contains the log implementation. + +2012-03-13 Tim Penhey + + Implement the logging features. + +2012-03-13 Thomi Richards + + Added the test file. + +2012-03-13 Thomi Richards + + Added a failing test for unity's logging infrastructure. + +2012-03-13 Thomi Richards + + DBus methods in place. + +2012-03-13 Brandon Schaefer + + . Fixes: . Approved by Thomi Richards. + +2012-03-13 Brandon Schaefer + + * Fixed using ensure_dash in ALL test cases, now only in setUp and tearDown + * Fixed self.dash = Dash() being used everytime in setUp. Now in AutopilotTest + +2012-03-13 Brandon Schaefer + + * Test for Multi_Key/Composition characters + +2012-03-13 Marco Trevisan (Treviño) + + Added support for Up/Down arrow keys to change the selected launcher icon when using the Super+Tab + + This fixes the bug #950404 + + On the test sides, I've used autopilot to test this particular fix, also I've made some changes to the launcher emulator, to make it handle in a better way the Launcher key navigation and the Launcher Switcher as two different kinds of key navigation. This should avoid any confusion and cleans the code.. Fixes: https://bugs.launchpad.net/bugs/950404. Approved by Andrea Azzarone, Thomi Richards. + +2012-03-10 Marco Trevisan (Treviño) + + autopilot: added the tests for the Up/Down arrow keys during launcher switcher + + Plus, redesigned the launcher emulator, underlining the differece between the Launcher Switcher + and the Launcher Key navigation. + +2012-03-09 Marco Trevisan (Treviño) + + unityshell: make Launcher switcher to work also with arrow keys + +2012-03-13 Andrea Azzarone + + The problems + ------------- + Bug #927710: No text inside multirange filters + Bug #942508: Dash - Font metrics and colors are wrong + + The fix + ------- + Update the dash fonts. + + Test + ---- + Not applicable. + + http://ubuntuone.com/1a4mdRPJ8tgFrg4bMuNiQE + + I've merged lp:~sladen/unity/unity-drunken-spinner-lp943656.. Fixes: https://bugs.launchpad.net/bugs/927710, https://bugs.launchpad.net/bugs/942508. Approved by John Lea, Andrea Cimitan, Mirco Müller. + +2012-03-13 Andrea Azzarone + + Add SVGs. + +2012-03-13 Andrea Azzarone + + Merge trunk. + +2012-03-06 Andrea Azzarone + + Fix the space between the search entry icon and the text. + +2012-03-06 Andrea Azzarone + + Merge needed branch. + +2012-03-05 Andrea Azzarone + + Move font description in const variables. + +2012-03-01 Andrea Azzarone + + Update the dash font settings. + +2012-03-13 Mirco Müller + + Trying to understand how and where changes to an icons alpha- and saturation-value are taking place is material to get insane. By now I've spent many many many hours trying to get behind what's going on. I can't say I fully grasp + the intricate ways of icons opacity and saturation in class Launcher. + + As far as I can tell, there are four valid "cases" for the launcher icons in terms of alpha and saturation. To make it easier for you to follow, have a look at this table: + + alpha | saturation + ------------------------------------------------------------------- + | dash open | 0.5 | 0.0 | + | dash closed | 1.0 | 1.0 | + | drop-target (dragging & dash open) | 1.0 | 1.0 | + | no drop-target (dragging & dash open) | 0.5 | 0.0 | + ------------------------------------------------------------------- + + So alpha should never be outside [0.5 .. 1.0] and saturation should never be outside [0.0 .. 1.0]. From my investigation it is sufficient to protect only against the lower threshold, where alpha needs to be 0.5 and saturation 0.0 + + without fix: + http://people.canonical.com/~mmueller/863230-issue-1.ogv + + with fix: + http://people.canonical.com/~mmueller/after-fix-863230.ogv + + If anybody ever causes this to regress, I'll ... !. Fixes: https://bugs.launchpad.net/bugs/863230. Approved by Tim Penhey. + +2012-02-29 Mirco Müller + + Added a manual-test for the bug + +2012-02-15 Mirco Müller + + Best attempt yet, trying to fix LP: #863230 + +2012-03-13 Gabor Kelemen + + Added missing files to POTFILES.in. Fixes: https://bugs.launchpad.net/bugs/923762. Approved by Thomi Richards, Michal Hruby. + +2012-03-05 Gabor Kelemen + + Update POTFILES.in/skip. LP: 923762 + +2012-03-13 Alex Launi + + Adds "x" and "y" properties to the quicklists and their menu items, so that autopilto can find and click them in tests.. Fixes: . Approved by Thomi Richards. + +2012-02-23 Alex Launi + + add absolute (screen) x and y coordinated to quicklists + +2012-03-13 Andrea Azzarone + + = The Problem = + + HUD shortcut is not in the overlay. + + = The Fix = + + Add it. + + = Testing = + + None.. Fixes: https://bugs.launchpad.net/bugs/942515. Approved by Marco Trevisan (Treviño). + +2012-03-05 Andrea Azzarone + + Fix. + +2012-02-28 Andrea Azzarone + + Add the HUD shortcut to the overlay. + +2012-03-13 Andrea Azzarone + + = The Problem = + + The shortcut overlay uses hardcoded value for switching ws. + + = The Fix = + + Add a new type of shortcut option COMPIZ_METAKEY_OPTION. + + = Testing = + + Added.. Fixes: https://bugs.launchpad.net/bugs/939517. Approved by Mirco Müller. + +2012-02-28 Andrea Azzarone + + Fix bug #939517. + +2012-03-13 Paul Sladen + + Dash/HUD: logic inversion in spinner rotation offset (LP: #943656). Fixes: https://bugs.launchpad.net/bugs/943656. Approved by Andrea Azzarone, Andrea Cimitan. + +2012-03-01 Paul Sladen + + Dash/HUD: logic inversion in spinner rotation offset + +2012-03-13 Andrea Cimitan + + The glow in the alt-tab switcher is misaligned leading to a dark line at right and bottom edge. This commit fixes it. Fixes: . Approved by Andrea Cimitan. + +2012-02-29 Andrea Cimitan + + Fix misalignment of the glow in alt-tab switcher + +2012-03-13 Martin Mrazik + + I'll try to automate this in the next few days.. Fixes: . Approved by Thomi Richards. + +2012-02-28 Martin Mrazik + + manual test for lp:929506 + +2012-03-13 Andrea Azzarone + + = The Problem = + + See: https://bugs.launchpad.net/unity/+bug/748101. + + = The Fix = + + Keep in consideration the baseline to align the labels inside the category header. + + = Testing = + + AP test: ./tools/autopilot run autopilot.tests.test_dash.DashVisualTests.test_see_more_result_alignment. Fixes: https://bugs.launchpad.net/bugs/748101. Approved by Alex Launi, Marco Trevisan (Treviño), Thomi Richards, Andrea Cimitan. + +2012-03-13 Andrea Azzarone + + Merge trunk. + +2012-02-29 Andrea Azzarone + + Fix. + +2012-02-29 Andrea Azzarone + + Complete the AP test. + +2012-02-29 Andrea Azzarone + + Merge trunk. + +2012-02-29 Andrea Azzarone + + First draft for the AP test. + +2012-02-29 Andrea Azzarone + + Use something like a baseline alignment for the category header. + +2012-03-13 Thomi Richards + + Make autopilot test log lines much shorter by using the module name rather than the full path name.. Fixes: . Approved by Jason Smith. + +2012-03-13 Thomi Richards + + Use the module name rather than the full path name in the test log file. + +2012-03-12 Jason Smith + + == The Problem == + Design requested changes to multi-monitor to provide support for toggling barriers and multiple-launchers + + == The Solution == + Implement the options + + == Testing == + Interactions should be covered under existing tests. Fixes: . Approved by Tim Penhey. + +2012-03-12 Jason Smith + + don't violate the rule of three + +2012-03-12 Jason Smith + + change text to be a little clearer + +2012-03-12 Jason Smith + + add manual test + +2012-03-12 Jason Smith + + ensure that we have the launcher properly reflect the entire desktop rather than just the monitor when in single launcher mode + +2012-03-12 Jason Smith + + implement mm options for multiple launchers + +2012-03-12 Brandon Schaefer + + Removed comments added by me... + +2012-03-08 Brandon Schaefer + + merge trunk + +2012-03-05 Brandon Schaefer + + Fixed style problems, along with some other clean ups. + +2012-02-06 Brandon Schaefer + + Changed to use std::sstream instead of std::string + +2012-02-06 Brandon Schaefer + + markup now uses std::string instead of gchar* and g_strdup_printf() + +2012-02-03 Brandon Schaefer + + Cleaned up, and fixed conflicts + +2012-03-12 Marco Trevisan (Treviño) + + Added tests for SwitcherController changes done in lp:~3v1n0/unity/alt+tab-background-load, enabled the SwitcherModel tests as well.. Fixes: https://bugs.launchpad.net/bugs/942634. Approved by Tim Penhey, Andrea Azzarone. + +2012-03-06 Marco Trevisan (Treviño) + + test_switcher_controller: make the construction test to really test something + +2012-03-06 Marco Trevisan (Treviño) + + test_switcher_controller: removing the redoundant Test prefix in functions + +2012-03-06 Marco Trevisan (Treviño) + + test_switcher_controller: reduce the time to use to perform the test + +2012-03-06 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/alt+tab-background-load changes + +2012-02-28 Marco Trevisan (Treviño) + + tests: added test_switcher_controller to check construction and lazy load + +2012-02-28 Marco Trevisan (Treviño) + + Tests, enabling test_switcher_model + +2012-02-28 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-12 Marco Trevisan (Treviño) + + Add some background operations to the SwitcherController to make the Alt+Tab to show-up quicker + + The switcher controller now when initialized setup a lazy timer (now set to 10s) that on timeout will construct the + switcher view, to make the first time usage quicker. + + Also, I've added an idle that will run as soon as the user presses the switcher key combination, that constructs the view in background (and shows an invisible window, since the the ShowWindow operation can take longer than just setting the view visible) to make sure that when the show-timeout occurs everything is already there and it just needs to be shown (setting its opacity). + + Tests included into the branch lp:~3v1n0/unity/alt+tab-background-load.tests. Fixes: https://bugs.launchpad.net/bugs/942634. Approved by Andrea Azzarone. + +2012-03-06 Marco Trevisan (Treviño) + + SwitcherController: allow to define the load timeout on construction + +2012-03-06 Marco Trevisan (Treviño) + + SwitcherController: use protected member to set the construct timeout + + So it will be possible to test it. + +2012-02-27 Marco Trevisan (Treviño) + + SwitcherController: setting the load timeout to 20s + +2012-02-26 Marco Trevisan (Treviño) + + SwitcherController: use SetOpacity instead of SetVisible + +2012-02-26 Marco Trevisan (Treviño) + + SwitcherController: move to UBusManager + +2012-02-25 Marco Trevisan (Treviño) + + SwitcherController: add an idle to construct the view when waiting for the show timeout + +2012-02-25 Marco Trevisan (Treviño) + + SwitcherController: add a lazy loader to create the Alt+Tab window on background + + This should improve the startup time of the first Alt+Tab session. + +2012-03-12 Marco Trevisan (Treviño) + + Partly fixes bug #824965 enabling scroll wheel on Alt+Tab to switch the active application.. Fixes: https://bugs.launchpad.net/bugs/824965. Approved by Alex Launi, Thomi Richards. + +2012-03-07 Marco Trevisan (Treviño) + + Merging with trunk changes. + +2012-03-06 Marco Trevisan (Treviño) + + UnityScreen: add / remove scroll actions in compiz screen + + This is not strictly needed here since compiz seems to grab them + already, but this should ensure that they're managed. + +2012-03-06 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-29 Marco Trevisan (Treviño) + + Autopilot, switcher: split mouse-wheel tests + +2012-02-29 Marco Trevisan (Treviño) + + unityshell: support both horizontal and vertical scroll events on AltTab + +2012-02-29 Marco Trevisan (Treviño) + + unityshell: remove unneeded space. + +2012-02-29 Marco Trevisan (Treviño) + + Added autopilot test for switcher mouse-wheel support. + +2012-02-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-27 Marco Trevisan (Treviño) + + UnityScreen: igonore quick scroll events, use a limit of 150ms + +2012-02-26 Marco Trevisan (Treviño) + + unityshell: inverting the scrolling direction to for the switcher + +2012-02-26 Marco Trevisan (Treviño) + + unityshell: allow to change Switcher selected icon via mouse-wheel + +2012-03-12 Thomi Richards + + Problem: Several of the test_shortcut_hint autopilot tests fail. + Solution: Update tests. One issue was that the autopilot API had changed, another was a typo in the test.. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-13 Thomi Richards + + Fixed shortcut_hint tests. + +2012-03-13 Thomi Richards + + Merged branch that fixes unity crash in shortcut hint controller. + +2012-03-12 Marco Trevisan (Treviño) + + Avoid autopilot to crash unity when the shortcut hint view has not been initialized.. Fixes: . Approved by Thomi Richards. + +2012-03-12 Marco Trevisan (Treviño) + + ShortcutController: avoid to crash during autopilot if view_window_ has not been initialized. + +2012-03-12 Marco Trevisan (Treviño) + + Add support to hide the shortcut hint view by Escape key. + + I've made some work to handle the Escape keypress events for both the Launcher + Switcher and the Shortcut hint view, using this policy: + - If the Launcher switcher is active, Escape terminates it + - If the Shortcut hint is active, Escape terminates it + - If both are active, the first Escape terminates the Super+Tab, + the second one will hide the shortcut hint. + + Added autopilot support for the Shortcut hint controller, and a first bunch of tests.. Fixes: https://bugs.launchpad.net/bugs/943422. Approved by Andrea Azzarone, Thomi Richards. + +2012-03-06 Marco Trevisan (Treviño) + + autopilot, test_shortcut_hint.py: set the default size on constructor. + +2012-03-06 Marco Trevisan (Treviño) + + autopilot: test_shortcut_hint.py check if all the shortcut hints are showing together + + Shortcut hints view and the launcher icon hint should be shown at the same time + +2012-03-06 Marco Trevisan (Treviño) + + Merging again with thomi's fixed tests + +2012-03-05 Thomi Richards + + Fixed tests so they pass, and merged launcher emulator changes, so this should merge cleanly with trunk. + +2012-03-05 Thomi Richards + + Removed unneeded refresh_state calls, fixed test. + +2012-03-02 Thomi Richards + + Various test cleanups. + +2012-03-02 Marco Trevisan (Treviño) + + autopilot, test_shortcut_hint: added ShortcutHints integration tests. + + They tests the interaction between the shortcut hints and other unity + parts, especially the LauncherSwitcher and the other Super keybindings + +2012-03-02 Marco Trevisan (Treviño) + + autopilot: test launcher switcher cancel by Escape key + +2012-03-01 Marco Trevisan (Treviño) + + autopilot, test_shortcut_hint: added first basic shortcut hint tests + +2012-03-01 Marco Trevisan (Treviño) + + autopilot: ShortcutHint emulator, misc code fixes + +2012-03-01 Marco Trevisan (Treviño) + + autopilot, X11 emulator: allow to get the primary monitor + +2012-03-01 Marco Trevisan (Treviño) + + ShortcutController: add more introspection data. + + Setting it as visible when the view is really visible. + Also include the FADE duration into the timeout. + +2012-03-01 Marco Trevisan (Treviño) + + unityshell: add the shortcut controller as an introspectable child. + +2012-03-01 Marco Trevisan (Treviño) + + Merging with autopilot fixes included into lp:~3v1n0/unity/super+tab-shortcut-fixes + +2012-03-01 Marco Trevisan (Treviño) + + autopilot: add first shortcut_hint.py emulator scheleton + +2012-03-01 Marco Trevisan (Treviño) + + ShortcutController: added introspection support + +2012-02-29 Marco Trevisan (Treviño) + + UnityScreen: EnableCancelAction, add support for multiple targets + + It allows to setup more cancel actions (one per target) and to remove them. + Thanks to this, we can handle the Escape keypress for both the Launcher + Switcher and the Shortcut hint view. + And we use this policy: + - If the Launcher switcher is active, Escape terminates it + - If the Shortcut hint is active, Escape terminates it + - If both are active, the first Escape terminates the Super+Tab, + the second one will hide the shortcut hint. + +2012-03-12 Gord Allott + + adds an include that broke the standalone client build + + Build fix - tests not applicable. Fixes: . Approved by Michal Hruby. + +2012-03-01 Gord Allott + + fixes the dash standalone client build + +2012-03-12 Andrea Azzarone + + The problem + === + Dash - Missing category separator line in dash + + The fix + === + + 17 - bool found_one = false; + 18 - + 19 - for (rit = children.rbegin(); rit != children.rend(); ++rit) + 20 - { + 21 - PlacesGroup* group = static_cast(*rit); + 22 - + 23 - if (group->IsVisible()) + 24 - group->SetDrawSeparator(found_one); + 25 - + 26 - found_one = group->IsVisible(); + 27 - } + + If the next group is not visibile the separator is not shown in the prev group. + This branch fixes it moving the logic side in another (testable) function. I'd love to + remove the static_cast too but I can't find an easy way right now. + + The test + === + Adds a unit test for the logic side.. Fixes: https://bugs.launchpad.net/bugs/850984. Approved by Marco Trevisan (Treviño). + +2012-03-09 Andrea Azzarone + + Fix include "issue". + +2012-03-09 Andrea Azzarone + + Fix. + +2012-03-09 Andrea Azzarone + + Adds tests. + +2012-03-09 Andrea Azzarone + + Fix bug #850984. + +2012-03-12 Michael Rawson + + Fixes bug #877382 (no long description on hover for CCSM).. Fixes: https://bugs.launchpad.net/bugs/877382. Approved by Tim Penhey. + +2012-03-01 Michael Rawson + + Fixed bug #877382 + +2012-03-12 Tim Penhey + + Added some manual tests for the launcher reorder animations.. Fixes: . Approved by Mirco Müller. + +2012-03-05 Tim Penhey + + Added a few manual tests about the moving of launcher icons. + +2012-03-12 Lorenzo Mattei + + . Fixes: https://bugs.launchpad.net/bugs/891818. Approved by Marco Trevisan (Treviño), Mirco Müller. + +2012-03-07 Lorenzo Mattei + + Safer autopilot test + +2012-03-07 Lorenzo Mattei + + Added autopilot test for lp:891818 + +2012-03-05 Lorenzo Mattei + + Fixex lp:891818 + +2012-03-12 Michal Hruby + + Makes the tests less racy by using g_timeout_add instead of the add_seconds which tries to fire multiple timeouts at once at the cost of precision. Also fixes a possible crash in the tests caused by FilesystemLenses.. Fixes: . Approved by Gord Allott. + +2012-03-05 Michal Hruby + + Safer tests + +2012-03-12 Michal Hruby + + == The Problem == + Crashed lens doesn't restart unless searching in home view. + + == The Solution == + Make sure a Search call can restart a lens just as GlobalSearch can. + + == Testing == + Added a manual test for the issue.. Fixes: https://bugs.launchpad.net/bugs/947301. Approved by Mirco Müller, Gord Allott. + +2012-03-06 Michal Hruby + + Fix the killall command in manual test + +2012-03-05 Michal Hruby + + Make sure Search method can restart a lens (not just GlobalSearch) + +2012-03-12 Paolo Rotolo + + Fix typo in plugins/unityshell/unityshell.xml.in: stoped → stopped. Fixes LP: #931382.. Fixes: https://bugs.launchpad.net/bugs/931382. Approved by Marco Trevisan (Treviño). + +2012-03-07 Paolo Rotolo + + Fix typo in plugins/unityshell/unityshell.xml.in: stoped → stopped. Fixes LP: #931382. + +2012-03-12 Martin Mrazik + + Test template to be used for all manual tests to ensure: + 1. consistency acrross test-cases + 2. quality of the manual tests + . Fixes: . Approved by Alex Launi. + +2012-03-07 Martin Mrazik + + Test template to be used for all manual tests to ensure: + 1. consistency acrross test-cases + 2. quality of the manual tests + +2012-03-12 Thomi Richards + + Adds the ability in autopilot to get a launcher icon with a specified desktop file.. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-09 Thomi Richards + + Added functionality to launcher model class - you can now retrieve icons by their desktop icon. + +2012-03-12 Thomas Voß + + Introduces a cached variable to handle the Google Test source dir.. Fixes: . Approved by Didier Roche. + +2012-03-09 Thomas Voß + + Introduced a cached variable for google-test source path. + +2012-03-12 Thomi Richards + + The Problem: + + Node properties in the unity introspection visualiser script were shown unordered. This made it hard to view node properties. + + The solution: + + Node properties are now sorted. + + Tests: + + ummm... no.. Fixes: . Approved by Tim Penhey. + +2012-03-12 Thomi Richards + + Unity introspection script now sorts node properties alphabetically. + +2012-03-12 Thomi Richards + + Fixed an autopilot test so it actually tests something useful.. Fixes: . Approved by Tim Penhey. + +2012-03-12 Thomi Richards + + The test_reveal_with_mouse_under_launcher test no longer moves the mouse out of the way before revealing the launcher. Previously this test wasn't actually testing anything. + 2012-03-12 Thomi Richards Fixed the CommandLensSearchTests.test_run_before_refresh test so it passes, and refactored the bamf emulator.. Fixes: . Approved by Tim Penhey. diff -Nru unity-5.6.0/CMakeLists.txt unity-5.8.0/CMakeLists.txt --- unity-5.6.0/CMakeLists.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 @@ -8,7 +8,7 @@ # set (PROJECT_NAME "unity") set (UNITY_MAJOR 5) -set (UNITY_MINOR 6) +set (UNITY_MINOR 8) set (UNITY_MICRO 0) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "5.0") @@ -122,7 +122,7 @@ # # Compiz Plugins # -set (UNITY_PLUGIN_DEPS "compiz;nux-2.0>=2.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4;atk;unity-misc>=0.4.0;gconf-2.0;libutouch-geis;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;gnome-desktop-3.0;gdu") +set (UNITY_PLUGIN_DEPS "compiz;nux-2.0>=2.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;gconf-2.0;libutouch-geis;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;gnome-desktop-3.0;gdu;xfixes") add_subdirectory(plugins/unityshell) add_subdirectory(plugins/gtkloader) @@ -133,10 +133,22 @@ # subdirs add_subdirectory(doc) +# Check for google test and build it locally +set( + GTEST_ROOT_DIR + "/usr/src/gtest" # Default value, adjustable by user with e.g., ccmake + CACHE + PATH + "Path to Google test srcs" +) + find_path(GTEST_INCLUDE_DIR gtest/gtest.h) if (GTEST_INCLUDE_DIR) #FIXME - hardcoded is bad! - add_subdirectory(/usr/src/gtest gtest) + add_subdirectory( + ${GTEST_ROOT_DIR} + gtest + ) endif(GTEST_INCLUDE_DIR) add_subdirectory(services) diff -Nru unity-5.6.0/com.canonical.Unity.gschema.xml unity-5.8.0/com.canonical.Unity.gschema.xml --- unity-5.6.0/com.canonical.Unity.gschema.xml 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/com.canonical.Unity.gschema.xml 2012-03-23 11:53:16.000000000 +0000 @@ -20,11 +20,6 @@ Whether the home screen should be expanded. Whether the home screen should be expanded. - - '#757550507B7BFFFF' - Average background color - The average color derived from the currently set desktop-wallpaper. This is written/updated by the Unity-process and read by NotifyOSD-process for example. - diff -Nru unity-5.6.0/debian/changelog unity-5.8.0/debian/changelog --- unity-5.6.0/debian/changelog 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/debian/changelog 2012-03-23 14:02:25.000000000 +0000 @@ -1,3 +1,102 @@ +unity (5.8.0-0ubuntu1) precise-proposed; urgency=low + + * New upstream release. + - New "push mouse offscreen" feature really difficult to get (LP: #923749) + - unity-2d-panel crashed with SIGSEGV in + unity::indicator::DBusIndicators::Impl::RequestSyncAll() (LP: #864737) + - Pressing "Alt+Enter" causes compiz to crash in CompOption::value() from + unity::UnityScreen::showLauncherKeyTerminate (LP: #960957) + - SEGSIGV after unplugging external monitor (LP: #962693) + - Background colorization should use a different heuristic (LP: #865239) + - compiz+unity3d generates > 50 wakeups a second on idle system + (LP: #917210) + - [FFe, UIFe] HUD - The HUD does not respect launcher autohide or icon + size settings (LP: #921506) + - clicking on folders in the file lens does not open nautilus + (LP: #921665) + - No text inside multirange filters (LP: #927710) + - can't alt-tab restore minimized uis which have an instance on another + workspace (LP: #933397) + - Ubuntu Software Center Unity launcher integration is not working + (LP: #932280) + - The line separator between the launcher and the dash is cleared when + selecting a category (LP: #941082) + - unity-panel-service crashed with SIGSEGV in g_hash_table_foreach() + (LP: #937119) + - Alt-F10 locks up Unity (LP: #948522) + - multimonitor, launcher: Provide an option to display either a single + launcher or a launcher on each display in a multi-monitor environment + (LP: #950136) + - multimonitor: Please give me a way to turn off sticky monitor edges + (LP: #946104) + - Unity 5.6: key bindings (such as Super) don't work on empty workspace or + on slow/loaded systems (LP: #953089) + - Alt+arrows keyboard shortcuts don't invoke Back and Forward navigation + (LP: #953783) + - HUD is sending 2 menu signals instead of 1 (LP: #956878) + - 6th item of HUD not fully visible (LP: #957229) + - HUD: seems to trigger operations more than once (LP: #960503) + - Launcher gets always desaturated when using HUD on secondary monitor + (LP: #961169) + - [5.8 pre staging] launcher is displayed on the left screen, not the + primary one (LP: #961281) + - launcher icons do not re-saturate after dash is closed (LP: #961844) + - Launcher shows arrows for applications on all workspaces (LP: #961977) + - Dash - Implement overlay scrollbars in Dash (LP: #608124) + - [UIFe] Dash - No message displayed when no results are returned in the + Dash (LP: #711199) + - Dash - "See more..." line should be base-aligned with section header + (LP: #748101) + - Dash - Missing category separator line in dash (LP: #850984) + - Dash and Launcher - As soon as a user starts dragging a file from the + Dash, there is a 'flicker' before the Launcher icons that are valid drop + receptacles re-saturate (LP: #863230) + - Dash - When multiple results have equal string match relevancy ranking, + those with equal ranking should be then sorted by frequency of use. + (LP: #871900) + - Keyboard shortcut - F10 shortcut is used to show menu and this is wrong + (LP: #878492) + - Frozen double icon after launching and dragging at once (LP: #918753) + - HUD is over gtk-menu (LP: #921305) + - Files missing from Unity's POTFILES.in (LP: #923762) + - Hidden menus are not really hidden (LP: #926330) + - Need to bring back a "reveal border" option (LP: #927523) + - Unity Panel lose shadow on changing the wallpaper (LP: #930271) + - Incorrect item count in "See x more results" (LP: #934944) + - Coverity PW.PARAMETER_HIDDEN - CID 10671 (LP: #938890) + - Coverity PW.CAST_TO_QUALIFIED_TYPE - CID 10670 (LP: #938895) + - [Shortcut overlay] Hardcoded value for switching ws (LP: #939517) + - Dash - Font metrics and colors are wrong (LP: #942508) + - Alt-tab switcher view should be pre-loaded to improve the startup time + (LP: #942634) + - Shortcut hint overlay should be hidden by Escape key (LP: #943422) + - Dash/HUD - Spinner off-centre, looks drunk (LP: #943656) + - Unable to restart lens which doesn't do global search (LP: #947301) + - Launcher Switcher (Super+Tab) selection could be changed by arrow keys + too (LP: #950404) + - you have to release alt for alt + F10 working (LP: #943223) + - magnifying glass is being overdrawn by text in searchbar (LP: #955160) + - hud searches don't update properly (LP: #956480) + - Filters not working (LP: #961338) + - Panel goes solid if switching from hud to dash or vice versa + (LP: #962720) + - compiz configuration options for unity are "fixme" (LP: #877382) + - Launcher - When Launcher already has keyboard focus, Alt-F1 doesn't exit + focus (LP: #885304) + - Dash - dash is not closed with alt+f4 (LP: #891818) + - Dash Home tooltip should use header capitalization (LP: #924354) + - Typo in string 149: stoped (LP: #931382) + - unity should not use dconf to store the average background colour + (LP: #949277) + - [UIFE] No HUD keybinding in the shortcut overlay (LP: #942515) + - The hseparator is drawn also for the final dash category (LP: #955296) + * debian/patches/series: + - remove the distro patches in trunk right now + * debian/control: + - build-dep on latest nux,compiz and libcompizconfig for ABI breakage + + -- Didier Roche Fri, 23 Mar 2012 12:55:51 +0100 + unity (5.6.0-0ubuntu4) precise; urgency=low * 02_remove_ungrad_workaround2.patch: diff -Nru unity-5.6.0/debian/control unity-5.8.0/debian/control --- unity-5.6.0/debian/control 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/debian/control 2012-03-23 14:02:25.000000000 +0000 @@ -25,9 +25,9 @@ libunity-misc-dev (>= 4.0.4), libutouch-grail-dev (>= 1.0.20), libxcb-icccm4-dev, - libnux-2.0-dev (>= 2.6.0), - compiz-dev (>= 1:0.9.7.0+bzr3035), - libcompizconfig0-dev (>= 0.9.7.0~bzr428-0ubuntu4~), + libnux-2.0-dev (>= 2.8.0), + compiz-dev (>= 1:0.9.7.2), + libcompizconfig0-dev (>= 0.9.7.0~bzr428-0ubuntu6~), xsltproc, libboost1.46-dev, libboost-serialization1.46-dev, diff -Nru unity-5.6.0/debian/patches/01_remove_ungrab_workaround.patch unity-5.8.0/debian/patches/01_remove_ungrab_workaround.patch --- unity-5.6.0/debian/patches/01_remove_ungrab_workaround.patch 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/debian/patches/01_remove_ungrab_workaround.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -Index: ubuntu/plugins/unityshell/src/unityshell.cpp -=================================================================== ---- ubuntu.orig/plugins/unityshell/src/unityshell.cpp 2012-03-13 09:39:19.944369000 +0100 -+++ ubuntu/plugins/unityshell/src/unityshell.cpp 2012-03-13 09:44:21.501069418 +0100 -@@ -111,7 +111,6 @@ - , _in_paint(false) - , relayoutSourceId(0) - , _redraw_handle(0) -- , alt_tap_timeout_id_(0) - , newFocusedWindow(nullptr) - , doShellRepaint(false) - , allowWindowPaint(false) -@@ -372,9 +371,6 @@ - if (relayoutSourceId != 0) - g_source_remove(relayoutSourceId); - -- if (alt_tap_timeout_id_) -- g_source_remove(alt_tap_timeout_id_); -- - ::unity::ui::IconRenderer::DestroyTextures(); - QuicklistManager::Destroy(); - -@@ -1608,12 +1604,6 @@ - if (!grab_index_) - return false; - -- if (alt_tap_timeout_id_) -- { -- g_source_remove(alt_tap_timeout_id_); -- alt_tap_timeout_id_ = 0; -- } -- - screen->addAction(&optionGetAltTabRight()); - screen->addAction(&optionGetAltTabDetailStart()); - screen->addAction(&optionGetAltTabDetailStop()); -@@ -1808,19 +1798,6 @@ - action->setState(action->state() | CompAction::StateTermKey); - last_hud_show_time_ = g_get_monotonic_time(); - -- /* Workaround to fix #943194 */ -- alt_tap_timeout_id_ = g_timeout_add(local::ALT_TAP_DURATION, [] (gpointer data) -> gboolean { -- auto self = static_cast(data); -- -- if (!self->switcher_controller_->Visible()) -- { -- XUngrabKeyboard(self->screen->dpy(), CurrentTime); -- } -- -- self->alt_tap_timeout_id_ = 0; -- return FALSE; -- }, this); -- - // pass key through - return false; - } -@@ -1840,12 +1817,6 @@ - if (!(state & CompAction::StateTermTapped)) - return false; - -- if (alt_tap_timeout_id_) -- { -- g_source_remove(alt_tap_timeout_id_); -- alt_tap_timeout_id_ = 0; -- } -- - gint64 current_time = g_get_monotonic_time(); - if (current_time - last_hud_show_time_ > (local::ALT_TAP_DURATION * 1000)) - { -Index: ubuntu/plugins/unityshell/src/unityshell.h -=================================================================== ---- ubuntu.orig/plugins/unityshell/src/unityshell.h 2012-03-12 10:18:17.351155000 +0100 -+++ ubuntu/plugins/unityshell/src/unityshell.h 2012-03-13 09:44:36.989146215 +0100 -@@ -290,7 +290,6 @@ - bool _in_paint; - guint32 relayoutSourceId; - guint32 _redraw_handle; -- guint32 alt_tap_timeout_id_; - typedef std::shared_ptr CompActionPtr; - typedef std::vector ShortcutActions; - ShortcutActions _shortcut_actions; diff -Nru unity-5.6.0/debian/patches/02_remove_ungrad_workaround2.patch unity-5.8.0/debian/patches/02_remove_ungrad_workaround2.patch --- unity-5.6.0/debian/patches/02_remove_ungrad_workaround2.patch 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/debian/patches/02_remove_ungrad_workaround2.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -=== added file 'manual-tests/AltCombos.txt' ---- a/manual-tests/AltCombos.txt 1970-01-01 00:00:00 +0000 -+++ b/manual-tests/AltCombos.txt 2012-03-14 09:20:23 +0000 -@@ -0,0 +1,10 @@ -+Alt+Arrow keys not passed to application -+---------------------------------------- -+Tests that Alt+ArrowKey events are correctly passed to the active window -+when Unity is not responding to them. -+ -+#. Open gnome-terminal -+#. While holding Alt, tap arrow keys: Up, Down, Right, Left -+ -+Outcome -+ The terminal should show the keycodes were received as text "ABCD". - -=== modified file 'plugins/unityshell/src/unityshell.cpp' ---- a/plugins/unityshell/src/unityshell.cpp 2012-03-13 20:44:08 +0000 -+++ b/plugins/unityshell/src/unityshell.cpp 2012-03-14 09:20:23 +0000 -@@ -1767,33 +1767,45 @@ - bool UnityScreen::altTabPrevAllInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - { - if (switcher_controller_->Visible()) -+ { - switcher_controller_->Prev(); -+ return true; -+ } - -- return true; -+ return false; - } - - bool UnityScreen::altTabPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - { - if (switcher_controller_->Visible()) -+ { - switcher_controller_->Prev(); -+ return true; -+ } - -- return true; -+ return false; - } - - bool UnityScreen::altTabDetailStartInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - { - if (switcher_controller_->Visible()) -+ { - switcher_controller_->SetDetail(true); -+ return true; -+ } - -- return true; -+ return false; - } - - bool UnityScreen::altTabDetailStopInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - { - if (switcher_controller_->Visible()) -+ { - switcher_controller_->SetDetail(false); -+ return true; -+ } - -- return true; -+ return false; - } - - bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) -@@ -1813,9 +1825,12 @@ - bool UnityScreen::altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - { - if (switcher_controller_->Visible()) -+ { - switcher_controller_->PrevDetail(); -+ return true; -+ } - -- return true; -+ return false; - } - - bool UnityScreen::launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) - diff -Nru unity-5.6.0/debian/patches/series unity-5.8.0/debian/patches/series --- unity-5.6.0/debian/patches/series 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -01_remove_ungrab_workaround.patch -02_remove_ungrad_workaround2.patch diff -Nru unity-5.6.0/manual-tests/AltCombos.txt unity-5.8.0/manual-tests/AltCombos.txt --- unity-5.6.0/manual-tests/AltCombos.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/AltCombos.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,20 @@ +Alt+Arrow keys not passed to application +---------------------------------------- +Tests that Alt+ArrowKey events are correctly passed to the active window +when Unity is not responding to them. + +#. Open gnome-terminal +#. While holding Alt, tap arrow keys: Up, Down, Right, Left + +Outcome + The terminal should show the keycodes were received as text "ABCD". + + +Alt+Enter Crash +--------------- +Tests that Alt+Enter does not cause unity to crash (LP: #960957) + +#. Press Alt+Enter. + +Outcome + Unity/compiz should not crash. diff -Nru unity-5.6.0/manual-tests/Dash.txt unity-5.8.0/manual-tests/Dash.txt --- unity-5.6.0/manual-tests/Dash.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/Dash.txt 2012-03-23 11:53:16.000000000 +0000 @@ -1,41 +1,3 @@ -Mouse down and search bar focus -------------------------------- -This test makes sure that the search bar doesn't lose the focus clicking into -am emtpy area (or into a filter button). - -#. Open the app lens -#. Expand the filter bar -#. Click between a filter expander and the All Button (for example between Type > and All) - or into a filter button. - -Outcome -The cursor is still blinking. - - -Category headers focus ----------------------- -This test makes sure that clicking on a category headers doesn't focus it. - -#. Open the apps lens. -#. Click on the dash search bar to make sure that the search bar has the focus. -#. Click on a category header to expand/collapse a category - -Outcome - The category should expand/collaspe and the search bar still has the focus. - - -Drag and drop dash icons ----------------------------- -This test makes sure that. - -#. Open the apps lens. -#. Drag a dash icon. -#. Now drop it inside the dash but on another icon or on a blank space. - -Outcome - The dropped icon should not have the keyboard focus and should not remain - enlightened. - Dash SearchBar middle-click --------------------------- This test shows how the middle click over the dash search bar should work @@ -51,3 +13,26 @@ The text previously selected is pasted on the search bar at mouse pointer position, if the operation is repeated the text is inserted where the mouse pointer is. + +Dash correct number of "see more" results with horizontal renderer +--------------------------- +This test ensures a correct number of "see more" results in the dash when using a horizontal renderer +(see lp:934944) + +#. Open the dash, navigate to a lens that uses a horizontal renderer such as the gwibber lens or music lens +#. Ensure that a category in the results has a "See x more results" label +#. Expand category that has "See x more results" label + +Outcome + The category will expand to show all the results, user should ensure that the X in "See x more categories" was valid. + +Dash Spinner +------------ +This tests that the spinner is properly shown when searching with the Dash. + +#. Open the dash and type a string ("abc"). + +Outcome + If the search is taking more than ~150ms, a spinner should be animating next + to the search bar, once the spinner stops spinning the results shouldn't + change. diff -Nru unity-5.6.0/manual-tests/DragDropDashLauncher.txt unity-5.8.0/manual-tests/DragDropDashLauncher.txt --- unity-5.6.0/manual-tests/DragDropDashLauncher.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/DragDropDashLauncher.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,6 @@ +- open Dash +- go to Files-lens +- select and drag a document-file (e.g. text or image) to the launcher +- as you drag the document-file watch the drag-targets (drop-recepticals) saturate +- this saturation-process should be smooth and without flicker +- the tinting of the non-drag-targets should not change diff -Nru unity-5.6.0/manual-tests/Filters.txt unity-5.8.0/manual-tests/Filters.txt --- unity-5.6.0/manual-tests/Filters.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/Filters.txt 2012-03-23 11:53:16.000000000 +0000 @@ -12,15 +12,3 @@ category header. #. Click on it (again). #. The filter category should expand. - - -Test no-over-state effect -========================= -This test show that filter buttons in the Dash do not have a mouse -over state. - -#. Open the dash. -#. Move the mouse on filter buttons. - -Outcome - The filter buttons have no mouseover state effect. diff -Nru unity-5.6.0/manual-tests/GrayscaleAntialiasing.txt unity-5.8.0/manual-tests/GrayscaleAntialiasing.txt --- unity-5.6.0/manual-tests/GrayscaleAntialiasing.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/GrayscaleAntialiasing.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -Grayscale antialiasing test -=========================== - -#. Launch gnome-tweak-tool and select "Fonts" in the left pane -#. Select value "Grayscale" for "Antialiasing" -#. Log out and back in - -Outcome - Text in unity panel, launcher and lenses should be antialiased using grayscale method. - If text is not antialiased, the test is failed. - - diff -Nru unity-5.6.0/manual-tests/Hud.txt unity-5.8.0/manual-tests/Hud.txt --- unity-5.6.0/manual-tests/Hud.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/Hud.txt 2012-03-23 11:53:16.000000000 +0000 @@ -56,3 +56,29 @@ After pressing escape in step three, the text "test" should be removed from the hud search After step four, the hud should dismiss itself and not be present. +Hud Reveal Behaviour +--------- +This test ensures that the hud behaves correctly with a locked out launcher + +#. Ensure the launchers hide mode is set to "Never" +#. Tap Alt + +Outcome + The Launcher should stick be locked out. + The Launcher icons should be desaturated. + The top most Launcher icon should be an icon related the the focused window + The BFB should not be present + + +Hud Sending Undo +---------------- +This test ensure that the undo action is properly handle in a text editor. + +#. Open GEdit and start a new document +#. Type "0 1" +#. Tap Alt +#. Type "undo" +#. Press and release the Enter Key + +Outcome + After pressing the Enter key the text in GEdit should be "0 " diff -Nru unity-5.6.0/manual-tests/Launcher.txt unity-5.8.0/manual-tests/Launcher.txt --- unity-5.6.0/manual-tests/Launcher.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/Launcher.txt 2012-03-23 11:53:16.000000000 +0000 @@ -42,6 +42,7 @@ clicking on its launcher icon should bring to focus the last focused window in the last used workspace. + Test Alt+F1 KeyNavMode Mouse Works ------------------------------- This test shows that the mouse still works normally while keynav mode is active. @@ -55,6 +56,7 @@ of keynav mode, or clicking on a launcher icon. All these actions should also exit the keynav mode. + Test Alt+F1 KeyNavMode Shortcuts ----------------------------- This test shows that all the shortcuts work and also exits from keynav mode. @@ -73,6 +75,7 @@ a new terminal. This is to show all SUPER, ALT, and CTRL shortcuts work; while closing the keynav mode. + Test Alt+F1 NavMode Quicklist Click Exit ---------------------------------------- This Test shows that clicking on a quicklist option quits keynav mode. @@ -84,6 +87,7 @@ Outcome No matter what option you click will exit keynav mode. + Drag Icons to Trash ------------------- @@ -100,3 +104,257 @@ * The trash can icon should remain stationary during the entire operation. * The operation should NOT LOOK LIKE THIS: https://bugs.launchpad.net/unity/+bug/932365/+attachment/2739868/+files/out-2.ogv + +Dragging icons to reorder - initial position +-------------------------------------------- +This test is all position of the dragged image in relation to the mouse pointer. + +#. Move the mouse so it is over a launcher icon for an application +#. Press and hold the mouse button + +Outcome: + * The icon should "detach" from the launcher and be centered on the mouse + * There sould be a blank "space" in the launcher where the icon was + * Any "pips" next to the icon aren't visible during the drag, and there are + none showing in the blank space + + +Dragging icons to reorder - over launcher +----------------------------------------- +This test is all about the smoothness of the animation around the reordering +of icons in the launcher. + +#. Move the mouse so it is over a launcher icon for an application +#. Press and hold the mouse button +#. Drag the icon up and down over the icons in the launcher + +Outcome: + * As the centre of the dragged icon passes the mid-point of the next item + above or below it, the icon being dragged over moves and is replaced by the + blank "space". + * The animation should be smooth + * If the dragged icon is moved rapidly, multiple icons can be moving either + upwards or downwards as the space is moved into place under the dragged icon + * The BFB and the switcher icons do not move + + +Dragging icons to reorder - away from launcher +----------------------------------------- +This test is about reordering the icons without the animation showing. + +#. Move the mouse so it is over a launcher icon for an application +#. Press and hold the mouse button +#. Drag the icon away from the launcher +#. Drag the icon up and down where there is no overlap with the launcher. +#. Release + +Outcome: + * As the icon is dragged away from the launcher, the "space" is closed up + and replaced with a grey line. + * As the icon is dragged up and down, the line moves between other launcher + icons. + * When released, the icon "flies" back into the launcher, a spaces opens for + it, and the any pips for running apps show again. + + +Dragging icon while program is starting +--------------------------------------- +This test that when a program is executed from the launcher and the icon is +getting dragged that the icon doesn't get frozen on the launcher. + +#. Click on Ubuntu Software Center from the launcher. +#. While it's starting drag the Ubuntu Software Center icon. +#. Drag the icon half over the launcher and desktop. +#. Wait for the program to start. + +Outcome: + * The icon should go back to its correct position in the launcher. + + +Test launchers with multiple monitors +------------------------------------- +This test checks if the launchers are shown in the correct monitor when +using a multimonitor setup. + +#. Open CCSM and and set the Experimental -> "Launcher Monitors" unity setting + to "All Desktops" + +Outcome: + * A launcher should be shown in each monitor. + +#. Open CCSM and and set the Experimental -> "Launcher Monitors" unity setting + to "Primary Desktop" + +Outcome: + * Only the primary monitor should show a launcher. Changing the primary monitor + from gnome-control-center -> Monitor should update the launcher position. + + +Test Multiple Launchers with Windows in Multiple Monitors +--------------------------------------------------------- +This test shows how the launchers should draw their icons when there are +application windows in multiple monitors. + +Setup: + * Run CCSM and ensure that the unity option in "Experimental" -> + "Launcher Monitors" is set to "All Desktops" + +Actions: + * Open 2 Gedit windows on monitor 1, workspace 1. + * Open 1 Gedit window on monitor 2, workspace 1. + * Focus one of the two gedit windows on monitor 1. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * Two pips on the left of the icon. + * A filled-in arrow on the right of the icon. + * Gedit launcher icon on monitor 2 must have: + * One empty arrow on the left of the icon. + * Nothing on the right of the icon. + + +Test Multiple Launchers with Windows in Multiple Monitors and Workspaces +------------------------------------------------------------------------ +This test shows how the launchers should draw their icons when there are +application windows in multiple monitors spreaded in multiple workspaces. + +Setup: + * Run CCSM and ensure that the unity option in "Experimental" -> + "Launcher Monitors" is set to "All Desktops" + +Actions: + * Open 1 Gedit window on monitor 1, workspace 1. + * Open 2 Gedit windows on monitor 2, workspace 1. + * Open 2 Gedit windows on monitor 1, workspace 2. + * Open 1 Gedit window on monitor 2, workspace 3. + * Move to workspace 1. + * Focus the gedit window on monitor 1. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * A filled-in arrow on the left of the icon. + * A filled-in arrow on the right of the icon. + * Gedit launcher icon on monitor 2 must have: + * Two pips on the left of the icon. + * Nothing on the right of the icon. + +Actions: + * Move to workspace 2. + * Focus one of the two gedit windows on monitor 1. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * Two pips on the left of the icon. + * A filled-in arrow on the right of the icon. + * Gedit launcher icon on monitor 2 must have: + * An empty arrow on the left of the icon. + * Nothing on the right of the icon. + +Actions: + * Move to workspace 3. + * Focus the gedit window on monitor 2. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * An empty arrow on the left of the icon. + * Nothing on the right of the icon. + * Gedit launcher icon on monitor 2 must have: + * A filled-in arrow on the left of the icon. + * A filled-in arrow on the right of the icon. + +Actions: + * Move to workspace 4. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * An empty arrow on the left of the icon. + * Nothing on the right of the icon. + * Gedit launcher icon on monitor 2 must have: + * An empty arrow on the left of the icon. + * Nothing on the right of the icon. + +Test Single Launcher with Windows in Multiple Monitors +------------------------------------------------------ +This test shows how the launcher should draw its icons when there are +application windows in multiple monitors. + +Setup: + * Run CCSM and ensure that the unity option in "Experimental" -> + "Launcher Monitors" is set to "Primary Desktop" + +Actions: + * Open 2 Gedit windows on monitor 1, workspace 1. + * Open 1 Gedit window on monitor 2, workspace 1. + * Focus one of the two gedit windows on monitor 1. + +Expected Results: + * The launcher is placed only on primary monitor + * Gedit launcher icon must have: + * Three pips on the left of the icon. + * A filled-in arrow on the right of the icon. + + +Test Single Launcher with Windows in Multiple Monitors and Workspaces +--------------------------------------------------------------------- +This test shows how the launcher should draw its icons when there are +application windows in multiple monitors spreaded in multiple workspaces. + +Setup: + * Run CCSM and ensure that the unity option in "Experimental" -> + "Launcher Monitors" is set to "Primary Desktop" + +Actions: + * Open 1 Gedit window on monitor 1, workspace 1. + * Open 2 Gedit windows on monitor 2, workspace 1. + * Open 2 Gedit windows on monitor 1, workspace 2. + * Open 1 Gedit window on monitor 2, workspace 3. + * Move to workspace 1. + * Focus the gedit window on monitor 1. + +Expected Results: + * The launcher is shown only on primary monitor + * Gedit launcher icon must have: + * Three pips on the left of the icon. + * A filled-in arrow on the right of the icon. + +Actions: + * Move to workspace 2. + * Focus one of the two gedit windows on monitor 1. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * Two pips on the left of the icon. + * A filled-in arrow on the right of the icon. + +Actions: + * Move to workspace 3. + * Focus the gedit window on monitor 2. + +Expected Results: + * Gedit launcher icon on monitor 2 must have: + * A filled-in arrow on the left of the icon. + * A filled-in arrow on the right of the icon. + +Actions: + * Move to workspace 4. + +Expected Results: + * Gedit launcher icon on monitor 1 must have: + * An empty arrow on the left of the icon. + * Nothing on the right of the icon. + + +Panel appearance with overlays +------------------------------ +Setup: + Have a secondary monitor plugged in and working. + Have the launchers on each monitor + Make sure the launcher setting is to never hide. + +Actions: +#. Press to bring up the dash +#. Press to close the dash + +Expected Result: + The launchers on each monitor have saturated icons (normal looking, not the + desaturated look that there is while the dash is open). diff -Nru unity-5.6.0/manual-tests/Lenses.txt unity-5.8.0/manual-tests/Lenses.txt --- unity-5.6.0/manual-tests/Lenses.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/Lenses.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,15 @@ +Restarting of crashed lenses +---------------------------- +This test makes sure that if a lens crashes, searching in the dash +automatically restarts it. + +#. Open a terminal +#. Make sure there are some results in the apps lens +#. Kill the applications lens daemon in the terminal + `killall /usr/lib/unity-lens-applications/unity-applications-daemon` +#. Open the dash and search for something (for example "gedit") + +Outcome +Applications lens should automatically restart and gedit should be visible +in the results. + diff -Nru unity-5.6.0/manual-tests/lp929506.txt unity-5.8.0/manual-tests/lp929506.txt --- unity-5.6.0/manual-tests/lp929506.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/lp929506.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,31 @@ +Regression testcase for +https://bugs.launchpad.net/unity/+bug/929506 +---------------------------------------------------- +Setup: restart your computer to get a clean unity instance + +Steps to perform: +1. Login to your Unity-3D shell but don't start or do anything (e.g. don't +press the super key and/or show the dash) +2. Verify the lensees are not running using the following command: +$ ps axf|grep [u]nity-lens +Output of this command should be empty +3. invoke dash (e.g. by pressing the Super key) +4. Verify the lenses were started by using the following command: +$ ps axf|grep [u]nity-lens + + +Expected Outcome: +Step #2 should produce an empty output. +Step #4 should produce something like this: +$ ps axf|grep [u]nity-lens + 2754 ? Sl 0:00 /usr/lib/unity-lens-applications/unity-applications-daemon + 2756 ? Sl 0:00 /usr/lib/unity-lens-files/unity-files-daemon + 2758 ? Sl 0:00 /usr/lib/unity-lens-music/unity-music-daemon + 2760 ? Sl 0:00 /usr/bin/python /usr/lib/unity-lens-video/unity-lens-video + 2816 ? Sl 0:00 /usr/lib/unity-lens-music/unity-musicstore-daemon + + +Wrong Outcome: +#2 and #4 both produce non-empty result which means the lenses were not +lazy-loaded but they were running before the first dash use. + diff -Nru unity-5.6.0/manual-tests/MMOptions.txt unity-5.8.0/manual-tests/MMOptions.txt --- unity-5.6.0/manual-tests/MMOptions.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/MMOptions.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,22 @@ +Test Barrier Toggle +----------- +This test is to ensure the barrier toggle works on multiple-monitor systems + +#. Get a system with 2 monitors, ensure the left most monitor is set as primary +#. Disable the "Capture Mouse" setting in CCSM +#. Move your mouse between the left and right monitor + +Outcome + The mouse should move freely between monitors, without a launcher blocking its movement. + + +Test Number of Launchers +----------- +This test is to ensure that the number of launchers created and positioned can be properly configured + +#. Get a system with 2 monitors, ensure the left most monitor is set as primary +#. Open CCSM and changed the Number of Launchers option to "Primary Only" +#. Check for the existence of a launcher on your non-primary monitor + +Outcome + There should only be a launcher on the primary monitor. \ No newline at end of file diff -Nru unity-5.6.0/manual-tests/PanelIndicators.txt unity-5.8.0/manual-tests/PanelIndicators.txt --- unity-5.6.0/manual-tests/PanelIndicators.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/PanelIndicators.txt 2012-03-23 11:53:16.000000000 +0000 @@ -25,3 +25,24 @@ Outcome Window buttons should appear. + + +Open Indicators from Keyboard +----------------------------- +This test shows how indicators can be opened via keyboard bindings. + +#. Start a clean screen +#. Press Alt+F10 + +Outcome + The menu of the first indicator visible (looking left to right) + should pop-up on keydown (once F10 has been pressed). + Pressing Alt+F10 again or clicking in an empty area of the screen should close it. + +#. Start an application window with menus +#. Press Alt+F10 + +Outcome + The first menu of the window (looking left to right) should pop-up on keydown + (once F10 has been pressed). Pressing Alt+F10 again or clicking in an empty area + of the screenshould pop down it. diff -Nru unity-5.6.0/manual-tests/PanelService.txt unity-5.8.0/manual-tests/PanelService.txt --- unity-5.6.0/manual-tests/PanelService.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/PanelService.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,12 @@ +Panel Service doesn't crash with a11y +------------------------------------- + +#. Start with a clean screen +#. Save this python script and run it http://paste.ubuntu.com/893441/ + +Outcome: + The test should open the Software Center, move to the accessories and then + close it again, during this process the the panel service shouldn't crash. + This means that the menus and indicators must not be removed and readded + from the unity panel. + For more info see bug #937119 diff -Nru unity-5.6.0/manual-tests/Panel.txt unity-5.8.0/manual-tests/Panel.txt --- unity-5.6.0/manual-tests/Panel.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/Panel.txt 2012-03-23 11:53:16.000000000 +0000 @@ -60,3 +60,17 @@ 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. + + +Panel appearance with overlays +------------------------------ +Actions: +#. Press to bring up the dash + +Expected Result: + The panel should be translucent matching the dash background + +#. Press to bring up the hud without closing the dash + +Expected Result: + The panel should stay translucent diff -Nru unity-5.6.0/manual-tests/SuperTab.txt unity-5.8.0/manual-tests/SuperTab.txt --- unity-5.6.0/manual-tests/SuperTab.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/manual-tests/SuperTab.txt 2012-03-23 11:53:16.000000000 +0000 @@ -22,29 +22,6 @@ neeeded. -Super Tab switcher interaction with Shortcut Hint -------------------------------------------------- -This test shows the interaction between the shortcut hint overlay and the -Super+Tab switcher. - -#. Start with a clean screen -#. Press Super to make the shortcuts-overlay to show -#. Then press Tab to initiate the Super+Tab launcher switcher - -Outcome: - The Super+Tab switcher is initialized, and the shortcut hint overlay is still - showing. Pressing also Shift to reverse the switcher direction doesn't hide - the overlay, that will be hidden once Super is released. - -#. Start with a clean screen -#. Press Super+Tab quickly to make the launcher switcher to initialize without - making the shortcut overlay to show. - -Outcome: - Super+Tab switcher is initialized and the shortcut hint overlay is not shown - even keeping only super pressed until releasing it and pressing it again. - - Escaping from Super Tab switcher -------------------------------- This test shows how to escape from the Super+Tab switcher. diff -Nru unity-5.6.0/manual-tests/Tapping.txt unity-5.8.0/manual-tests/Tapping.txt --- unity-5.6.0/manual-tests/Tapping.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/Tapping.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,20 @@ +Super Tap Timing on Slow Systems +-------------------------------- +This test verifies that tap duration thresholding (unique to Super and Alt) +works on slow systems where previously it did not work reliably (LP: #953089). +The problems with Super tap timing have only been observed on slow and/or +heavily loaded systems, such as Atom-based netbooks. + +#. Start with a clean login. +#. Load the CPU(s) by running one or more instances of this command in + a terminal window(s): while true; do true; done +#. Tap the Super key. Verify the Dash is shown. +#. Tap the Super key again. Verify the Dash is hidden. +#. Switch to a clear workspace (e.g. Ctrl+Alt+Right). +#. Tap the Super key again. Verify the Dash is shown again. +#. Tap the Super key again. Verify the Dash is hidden again. + +Outcome: + The Dash should appear and disappear in response to each tap on the Super + key. Note that a tap is anything faster than 1/4 of a second. Any press + that lasts longer than that is not considered a tap. diff -Nru unity-5.6.0/manual-tests/TEST_TEMPLATE.txt unity-5.8.0/manual-tests/TEST_TEMPLATE.txt --- unity-5.6.0/manual-tests/TEST_TEMPLATE.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/TEST_TEMPLATE.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,20 @@ +#Please use this template for adding new manual-tests to ensure a consistency. +#Text to be changed is enclosed in <<>> +# +#Please also note that Tests should test ONE THING ONLY. If you want to test +#more than one thing, write multiple tests. That helps us to automate them as +#well as execute them manually. +# +#If you're testing purely visual changes, please make sure you link to a +#reference image or add it to the bzr repository. + +<> +---------------------------------------------------- +Setup: +<> + +Actions: +<> + +Expected Result: +<> diff -Nru unity-5.6.0/manual-tests/Wakeups.txt unity-5.8.0/manual-tests/Wakeups.txt --- unity-5.6.0/manual-tests/Wakeups.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/manual-tests/Wakeups.txt 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,23 @@ +Launcher autoscroll wake-ups +---------------------------- +This test makes sure that the timer controlling autoscroll animations does +not keep running (at 50Hz) when it's not required to animate anything. This +is LP: #917210. + +#. Ensure the screen is idle, with very little changing. +#. Open a terminal and start a tool that can measure process wakeups per + second. You can choose one of: + - gnome-power-statistics (click on Processor) + - powertop + - eventstat +#. Hover the mouse pointer over the top end of the Launcher. That's just above + the Ubuntu icon. +#. Hover the mouse pointer over the bottom end of the Launcher. That's over + the bottom of the trash icon. +#. Move the mouse pointer back to the centre of the screen and leave it there. +#. Wait 30-60 seconds, leaving the screen idle before verifying the Outcome. + +Outcome + The number of wakeups per second (events per second) reported for the + compiz process should be much lower than 50. + Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/launcher_icon_glow_200.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/launcher_icon_glow_200.png differ diff -Nru unity-5.6.0/plugins/unityshell/resources/search_circle.svg unity-5.8.0/plugins/unityshell/resources/search_circle.svg --- unity-5.6.0/plugins/unityshell/resources/search_circle.svg 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/resources/search_circle.svg 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/search_close.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/search_close.png differ diff -Nru unity-5.6.0/plugins/unityshell/resources/search_close.svg unity-5.8.0/plugins/unityshell/resources/search_close.svg --- unity-5.6.0/plugins/unityshell/resources/search_close.svg 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/resources/search_close.svg 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/search_magnify.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/search_magnify.png differ Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/search_spin.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/search_spin.png differ diff -Nru unity-5.6.0/plugins/unityshell/resources/search_spin.svg unity-5.8.0/plugins/unityshell/resources/search_spin.svg --- unity-5.6.0/plugins/unityshell/resources/search_spin.svg 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/resources/search_spin.svg 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/switcher_corner.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/switcher_corner.png differ Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/switcher_left.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/switcher_left.png differ Binary files /tmp/lADn1yVzMD/unity-5.6.0/plugins/unityshell/resources/switcher_top.png and /tmp/RE0MfnaXRV/unity-5.8.0/plugins/unityshell/resources/switcher_top.png differ diff -Nru unity-5.6.0/plugins/unityshell/src/AbstractLauncherIcon.h unity-5.8.0/plugins/unityshell/src/AbstractLauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/AbstractLauncherIcon.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/AbstractLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -147,10 +147,14 @@ virtual std::vector WindowsForMonitor(int monitor) = 0; - virtual std::string NameForWindow (Window window) = 0; + virtual std::vector WindowsOnViewport() = 0; + + virtual std::string NameForWindow(Window window) = 0; virtual const bool WindowVisibleOnMonitor(int monitor) = 0; + virtual const bool WindowVisibleOnViewport() = 0; + virtual bool IsSpacer() = 0; virtual float PresentUrgency() = 0; diff -Nru unity-5.6.0/plugins/unityshell/src/AbstractPlacesGroup.cpp unity-5.8.0/plugins/unityshell/src/AbstractPlacesGroup.cpp --- unity-5.6.0/plugins/unityshell/src/AbstractPlacesGroup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/AbstractPlacesGroup.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Andrea Azzarone + */ + + +#include "AbstractPlacesGroup.h" + +namespace unity +{ +namespace dash +{ + +NUX_IMPLEMENT_OBJECT_TYPE(AbstractPlacesGroup); + +AbstractPlacesGroup::AbstractPlacesGroup() + : nux::View(NUX_TRACKER_LOCATION) + , draw_separator(false) +{ +} + +void AbstractPlacesGroup::Draw(nux::GraphicsEngine&, bool) +{ +} + +void AbstractPlacesGroup::DrawContent(nux::GraphicsEngine&, bool) +{ +} + +} // namespace dash +} // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/src/AbstractPlacesGroup.h unity-5.8.0/plugins/unityshell/src/AbstractPlacesGroup.h --- unity-5.6.0/plugins/unityshell/src/AbstractPlacesGroup.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/AbstractPlacesGroup.h 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Andrea Azzarone + */ + + +#ifndef UNITYSHELL_ABSTRACTPLACESGROUP_H +#define UNITYSHELL_ABSTRACTPLACESGROUP_H + +#include +#include +#include + +namespace unity +{ +namespace dash +{ + +class AbstractPlacesGroup : public nux::View +{ + NUX_DECLARE_OBJECT_TYPE(AbstractPlacesGroup, nux::View); +public: + AbstractPlacesGroup(); + + // Properties + nux::Property draw_separator; + +protected: + void Draw(nux::GraphicsEngine&, bool); + void DrawContent(nux::GraphicsEngine&, bool); + +}; + +} +} + +#endif + diff -Nru unity-5.6.0/plugins/unityshell/src/AbstractShortcutHint.h unity-5.8.0/plugins/unityshell/src/AbstractShortcutHint.h --- unity-5.6.0/plugins/unityshell/src/AbstractShortcutHint.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/AbstractShortcutHint.h 2012-03-23 11:53:16.000000000 +0000 @@ -33,6 +33,7 @@ enum OptionType { COMPIZ_KEY_OPTION = 0, + COMPIZ_METAKEY_OPTION, COMPIZ_MOUSE_OPTION, HARDCODED_OPTION /* GSETTINGS_OPTION, diff -Nru unity-5.6.0/plugins/unityshell/src/BamfLauncherIcon.cpp unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.cpp --- unity-5.6.0/plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -287,23 +287,40 @@ ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, nullptr); } -std::vector BamfLauncherIcon::Windows() +std::vector BamfLauncherIcon::GetWindows(WindowFilterMask filter, int monitor) { std::vector results; GList* children, *l; WindowManager *wm = WindowManager::Default(); + monitor = (filter & WindowFilter::ON_ALL_MONITORS) ? -1 : monitor; + bool mapped = (filter & WindowFilter::MAPPED); + bool user_visible = (filter & WindowFilter::USER_VISIBLE); + bool current_desktop = (filter & WindowFilter::ON_CURRENT_DESKTOP); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { if (!BAMF_IS_WINDOW(l->data)) continue; + + auto window = static_cast(l->data); + auto view = static_cast(l->data); - Window xid = bamf_window_get_xid(static_cast(l->data)); - - if (wm->IsWindowMapped(xid)) + if ((monitor >= 0 && bamf_window_get_monitor(window) == monitor) || monitor < 0) { - results.push_back(xid); + if ((user_visible && bamf_view_user_visible(view)) || !user_visible) + { + guint32 xid = bamf_window_get_xid(window); + + if ((mapped && wm->IsWindowMapped(xid)) || !mapped) + { + if ((current_desktop && wm->IsWindowOnCurrentDesktop(xid)) || !current_desktop) + { + results.push_back(xid); + } + } + } } } @@ -311,31 +328,30 @@ return results; } -std::vector BamfLauncherIcon::WindowsForMonitor(int monitor) +std::vector BamfLauncherIcon::Windows() { - std::vector results; - GList* children, *l; - WindowManager *wm = WindowManager::Default(); + return GetWindows(WindowFilter::MAPPED|WindowFilter::ON_ALL_MONITORS); +} - children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); - for (l = children; l; l = l->next) - { - if (!BAMF_IS_WINDOW(l->data)) - continue; +std::vector BamfLauncherIcon::WindowsOnViewport() +{ + WindowFilterMask filter; + filter |= WindowFilter::MAPPED; + filter |= WindowFilter::USER_VISIBLE; + filter |= WindowFilter::ON_CURRENT_DESKTOP; + filter |= WindowFilter::ON_ALL_MONITORS; - auto window = static_cast(l->data); - if (bamf_window_get_monitor(window) == monitor) - { - guint32 xid = bamf_window_get_xid(window); - bool user_visible = bamf_view_user_visible(reinterpret_cast(window)); + return GetWindows(filter); +} - if (user_visible && wm->IsWindowMapped(xid) && wm->IsWindowOnCurrentDesktop(xid)) - results.push_back(xid); - } - } +std::vector BamfLauncherIcon::WindowsForMonitor(int monitor) +{ + WindowFilterMask filter; + filter |= WindowFilter::MAPPED; + filter |= WindowFilter::USER_VISIBLE; + filter |= WindowFilter::ON_CURRENT_DESKTOP; - g_list_free(children); - return results; + return GetWindows(filter, monitor); } std::string BamfLauncherIcon::NameForWindow(Window window) @@ -684,8 +700,8 @@ int index = 0; while (nicks[index]) { - - // Build a dbusmenu item for each nick that is the desktop + + // Build a dbusmenu item for each nick that is the desktop // file that is built from it's name and includes a callback // to the desktop shortcuts object to execute the nick glib::String name(indicator_desktop_shortcuts_nick_get_name(_desktop_shortcuts, @@ -781,7 +797,7 @@ bamf_view_set_sticky(BAMF_VIEW(_bamf_app.RawPtr()), true); if (save && !desktop_file.empty()) - FavoriteStore::GetDefault().AddFavorite(desktop_file.c_str(), -1); + FavoriteStore::GetDefault().AddFavorite(desktop_file, -1); } void BamfLauncherIcon::UnStick() @@ -797,7 +813,7 @@ Remove(); if (!desktop_file.empty()) - FavoriteStore::GetDefault().RemoveFavorite(desktop_file.c_str()); + FavoriteStore::GetDefault().RemoveFavorite(desktop_file); } void BamfLauncherIcon::ToggleSticky() diff -Nru unity-5.6.0/plugins/unityshell/src/BamfLauncherIcon.h unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/BamfLauncherIcon.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -61,6 +61,7 @@ virtual unsigned long long SwitcherPriority(); std::vector Windows(); + std::vector WindowsOnViewport(); std::vector WindowsForMonitor(int monitor); std::string NameForWindow(Window window); @@ -87,6 +88,15 @@ std::string GetName() const; private: + typedef unsigned long int WindowFilterMask; + enum WindowFilter + { + MAPPED = (1 << 0), + USER_VISIBLE = (1 << 1), + ON_CURRENT_DESKTOP = (1 << 2), + ON_ALL_MONITORS = (1 << 3), + }; + void EnsureWindowState(); void EnsureMenuItemsReady(); void UpdateDesktopFile(); @@ -103,6 +113,7 @@ bool OwnsWindow(Window w) const; + std::vector GetWindows(WindowFilterMask filter, int monitor = -1); const std::set& GetSupportedTypes(); diff -Nru unity-5.6.0/plugins/unityshell/src/BFBLauncherIcon.cpp unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.cpp --- unity-5.6.0/plugins/unityshell/src/BFBLauncherIcon.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -32,11 +32,12 @@ UBusManager BFBLauncherIcon::ubus_manager_; -BFBLauncherIcon::BFBLauncherIcon() +BFBLauncherIcon::BFBLauncherIcon(LauncherHideMode hide_mode) : SimpleLauncherIcon() , reader_(dash::LensDirectoryReader::GetDefault()) + , launcher_hide_mode_(hide_mode) { - tooltip_text = _("Dash home"); + tooltip_text = _("Dash Home"); icon_name = PKGDATADIR"/launcher_bfb.png"; SetQuirk(QUIRK_VISIBLE, true); SetQuirk(QUIRK_RUNNING, false); @@ -45,6 +46,31 @@ background_color_ = nux::color::White; mouse_enter.connect([&](int m) { ubus_manager_.SendMessage(UBUS_DASH_ABOUT_TO_SHOW, NULL); }); + ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::bind(sigc::mem_fun(this, &BFBLauncherIcon::OnOverlayShown), true)); + ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::bind(sigc::mem_fun(this, &BFBLauncherIcon::OnOverlayShown), false)); +} + +void BFBLauncherIcon::SetHideMode(LauncherHideMode hide_mode) +{ + launcher_hide_mode_ = hide_mode; +} + +void BFBLauncherIcon::OnOverlayShown(GVariant *data, bool visible) +{ + unity::glib::String overlay_identity; + gboolean can_maximise = FALSE; + gint32 overlay_monitor = 0; + g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, + &overlay_identity, &can_maximise, &overlay_monitor); + + + // If the hud is open, we hide the BFB iff we have a locked launcher + if (!g_strcmp0(overlay_identity, "hud") && + launcher_hide_mode_ == LAUNCHER_HIDE_NEVER) + { + SetQuirk(QUIRK_VISIBLE, !visible); + EmitNeedsRedraw(); + } } nux::Color BFBLauncherIcon::BackgroundColor() diff -Nru unity-5.6.0/plugins/unityshell/src/BFBLauncherIcon.h unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/BFBLauncherIcon.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -24,6 +24,7 @@ #include +#include "LauncherOptions.h" #include "UBusWrapper.h" namespace unity @@ -35,23 +36,26 @@ { public: - BFBLauncherIcon(); + BFBLauncherIcon(LauncherHideMode hide_mode); virtual nux::Color BackgroundColor(); virtual nux::Color GlowColor(); void ActivateLauncherIcon(ActionArg arg); + void SetHideMode(LauncherHideMode hide_mode); protected: std::list GetMenus(); std::string GetName() const; private: + void OnOverlayShown(GVariant *data, bool visible); static void OnMenuitemActivated(DbusmenuMenuitem* item, int time, gchar* lens); static unity::UBusManager ubus_manager_; nux::Color background_color_; dash::LensDirectoryReader::Ptr reader_; + LauncherHideMode launcher_hide_mode_; }; } diff -Nru unity-5.6.0/plugins/unityshell/src/BGHash.cpp unity-5.8.0/plugins/unityshell/src/BGHash.cpp --- unity-5.6.0/plugins/unityshell/src/BGHash.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/BGHash.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -35,8 +35,6 @@ int level_of_recursion; const int MAX_LEVEL_OF_RECURSION = 16; const int MIN_LEVEL_OF_RECURSION = 2; - std::string AVG_BG_COLOR = "average-bg-color"; - std::string UNITY_SCHEMA = "com.canonical.Unity"; } namespace unity { @@ -343,23 +341,6 @@ _hires_time_start = g_get_monotonic_time(); _hires_time_end = 500 * 1000; // 500 milliseconds _transition_handler = g_timeout_add (1000/60, (GSourceFunc)BGHash::OnTransitionCallback, this); - - // export to gsettings - GSettings* settings = NULL; - GdkColor color = {0, - (guint16) (_new_color.red * 65535.0 * 0.7f), - (guint16) (_new_color.green * 65535.0 * 0.7f), - (guint16) (_new_color.blue * 65535.0 * 0.7f)}; - - settings = g_settings_new (UNITY_SCHEMA.c_str()); - if (settings) - { - unity::glib::String color_string(gdk_color_to_string(&color)); - LOG_DEBUG(logger) << "Setting gsettings key to: " << color_string; - g_settings_set_string(settings, AVG_BG_COLOR.c_str(), color_string); - g_object_unref (settings); - } - } gboolean BGHash::OnTransitionCallback(BGHash *self) @@ -395,10 +376,10 @@ ubus_server_send_message(ubus_server_get_default(), UBUS_BACKGROUND_COLOR_CHANGED, g_variant_new ("(dddd)", - _current_color.red * 0.7f, - _current_color.green * 0.7f, - _current_color.blue * 0.7f, - 0.5) + _current_color.red, + _current_color.green, + _current_color.blue, + _current_color.alpha) ); } @@ -712,6 +693,7 @@ // grayscale image LOG_DEBUG (logger) << "got a grayscale image"; chosen_color = nux::Color (46 , 52 , 54 ); + chosen_color.alpha = 0.72f; } else { @@ -731,13 +713,15 @@ nux::color::HueSaturationValue hsv_color (chosen_color); - hsv_color.saturation = std::min(base_hsv.saturation, hsv_color.saturation) * 1.36f; - hsv_color.value = std::min(std::min(base_hsv.value, hsv_color.value), 0.2f); + hsv_color.saturation = std::min(base_hsv.saturation, hsv_color.saturation) * 1.3f; + hsv_color.value = std::min(std::min(base_hsv.value, hsv_color.value), 0.26f); chosen_color = nux::Color (nux::color::RedGreenBlue(hsv_color)); + + // Reduce alpha on really dark average colors + chosen_color.alpha = 0.72f - 2 * (0.26f - hsv_color.value); } // apply design to the colour - chosen_color.alpha = 0.5f; LOG_DEBUG(logger) << "eventually chose " << chosen_color.red << ", " diff -Nru unity-5.6.0/plugins/unityshell/src/DashController.cpp unity-5.8.0/plugins/unityshell/src/DashController.cpp --- unity-5.6.0/plugins/unityshell/src/DashController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,6 +39,7 @@ Controller::Controller() : launcher_width(64) + , use_primary(false) , window_(0) , visible_(false) , need_show_(false) @@ -160,11 +161,22 @@ geo = self->GetIdealWindowGeometry(); } +int Controller::GetIdealMonitor() +{ + UScreen *uscreen = UScreen::GetDefault(); + int primary_monitor; + if (use_primary) + primary_monitor = uscreen->GetPrimaryMonitor(); + else + primary_monitor = uscreen->GetMonitorWithMouse(); + + return primary_monitor; +} + nux::Geometry Controller::GetIdealWindowGeometry() { UScreen *uscreen = UScreen::GetDefault(); - int primary_monitor = uscreen->GetMonitorWithMouse(); - auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); + auto monitor_geo = uscreen->GetMonitorGeometry(GetIdealMonitor()); // We want to cover as much of the screen as possible to grab any mouse events outside // of our window @@ -260,7 +272,7 @@ StartShowHideTimeline(); - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, UScreen::GetDefault()->GetMonitorWithMouse()); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor()); ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info); } @@ -286,7 +298,7 @@ StartShowHideTimeline(); - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, g_variant_new_int32(UScreen::GetDefault()->GetMonitorWithMouse())); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor()); ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info); } diff -Nru unity-5.6.0/plugins/unityshell/src/DashController.h unity-5.8.0/plugins/unityshell/src/DashController.h --- unity-5.6.0/plugins/unityshell/src/DashController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashController.h 2012-03-23 11:53:16.000000000 +0000 @@ -52,6 +52,7 @@ std::vector GetAllShortcuts(); nux::Property launcher_width; + nux::Property use_primary; sigc::signal on_realize; @@ -67,6 +68,7 @@ void RegisterUBusInterests(); nux::Geometry GetIdealWindowGeometry(); + int GetIdealMonitor(); void Relayout(GdkScreen*screen=NULL); void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); diff -Nru unity-5.6.0/plugins/unityshell/src/DashStyle.cpp unity-5.8.0/plugins/unityshell/src/DashStyle.cpp --- unity-5.6.0/plugins/unityshell/src/DashStyle.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashStyle.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -88,12 +88,13 @@ class LazyLoadTexture { public: - LazyLoadTexture(std::string const& filename); + LazyLoadTexture(std::string const& filename, int size = -1); nux::BaseTexture* texture(); private: void LoadTexture(); private: std::string filename_; + int size_; BaseTexturePtr texture_; }; @@ -120,7 +121,7 @@ nux::Color const& color, std::string const& label, int font_size = -1, - double horizMargin = 10.0, + double horizMargin = 4.0, Alignment alignment = Alignment::CENTER); void ButtonOutlinePath(cairo_t* cr, bool align); @@ -205,6 +206,7 @@ LazyLoadTexture dash_shine_; LazyLoadTexture search_magnify_texture_; + LazyLoadTexture search_circle_texture_; LazyLoadTexture search_close_texture_; LazyLoadTexture search_spin_texture_; @@ -240,8 +242,9 @@ , dash_top_tile_("/dash_top_tile.png") , dash_shine_("/dash_sheen.png") , search_magnify_texture_("/search_magnify.png") - , search_close_texture_("/search_close.png") - , search_spin_texture_("/search_spin.png") + , search_circle_texture_("/search_circle.svg", 32) + , search_close_texture_("/search_close.svg", 32) + , search_spin_texture_("/search_spin.svg", 32) , group_unexpand_texture_("/dash_group_unexpand.png") , group_expand_texture_("/dash_group_expand.png") , star_deselected_texture_("/star_deselected.png") @@ -1530,16 +1533,16 @@ (double) (garnish) + 1.0, (double) (garnish) + 1.0, 7.0, - w - (double) (2 * garnish) - 1.0, - h - (double) (2 * garnish) - 1.0); + w - (double) (2 * garnish) - 2.0, + h - (double) (2 * garnish) - 2.0); else RoundedRect(cr, 1.0, - (double) (garnish), - (double) (garnish), + (double) (garnish) + 0.5, + (double) (garnish) + 0.5, 7.0, - w - (double) (2 * garnish), - h - (double) (2 * garnish)); + w - (double) (2 * garnish) - 1.0, + h - (double) (2 * garnish) - 1.0); if (pimpl->button_label_fill_color_[state].alpha != 0.0) @@ -1559,7 +1562,7 @@ pimpl->button_label_text_color_[state], label, font_size, - 10.0, + 11.0, // 15px = 11pt alignment); return true; @@ -1725,8 +1728,6 @@ if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE) return false; - unsigned int garnish = GetButtonGarnishSize(); - double w = cairo_image_surface_get_width(cairo_get_target(cr)); double h = cairo_image_surface_get_height(cairo_get_target(cr)); @@ -1736,12 +1737,12 @@ RoundedRect(cr, 1.0, - (double) (garnish), - (double) (garnish), + (double) 0.5, + (double) 0.5, 7.0, - w - (double) (2 * garnish), - h - (double) (2 * garnish)); - + w - 1.0, + h - 1.0); + cairo_set_source_rgba(cr, color); cairo_fill_preserve(cr); cairo_stroke(cr); @@ -1814,7 +1815,7 @@ pimpl->Text(cr, pimpl->button_label_text_color_[state], label, - 1.0); + 10); // 13px = 10pt return true; } @@ -2105,6 +2106,11 @@ return pimpl->search_magnify_texture_.texture(); } +nux::BaseTexture* Style::GetSearchCircleIcon() +{ + return pimpl->search_circle_texture_.texture(); +} + nux::BaseTexture* Style::GetSearchCloseIcon() { return pimpl->search_close_texture_.texture(); @@ -2145,12 +2151,134 @@ return pimpl->dash_shine_.texture(); } +int Style::GetVSeparatorSize() const +{ + return 1; +} + +int Style::GetHSeparatorSize() const +{ + return 1; + +} + +int Style::GetFilterBarWidth() const +{ + return 300; +} + + +int Style::GetFilterBarLeftPadding() const +{ + return 5; +} + +int Style::GetFilterBarRightPadding() const +{ + return 5; +} + +int Style::GetDashViewTopPadding() const +{ + return 10; +} + +int Style::GetSearchBarLeftPadding() const +{ + return 10; +} + +int Style::GetSearchBarRightPadding() const +{ + return 10; +} + +int Style::GetSearchBarHeight() const +{ + return 42; +} + +int Style::GetFilterResultsHighlightRightPadding() const +{ + return 5; +} + +int Style::GetFilterResultsHighlightLeftPadding() const +{ + return 5; +} + +int Style::GetFilterBarTopPadding() const +{ + return 10; +} + +int Style::GetFilterHighlightPadding() const +{ + return 2; +} + +int Style::GetSpaceBetweenFilterWidgets() const +{ + return 12; +} + +int Style::GetAllButtonHeight() const +{ + return 30; +} + +int Style::GetFilterButtonHeight() const +{ + return 30; +} + +int Style::GetSpaceBetweenLensAndFilters() const +{ + return 9; +} + +int Style::GetFilterViewRightPadding() const +{ + return 10; +} + +int Style::GetScrollbarWidth() const +{ + return 3; +} + +int Style::GetCategoryHighlightHeight() const +{ + return 24; +} + +int Style::GetPlacesGroupTopSpace() const +{ + return 15; +} + +int Style::GetCategoryHeaderLeftPadding() const +{ + return 20; +} + +int Style::GetCategorySeparatorLeftPadding() const +{ + return 15; +} + +int Style::GetCategorySeparatorRightPadding() const +{ + return 15; +} namespace { -LazyLoadTexture::LazyLoadTexture(std::string const& filename) +LazyLoadTexture::LazyLoadTexture(std::string const& filename, int size) : filename_(filename) + , size_(size) { } @@ -2167,7 +2295,7 @@ glib::Object pixbuf; glib::Error error; - pixbuf = ::gdk_pixbuf_new_from_file(full_path.c_str(), &error); + pixbuf = ::gdk_pixbuf_new_from_file_at_size(full_path.c_str(), size_, size_, &error); if (error) { LOG_WARN(logger) << "Unable to texture " << full_path << ": " << error; diff -Nru unity-5.6.0/plugins/unityshell/src/DashStyle.h unity-5.8.0/plugins/unityshell/src/DashStyle.h --- unity-5.6.0/plugins/unityshell/src/DashStyle.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashStyle.h 2012-03-23 11:53:16.000000000 +0000 @@ -178,6 +178,7 @@ nux::BaseTexture* GetDashShine(); nux::BaseTexture* GetSearchMagnifyIcon(); + nux::BaseTexture* GetSearchCircleIcon(); nux::BaseTexture* GetSearchCloseIcon(); nux::BaseTexture* GetSearchSpinIcon(); @@ -188,6 +189,47 @@ nux::BaseTexture* GetStarSelectedIcon(); nux::BaseTexture* GetStarHighlightIcon(); + // Returns the width of the separator between the dash and the launcher. + int GetVSeparatorSize() const; + + // Returns the height of the separator between the dash and the top panel. + int GetHSeparatorSize() const; + + // Practically it is the space between the top border of the dash and the searchbar. + int GetDashViewTopPadding() const; + + // Search bar + int GetSearchBarLeftPadding() const; + int GetSearchBarRightPadding() const; + int GetSearchBarHeight() const; + int GetFilterResultsHighlightRightPadding() const; + int GetFilterResultsHighlightLeftPadding() const; + + // Filter bar + int GetFilterBarTopPadding() const; + int GetFilterHighlightPadding() const; + int GetSpaceBetweenFilterWidgets() const; + int GetAllButtonHeight() const; + int GetFilterBarLeftPadding() const; + int GetFilterBarRightPadding() const; + int GetFilterBarWidth() const; + int GetFilterButtonHeight() const; + int GetFilterViewRightPadding() const; + + int GetSpaceBetweenLensAndFilters() const; + + // Scrollbars + int GetScrollbarWidth() const; + + // Places Group + int GetCategoryHighlightHeight() const; + int GetPlacesGroupTopSpace() const; + int GetCategoryHeaderLeftPadding() const; + int GetCategorySeparatorLeftPadding() const; + int GetCategorySeparatorRightPadding() const; + + const static int SEARCH_BAR_EXTRA_PADDING = 1; + sigc::signal changed; private: diff -Nru unity-5.6.0/plugins/unityshell/src/DashView.cpp unity-5.8.0/plugins/unityshell/src/DashView.cpp --- unity-5.6.0/plugins/unityshell/src/DashView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -82,13 +82,14 @@ , searching_timeout_id_(0) , search_in_progress_(false) , activate_on_finish_(false) + , hide_message_delay_id_(0) , visible_(false) { renderer_.SetOwner(this); - renderer_.need_redraw.connect([this] () { + renderer_.need_redraw.connect([this] () { QueueDraw(); }); - + SetupViews(); SetupUBusConnections(); @@ -99,6 +100,7 @@ Relayout(); home_lens_->AddLenses(lenses_); + home_lens_->search_finished.connect(sigc::mem_fun(this, &DashView::OnGlobalSearchFinished)); lens_bar_->Activate("home.lens"); } @@ -106,6 +108,8 @@ { if (searching_timeout_id_) g_source_remove (searching_timeout_id_); + if (hide_message_delay_id_) + g_source_remove(hide_message_delay_id_); } void DashView::SetMonitorOffset(int x, int y) @@ -135,6 +139,12 @@ LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW << " on '" << home_lens_->id() << "'"; } + else if (active_lens_view_) + { + // careful here, the lens_view's view_type doesn't get reset when the dash + // hides, but lens' view_type does, so we need to update the lens directly + active_lens_view_->lens()->view_type = ViewType::LENS_VIEW; + } renderer_.AboutToShow(); } @@ -158,21 +168,30 @@ void DashView::SetupViews() { + dash::Style& style = dash::Style::Instance(); + layout_ = new nux::VLayout(); + layout_->SetLeftAndRightPadding(style.GetVSeparatorSize(), 0); + layout_->SetTopAndBottomPadding(style.GetHSeparatorSize(), 0); SetLayout(layout_); content_layout_ = new DashLayout(NUX_TRACKER_LOCATION); - content_layout_->SetHorizontalExternalMargin(0); - content_layout_->SetVerticalExternalMargin(0); - + content_layout_->SetTopAndBottomPadding(style.GetDashViewTopPadding() - style.SEARCH_BAR_EXTRA_PADDING, 0); layout_->AddLayout(content_layout_, 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); + + search_bar_layout_ = new nux::HLayout(); + search_bar_layout_->SetLeftAndRightPadding(style.GetSearchBarLeftPadding() - style.SEARCH_BAR_EXTRA_PADDING, style.GetSearchBarLeftPadding() - style.GetFilterResultsHighlightRightPadding() - style.SEARCH_BAR_EXTRA_PADDING); + content_layout_->AddLayout(search_bar_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + search_bar_ = new SearchBar(); AddChild(search_bar_); + search_bar_->SetMinimumHeight(style.GetSearchBarHeight() + style.SEARCH_BAR_EXTRA_PADDING * 2); + search_bar_->SetMaximumHeight(style.GetSearchBarHeight() + style.SEARCH_BAR_EXTRA_PADDING * 2); search_bar_->activated.connect(sigc::mem_fun(this, &DashView::OnEntryActivated)); search_bar_->search_changed.connect(sigc::mem_fun(this, &DashView::OnSearchChanged)); search_bar_->live_search_reached.connect(sigc::mem_fun(this, &DashView::OnLiveSearchReached)); search_bar_->showing_filters.changed.connect([&] (bool showing) { if (active_lens_view_) active_lens_view_->filters_expanded = showing; QueueDraw(); }); - content_layout_->AddView(search_bar_, 0, nux::MINOR_POSITION_LEFT); + search_bar_layout_->AddView(search_bar_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); content_layout_->SetSpecialArea(search_bar_->show_filters()); lenses_layout_ = new nux::VLayout(); @@ -204,7 +223,7 @@ void DashView::Relayout() { - nux::Geometry geo = GetGeometry(); + nux::Geometry const& geo = GetGeometry(); content_geo_ = GetBestFitGeometry(geo); if (Settings::Instance().GetFormFactor() == FormFactor::NETBOOK) @@ -213,16 +232,16 @@ content_geo_ = geo; } + dash::Style& style = dash::Style::Instance(); + // kinda hacky, but it makes sure the content isn't so big that it throws // the bottom of the dash off the screen // not hugely happy with this, so FIXME - lenses_layout_->SetMaximumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height); - lenses_layout_->SetMinimumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height); + lenses_layout_->SetMaximumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()); + lenses_layout_->SetMinimumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()); layout_->SetMinMaxSize(content_geo_.width, content_geo_.height); - dash::Style& style = dash::Style::Instance(); - // Minus the padding that gets added to the left float tile_width = style.GetTileWidth(); style.SetDefaultNColumns(floorf((content_geo_.width - 32) / tile_width)); @@ -254,9 +273,8 @@ height = search_bar_->GetGeometry().height; height += tile_height * 3; - height += (24 + 15) * 3; // adding three group headers - height += lens_bar_->GetGeometry().height; - height += 6; // account for padding in PlacesGroup + height += 46 * 3; // adding three group headers + //height += lens_bar_->GetGeometry().height; if (for_geo.width > 800 && for_geo.height > 550) { @@ -275,7 +293,7 @@ void DashView::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw) { renderer_.DrawInner(gfx_context, content_geo_, GetAbsoluteGeometry(), GetGeometry()); - + if (IsFullRedraw()) { nux::GetPainter().PushBackgroundStack(); @@ -286,7 +304,7 @@ { layout_->ProcessDraw(gfx_context, force_draw); } - + renderer_.DrawInnerCleanup(gfx_context, content_geo_, GetAbsoluteGeometry(), GetGeometry()); } @@ -374,6 +392,16 @@ return FALSE; } +gboolean DashView::HideResultMessageCb(gpointer data) +{ + DashView *self = static_cast(data); + + self->active_lens_view_->HideResultsMessage(); + self->hide_message_delay_id_ = 0; + + return FALSE; +} + void DashView::OnSearchChanged(std::string const& search_string) { LOG_DEBUG(logger) << "Search changed: " << search_string; @@ -385,9 +413,21 @@ if (searching_timeout_id_) { g_source_remove (searching_timeout_id_); + searching_timeout_id_ = 0; } + // 250ms for the Search method call, rest for the actual search searching_timeout_id_ = g_timeout_add (500, &DashView::ResetSearchStateCb, this); + + + if (hide_message_delay_id_) + { + g_source_remove(hide_message_delay_id_); + hide_message_delay_id_ = 0; + } + + // 150ms to hide the no reults message if its take a while to return results + hide_message_delay_id_ = g_timeout_add (150, &DashView::HideResultMessageCb, this); } } @@ -414,7 +454,7 @@ lens->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply)); lens->search_finished.connect(sigc::mem_fun(this, &DashView::OnSearchFinished)); - lens->global_search_finished.connect(sigc::mem_fun(this, &DashView::OnGlobalSearchFinished)); + // global search done is handled by the home lens, no need to connect to it } void DashView::OnLensBarActivated(std::string const& id) @@ -426,6 +466,7 @@ } LensView* view = active_lens_view_ = lens_views_[id]; + view->JumpToTop(); for (auto it: lens_views_) { @@ -450,22 +491,30 @@ search_bar_->can_refine_search = view->can_refine_search(); + if (hide_message_delay_id_) + { + g_source_remove(hide_message_delay_id_); + hide_message_delay_id_ = 0; + } + view->QueueDraw(); QueueDraw(); } void DashView::OnSearchFinished(Lens::Hints const& hints) { - Lens::Hints::const_iterator it; - it = hints.find("no-results-hint"); - - if (it != hints.end()) + if (hide_message_delay_id_) { - LOG_DEBUG(logger) << "We have no-results-hint: " << g_variant_get_string (it->second, NULL); + g_source_remove(hide_message_delay_id_); + hide_message_delay_id_ = 0; } - std::string search_string = search_bar_->search_string; - if (active_lens_view_ && active_lens_view_->search_string == search_string) + if (active_lens_view_ == NULL) return; + + active_lens_view_->CheckNoResults(hints); + std::string const& search_string = search_bar_->search_string; + + if (active_lens_view_->search_string == search_string) { search_bar_->SearchFinished(); search_in_progress_ = false; @@ -659,14 +708,14 @@ { auto show_filters = search_bar_->show_filters(); auto fscroll_view = active_lens_view_->fscroll_view(); - + if (show_filters && show_filters->HasKeyFocus()) { if (fscroll_view->IsVisible() && fscroll_view) return fscroll_view->KeyNavIteration(direction); else return active_lens_view_->KeyNavIteration(direction); - } + } } return this; } @@ -713,12 +762,20 @@ // Not sure if Enter should be a navigation key direction = KEY_NAV_ENTER; break; + case NUX_VK_F4: + // Maybe we should not do it here, but it needs to be checked where + // we are able to know if alt is pressed. + if (special_keys_state & NUX_STATE_ALT) + { + ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); + } + break; default: direction = KEY_NAV_NONE; break; } - // We should not do it here, but I really don't want to make DashView + // We should not do it here, but I really don't want to make DashView // focusable and I'm not able to know if ctrl is pressed in // DashView::KeyNavIteration. nux::InputArea* focus_area = nux::GetWindowCompositor().GetKeyFocusArea(); @@ -762,10 +819,10 @@ for (auto tab = rbegin; tab != rend; ++tab) { const auto& tab_ptr = *tab; - + if (use_the_prev) return tab_ptr; - + if (focus_area) use_the_prev = focus_area->IsChildOf(tab_ptr); } @@ -787,7 +844,7 @@ { if (use_the_next) return tab; - + if (focus_area) use_the_next = focus_area->IsChildOf(tab); } diff -Nru unity-5.6.0/plugins/unityshell/src/DashView.h unity-5.8.0/plugins/unityshell/src/DashView.h --- unity-5.6.0/plugins/unityshell/src/DashView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DashView.h 2012-03-23 11:53:16.000000000 +0000 @@ -108,6 +108,7 @@ nux::Area* KeyNavIteration(nux::KeyNavDirection direction); static gboolean ResetSearchStateCb(gpointer data); + static gboolean HideResultMessageCb(gpointer data); private: UBusManager ubus_manager_; @@ -119,6 +120,7 @@ // View related nux::VLayout* layout_; DashLayout* content_layout_; + nux::HLayout* search_bar_layout_; SearchBar* search_bar_; nux::VLayout* lenses_layout_; LensBar* lens_bar_; @@ -136,6 +138,8 @@ bool search_in_progress_; bool activate_on_finish_; + guint hide_message_delay_id_; + bool visible_; }; diff -Nru unity-5.6.0/plugins/unityshell/src/DebugDBusInterface.cpp unity-5.8.0/plugins/unityshell/src/DebugDBusInterface.cpp --- unity-5.6.0/plugins/unityshell/src/DebugDBusInterface.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/DebugDBusInterface.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include "DebugDBusInterface.h" #include "Introspectable.h" @@ -38,10 +40,21 @@ { namespace { - nux::logging::Logger logger("unity.debug.DebugDBusInterface"); +nux::logging::Logger logger("unity.debug.DebugDBusInterface"); + +namespace local +{ + std::ofstream output_file; +} } GVariant* GetState(std::string const& query); +void StartLogToFile(std::string const& file_path); +void ResetLogging(); +void SetLogSeverity(std::string const& log_component, + std::string const& severity); +void LogMessage(std::string const& severity, + std::string const& message); const char* DebugDBusInterface::DBUS_DEBUG_OBJECT_PATH = "/com/canonical/Unity/Debug"; @@ -54,6 +67,23 @@ " " " " "" + " " + " " + " " + "" + " " + " " + "" + " " + " " + " " + " " + "" + " " + " " + " " + " " + "" " " " "; @@ -67,7 +97,7 @@ static CompScreen* _screen; static Introspectable* _parent_introspectable; -DebugDBusInterface::DebugDBusInterface(Introspectable* parent, +DebugDBusInterface::DebugDBusInterface(Introspectable* parent, CompScreen* screen) { _screen = screen; @@ -100,7 +130,7 @@ return; } - while (introspection_data->interfaces[i] != NULL) + while (introspection_data->interfaces[i] != NULL) { error = NULL; g_dbus_connection_register_object(connection, @@ -150,9 +180,40 @@ g_dbus_method_invocation_return_value(invocation, ret); g_variant_unref(ret); } + else if (g_strcmp0(method_name, "StartLogToFile") == 0) + { + const gchar* log_path; + g_variant_get(parameters, "(&s)", &log_path); + + StartLogToFile(log_path); + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "ResetLogging") == 0) + { + ResetLogging(); + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "SetLogSeverity") == 0) + { + const gchar* component; + const gchar* severity; + g_variant_get(parameters, "(&s&s)", &component, &severity); + + SetLogSeverity(component, severity); + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "LogMessage") == 0) + { + const gchar* severity; + const gchar* message; + g_variant_get(parameters, "(&s&s)", &severity, &message); + + LogMessage(severity, message); + g_dbus_method_invocation_return_value(invocation, NULL); + } else { - g_dbus_method_invocation_return_dbus_error(invocation, + g_dbus_method_invocation_return_dbus_error(invocation, unity::DBUS_BUS_NAME.c_str(), "Failed to find method"); } @@ -165,17 +226,50 @@ std::list parts = GetIntrospectableNodesFromQuery(query, _parent_introspectable); GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); - + for (Introspectable *node : parts) { g_variant_builder_add_value(&builder, node->Introspect()); } - + return g_variant_new("(aa{sv})", &builder); } +void StartLogToFile(std::string const& file_path) +{ + if (local::output_file.is_open()) + local::output_file.close(); + local::output_file.open(file_path); + nux::logging::Writer::Instance().SetOutputStream(local::output_file); +} + +void ResetLogging() +{ + if (local::output_file.is_open()) + local::output_file.close(); + nux::logging::Writer::Instance().SetOutputStream(std::cout); + nux::logging::reset_logging(); +} + +void SetLogSeverity(std::string const& log_component, + std::string const& severity) +{ + nux::logging::Logger(log_component).SetLogLevel(nux::logging::get_logging_level(severity)); +} + +void LogMessage(std::string const& severity, + std::string const& message) +{ + nux::logging::Level level = nux::logging::get_logging_level(severity); + if (logger.GetEffectiveLogLevel() <= level) + { + nux::logging::LogStream(level, logger.module(), __FILE__, __LINE__).stream() + << message; + } +} + /* - * Do a breadth-first search of the introspection tree and find all nodes that match the + * Do a breadth-first search of the introspection tree and find all nodes that match the * query. */ std::list GetIntrospectableNodesFromQuery(std::string const& query, Introspectable* tree_root) @@ -197,12 +291,12 @@ { std::list query_strings; boost::algorithm::split(query_strings, sanitised_query, boost::algorithm::is_any_of("/")); - // Boost's split() implementation does not match it's documentation! According to the - // docs, it's not supposed to add empty strings, but it does, which is a PITA. This + // Boost's split() implementation does not match it's documentation! According to the + // docs, it's not supposed to add empty strings, but it does, which is a PITA. This // next line removes them: - query_strings.erase( std::remove_if( query_strings.begin(), - query_strings.end(), - boost::bind( &std::string::empty, _1 ) ), + query_strings.erase( std::remove_if( query_strings.begin(), + query_strings.end(), + boost::bind( &std::string::empty, _1 ) ), query_strings.end()); foreach(std::string part, query_strings) { @@ -229,7 +323,7 @@ { LOG_WARNING(logger) << "Malformed relative introspection query: '" << query << "'."; } - + // non-recursive BFS traversal to find starting points: std::queue queue; queue.push(tree_root); @@ -254,14 +348,14 @@ // now we have the tree start points, process them: query_parts.pop_front(); typedef std::pair::iterator> node_match_pair; - + std::queue traverse_queue; foreach(Introspectable *node, start_points) { traverse_queue.push(node_match_pair(node, query_parts.begin())); } start_points.clear(); - + while (!traverse_queue.empty()) { node_match_pair p = traverse_queue.front(); diff -Nru unity-5.6.0/plugins/unityshell/src/Decaymulator.cpp unity-5.8.0/plugins/unityshell/src/Decaymulator.cpp --- unity-5.6.0/plugins/unityshell/src/Decaymulator.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/Decaymulator.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -21,13 +21,19 @@ namespace unity { namespace ui { - + Decaymulator::Decaymulator() { on_decay_handle = 0; value.changed.connect(sigc::mem_fun(this, &Decaymulator::OnValueChanged)); } +Decaymulator::~Decaymulator() +{ + if (on_decay_handle) + g_source_remove(on_decay_handle); +} + void Decaymulator::OnValueChanged(int value) { if (!on_decay_handle && value > 0) @@ -49,10 +55,9 @@ return FALSE; } - self->value = self->value - partial_decay; return TRUE; } } -} \ No newline at end of file +} diff -Nru unity-5.6.0/plugins/unityshell/src/Decaymulator.h unity-5.8.0/plugins/unityshell/src/Decaymulator.h --- unity-5.6.0/plugins/unityshell/src/Decaymulator.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/Decaymulator.h 2012-03-23 11:53:16.000000000 +0000 @@ -37,6 +37,7 @@ nux::Property value; Decaymulator(); + ~Decaymulator(); private: void OnValueChanged(int value); @@ -48,4 +49,4 @@ } } -#endif \ No newline at end of file +#endif diff -Nru unity-5.6.0/plugins/unityshell/src/FilterBar.cpp unity-5.8.0/plugins/unityshell/src/FilterBar.cpp --- unity-5.6.0/plugins/unityshell/src/FilterBar.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterBar.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -23,6 +23,7 @@ #include #include +#include "DashStyle.h" #include "FilterBar.h" #include "FilterExpanderLabel.h" #include "FilterFactory.h" @@ -36,9 +37,6 @@ nux::logging::Logger logger("unity.dash.filterbar"); -const int SEPARATOR_LEFT_PADDING = 5; -const int SEPARATOR_WIDTH_SOTTRACTOR = 9; - } NUX_IMPLEMENT_OBJECT_TYPE(FilterBar); @@ -59,8 +57,11 @@ void FilterBar::Init() { + dash::Style& style = dash::Style::Instance(); + nux::LinearLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); - layout->SetSpaceBetweenChildren(10); + layout->SetTopAndBottomPadding(style.GetFilterBarTopPadding() - style.GetFilterHighlightPadding() - style.SEARCH_BAR_EXTRA_PADDING); + layout->SetSpaceBetweenChildren(style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding()); SetLayout(layout); } @@ -81,6 +82,8 @@ AddChild(filter_view); filter_map_[filter] = filter_view; GetLayout()->AddView(filter_view, 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); + + UpdateDrawSeparators(); } void FilterBar::RemoveFilter(Filter::Ptr const& filter) @@ -96,6 +99,8 @@ break; } } + + UpdateDrawSeparators(); } void FilterBar::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) @@ -112,36 +117,31 @@ GfxContext.PushClippingRectangle(GetGeometry()); GetLayout()->ProcessDraw(GfxContext, force_draw); - nux::Color col(0.13f, 0.13f, 0.13f, 0.13f); + GfxContext.PopClippingRectangle(); +} - std::list& layout_list = GetLayout()->GetChildren(); - int i = 0; - int num_separators = layout_list.size() - 1; +void FilterBar::UpdateDrawSeparators() +{ + std::list children = GetLayout()->GetChildren(); + std::list::reverse_iterator rit; + bool found_one = false; - for (auto iter : layout_list) + for (rit = children.rbegin(); rit != children.rend(); ++rit) { - if (i != num_separators) - { - nux::Area* filter_view = iter; - nux::Geometry const& geom = filter_view->GetGeometry(); + FilterExpanderLabel* widget = dynamic_cast(*rit); - unsigned int alpha = 0, src = 0, dest = 0; - GfxContext.GetRenderStates().GetBlend(alpha, src, dest); + if (!widget) + continue; - GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - GfxContext.GetRenderStates().SetColorMask(true, true, true, false); - nux::GetPainter().Draw2DLine(GfxContext, - geom.x + SEPARATOR_LEFT_PADDING, geom.y + geom.height - 1, - geom.x + geom.width - SEPARATOR_WIDTH_SOTTRACTOR, geom.y + geom.height - 1, - col); - GfxContext.GetRenderStates().SetBlend(alpha, src, dest); - } - ++i; + widget->draw_separator = found_one; + found_one = true; } - - GfxContext.PopClippingRectangle(); } +// +// Key navigation +// + bool FilterBar::AcceptKeyNavFocus() { return false; diff -Nru unity-5.6.0/plugins/unityshell/src/FilterBar.h unity-5.8.0/plugins/unityshell/src/FilterBar.h --- unity-5.6.0/plugins/unityshell/src/FilterBar.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterBar.h 2012-03-23 11:53:16.000000000 +0000 @@ -60,6 +60,7 @@ private: void Init(); + void UpdateDrawSeparators(); FilterFactory factory_; Filters::Ptr filters_; diff -Nru unity-5.6.0/plugins/unityshell/src/FilterBasicButton.cpp unity-5.8.0/plugins/unityshell/src/FilterBasicButton.cpp --- unity-5.6.0/plugins/unityshell/src/FilterBasicButton.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterBasicButton.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -100,7 +100,7 @@ void FilterBasicButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state) { - Style::Instance().Button(cr, faked_state, label_); + Style::Instance().Button(cr, faked_state, label_, -1, Alignment::CENTER, true); } void FilterBasicButton::RedrawFocusOverlay(nux::Geometry const& geom, cairo_t* cr) @@ -111,7 +111,7 @@ long FilterBasicButton::ComputeContentSize() { long ret = nux::Button::ComputeContentSize(); - + nux::Geometry const& geo = GetGeometry(); if (cached_geometry_ != geo) diff -Nru unity-5.6.0/plugins/unityshell/src/FilterExpanderLabel.cpp unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.cpp --- unity-5.6.0/plugins/unityshell/src/FilterExpanderLabel.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -22,30 +22,18 @@ #include "DashStyle.h" #include "FilterExpanderLabel.h" +#include "LineSeparator.h" namespace { const float EXPAND_DEFAULT_ICON_OPACITY = 1.0f; -// right_hand_contents_ -const int RIGHT_HAND_CONTENTS_HEIGHT = 33; - -// layout_ -const int LAYOUT_LEFT_PADDING = 3; -const int LAYOUT_RIGHT_PADDING = 1; - -// top_bar_layout_ -const int TOP_BAR_LAYOUT_LEFT_PADDING = 2; -const int TOP_BAR_LAYOUT_RIGHT_PADDING = 0; -const int TOP_BAR_LAYOUT_WIDTH_ADDER = 19; - // expander_layout_ const int EXPANDER_LAYOUT_SPACE_BETWEEN_CHILDREN = 8; -// highlight -const int HIGHLIGHT_HEIGHT = 34; -const int HIGHLIGHT_WIDTH_SUBTRACTOR = 5; +// font +const char* const FONT_EXPANDER_LABEL = "Ubuntu Bold 13"; // 17px = 13 class ExpanderView : public nux::View { @@ -95,6 +83,7 @@ FilterExpanderLabel::FilterExpanderLabel(std::string const& label, NUX_FILE_LINE_DECL) : nux::View(NUX_FILE_LINE_PARAM) , expanded(true) + , draw_separator(false) , layout_(nullptr) , top_bar_layout_(nullptr) , expander_view_(nullptr) @@ -102,35 +91,62 @@ , right_hand_contents_(nullptr) , cairo_label_(nullptr) , raw_label_(label) - , label_("" + label + "") + , label_("label") + , separator_(nullptr) { expanded.changed.connect(sigc::mem_fun(this, &FilterExpanderLabel::DoExpandChange)); BuildLayout(); - SetAcceptKeyNavFocusOnMouseDown(false); + + separator_ = new HSeparator; + separator_->SinkReference(); + + dash::Style& style = dash::Style::Instance(); + int space_height = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding(); + + space_ = new nux::SpaceLayout(space_height, space_height, space_height, space_height); + space_->SinkReference(); + + draw_separator.changed.connect([&](bool value) + { + if (value and !separator_->IsChildOf(layout_)) + { + layout_->AddLayout(space_, 0); + layout_->AddView(separator_, 0); + } + else if (!value and separator_->IsChildOf(layout_)) + { + layout_->AddLayout(space_, 0); + layout_->RemoveChildObject(separator_); + } + QueueDraw(); + }); } FilterExpanderLabel::~FilterExpanderLabel() { + if (space_) + space_->UnReference(); + + if (separator_) + separator_->UnReference(); } void FilterExpanderLabel::SetLabel(std::string const& label) { raw_label_ = label; - label_ = ""; - label_ += raw_label_; - label_ += ""; - cairo_label_->SetText(label_.c_str()); + cairo_label_->SetText(label.c_str()); } void FilterExpanderLabel::SetRightHandView(nux::View* view) { - view->SetMinimumHeight(RIGHT_HAND_CONTENTS_HEIGHT); - view->SetMaximumHeight(RIGHT_HAND_CONTENTS_HEIGHT); + dash::Style& style = dash::Style::Instance(); right_hand_contents_ = view; - top_bar_layout_->AddView(right_hand_contents_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + right_hand_contents_->SetMinimumHeight(style.GetAllButtonHeight()); + right_hand_contents_->SetMaximumHeight(style.GetAllButtonHeight()); + top_bar_layout_->AddView(right_hand_contents_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); } void FilterExpanderLabel::SetContents(nux::Layout* contents) @@ -139,18 +155,19 @@ contents_ = contents; layout_->AddLayout(contents_.GetPointer(), 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); - top_bar_layout_->SetTopAndBottomPadding(0); QueueDraw(); } void FilterExpanderLabel::BuildLayout() { + dash::Style& style = dash::Style::Instance(); + layout_ = new nux::VLayout(NUX_TRACKER_LOCATION); - layout_->SetLeftAndRightPadding(LAYOUT_LEFT_PADDING, LAYOUT_RIGHT_PADDING); + layout_->SetLeftAndRightPadding(style.GetFilterBarLeftPadding(), style.GetFilterBarRightPadding()); top_bar_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); - top_bar_layout_->SetLeftAndRightPadding(TOP_BAR_LAYOUT_LEFT_PADDING, TOP_BAR_LAYOUT_RIGHT_PADDING); + top_bar_layout_->SetTopAndBottomPadding(style.GetFilterHighlightPadding()); expander_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); expander_layout_->SetSpaceBetweenChildren(EXPANDER_LAYOUT_SPACE_BETWEEN_CHILDREN); @@ -159,10 +176,10 @@ expander_view_->SetLayout(expander_layout_); top_bar_layout_->AddView(expander_view_, 0); - cairo_label_ = new nux::StaticText(label_.c_str(), NUX_TRACKER_LOCATION); - cairo_label_->SetFontName("Ubuntu 10"); + cairo_label_ = new nux::StaticCairoText(label_.c_str(), NUX_TRACKER_LOCATION); + cairo_label_->SetFont(FONT_EXPANDER_LABEL); cairo_label_->SetTextColor(nux::color::White); - cairo_label_->SetAcceptKeyNavFocusOnMouseDown(false); + cairo_label_->SetAcceptKeyboardEvent(false); nux::BaseTexture* arrow; arrow = dash::Style::Instance().GetGroupUnexpandIcon(); @@ -183,8 +200,6 @@ expander_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER); top_bar_layout_->AddSpace(1, 1); - top_bar_layout_->SetMaximumWidth((Style::Instance().GetTileWidth() - 12) * 2 + TOP_BAR_LAYOUT_WIDTH_ADDER); - layout_->AddLayout(top_bar_layout_, 0, nux::MINOR_POSITION_LEFT); layout_->SetVerticalInternalMargin(0); @@ -232,13 +247,11 @@ if (change and contents_ and !contents_->IsChildOf(layout_)) { - layout_->AddLayout(contents_.GetPointer(), 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); - top_bar_layout_->SetTopAndBottomPadding(0); + layout_->AddLayout(contents_.GetPointer(), 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL, 100.0f, nux::LayoutPosition(1)); } else if (!change and contents_ and contents_->IsChildOf(layout_)) { layout_->RemoveChildObject(contents_.GetPointer()); - top_bar_layout_->SetTopAndBottomPadding(0, 10); } layout_->ComputeContentSize(); @@ -261,8 +274,7 @@ { nux::Geometry geo(top_bar_layout_->GetGeometry()); geo.x = base.x; - geo.height = HIGHLIGHT_HEIGHT; - geo.width = base.width - HIGHLIGHT_WIDTH_SUBTRACTOR;; + geo.width = base.width; if (!highlight_layer_) highlight_layer_.reset(dash::Style::Instance().FocusOverlay(geo.width, geo.height)); diff -Nru unity-5.6.0/plugins/unityshell/src/FilterExpanderLabel.h unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.h --- unity-5.6.0/plugins/unityshell/src/FilterExpanderLabel.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.h 2012-03-23 11:53:16.000000000 +0000 @@ -30,11 +30,11 @@ #include #include #include -#include #include #include "IconTexture.h" #include "Introspectable.h" +#include "StaticCairoText.h" namespace nux { @@ -43,6 +43,9 @@ namespace unity { + +class HSeparator; + namespace dash { @@ -61,6 +64,7 @@ virtual std::string GetFilterType() = 0; nux::Property expanded; + nux::Property draw_separator; protected: virtual bool AcceptKeyNavFocus(); @@ -81,13 +85,15 @@ nux::View* expander_view_; nux::LinearLayout* expander_layout_; nux::View* right_hand_contents_; - nux::StaticText* cairo_label_; + nux::StaticCairoText* cairo_label_; std::string raw_label_; std::string label_; nux::VLayout* arrow_layout_; nux::SpaceLayout* arrow_top_space_; nux::SpaceLayout* arrow_bottom_space_; IconTexture* expand_icon_; + HSeparator* separator_; + nux::SpaceLayout* space_; nux::ObjectPtr contents_; std::unique_ptr highlight_layer_; diff -Nru unity-5.6.0/plugins/unityshell/src/FilterGenreWidget.cpp unity-5.8.0/plugins/unityshell/src/FilterGenreWidget.cpp --- unity-5.6.0/plugins/unityshell/src/FilterGenreWidget.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterGenreWidget.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,6 +39,8 @@ FilterGenre::FilterGenre(int columns, NUX_FILE_LINE_DECL) : FilterExpanderLabel(_("Categories"), NUX_FILE_LINE_PARAM) { + dash::Style& style = dash::Style::Instance(); + InitTheme(); all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION); @@ -46,16 +48,18 @@ genre_layout_ = new nux::GridHLayout(NUX_TRACKER_LOCATION); genre_layout_->ForceChildrenSize(true); genre_layout_->MatchContentSize(true); - genre_layout_->SetSpaceBetweenChildren (9, 9); - genre_layout_->SetTopAndBottomPadding(9, 12); + genre_layout_->SetTopAndBottomPadding(style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding(), style.GetFilterHighlightPadding()); genre_layout_->EnablePartialVisibility(false); + if (columns == 3) { - genre_layout_->SetChildrenSize(92, 33); + genre_layout_->SetChildrenSize((style.GetFilterBarWidth() - 12 * 2) / 3, style.GetFilterButtonHeight()); + genre_layout_->SetSpaceBetweenChildren (12, 12); } else { - genre_layout_->SetChildrenSize(Style::Instance().GetTileWidth() - 7, 33); + genre_layout_->SetChildrenSize((style.GetFilterBarWidth() - 10 ) / 2, style.GetFilterButtonHeight()); + genre_layout_->SetSpaceBetweenChildren (10, 12); } SetRightHandView(all_button_); @@ -72,7 +76,7 @@ all_button_->SetFilter(filter_); expanded = !filter_->collapsed(); - + filter_->option_added.connect(sigc::mem_fun(this, &FilterGenre::OnOptionAdded)); filter_->option_removed.connect(sigc::mem_fun(this, &FilterGenre::OnOptionRemoved)); diff -Nru unity-5.6.0/plugins/unityshell/src/FilterMultiRangeButton.cpp unity-5.8.0/plugins/unityshell/src/FilterMultiRangeButton.cpp --- unity-5.6.0/plugins/unityshell/src/FilterMultiRangeButton.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterMultiRangeButton.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -148,7 +148,7 @@ } } - SetMinimumHeight(32); + SetMinimumHeight(dash::Style::Instance().GetFilterButtonHeight() + 3); } void FilterMultiRangeButton::RedrawTheme(nux::Geometry const& geom, @@ -158,12 +158,10 @@ MultiRangeSide faked_side) { std::string name("10"); - std::stringstream final; if (filter_) { name = filter_->name; - final << "" << name << ""; } Arrow arrow; @@ -184,7 +182,7 @@ else segment = Segment::RIGHT; - Style::Instance().MultiRangeSegment(cr, faked_state, final.str(), arrow, segment); + Style::Instance().MultiRangeSegment(cr, faked_state, name, arrow, segment); NeedRedraw(); } @@ -192,7 +190,7 @@ cairo_t* cr, MultiRangeArrow faked_arrow, MultiRangeSide faked_side) -{ +{ Arrow arrow; if (faked_arrow == MultiRangeArrow::NONE) arrow = Arrow::NONE; diff -Nru unity-5.6.0/plugins/unityshell/src/FilterMultiRangeWidget.cpp unity-5.8.0/plugins/unityshell/src/FilterMultiRangeWidget.cpp --- unity-5.6.0/plugins/unityshell/src/FilterMultiRangeWidget.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterMultiRangeWidget.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -22,6 +22,7 @@ #include +#include "DashStyle.h" #include "FilterMultiRangeWidget.h" #include "FilterMultiRangeButton.h" #include "FilterBasicButton.h" @@ -33,15 +34,6 @@ { namespace dash { -namespace -{ - -const int TOP_PADDING = 9; -const int RIGHT_PADDING = 8; -const int BOTTOM_PADDING = 12; -const int LEFT_PADDING = 0; - -} NUX_IMPLEMENT_OBJECT_TYPE(FilterMultiRange); @@ -50,11 +42,17 @@ { InitTheme(); + dash::Style& style = dash::Style::Instance(); + const int left_padding = 0; + const int right_padding = 0; + const int top_padding = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding() - 2; + const int bottom_padding = style.GetFilterHighlightPadding() - 1; + all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION); layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); - layout_->SetLeftAndRightPadding(LEFT_PADDING, RIGHT_PADDING); - layout_->SetTopAndBottomPadding(TOP_PADDING, BOTTOM_PADDING); + layout_->SetLeftAndRightPadding(left_padding, right_padding); + layout_->SetTopAndBottomPadding(top_padding, bottom_padding); SetRightHandView(all_button_); SetContents(layout_); diff -Nru unity-5.6.0/plugins/unityshell/src/FilterRatingsWidget.cpp unity-5.8.0/plugins/unityshell/src/FilterRatingsWidget.cpp --- unity-5.6.0/plugins/unityshell/src/FilterRatingsWidget.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/FilterRatingsWidget.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -24,6 +24,7 @@ #include #include +#include "DashStyle.h" #include "FilterGenreWidget.h" #include "FilterGenreButton.h" #include "FilterBasicButton.h" @@ -32,8 +33,6 @@ namespace { -const int top_padding = 11; -const int bottom_padding = 12; const int star_size = 28; } @@ -49,6 +48,10 @@ { all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION); + dash::Style& style = dash::Style::Instance(); + const int top_padding = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding() - 1; // -1 (PNGs have an 1px top padding) + const int bottom_padding = style.GetFilterHighlightPadding(); + nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); layout->SetTopAndBottomPadding(top_padding, bottom_padding); ratings_ = new FilterRatingsButton(NUX_TRACKER_LOCATION); diff -Nru unity-5.6.0/plugins/unityshell/src/HudController.cpp unity-5.8.0/plugins/unityshell/src/HudController.cpp --- unity-5.6.0/plugins/unityshell/src/HudController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,7 +39,7 @@ } Controller::Controller() - : launcher_width(66) + : launcher_width(65) , hud_service_("com.canonical.hud", "/com/canonical/hud") , window_(nullptr) , visible_(false) @@ -47,7 +47,9 @@ , timeline_id_(0) , last_opacity_(0.0f) , start_time_(0) + , launcher_is_locked_out_(false) , view_(nullptr) + , monitor_index_(0) { LOG_DEBUG(logger) << "hud startup"; SetupRelayoutCallbacks(); @@ -69,6 +71,8 @@ } }); + launcher_width.changed.connect([this] (int new_width) { Relayout(); }); + PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed)); hud_service_.queries_updated.connect(sigc::mem_fun(this, &Controller::OnQueriesFinished)); @@ -154,17 +158,23 @@ nux::Geometry Controller::GetIdealWindowGeometry() { - UScreen *uscreen = UScreen::GetDefault(); - int primary_monitor = uscreen->GetMonitorWithMouse(); - auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); - - // We want to cover as much of the screen as possible to grab any mouse events outside - // of our window - panel::Style &panel_style = panel::Style::Instance(); - return nux::Geometry (monitor_geo.x, - monitor_geo.y + panel_style.panel_height, - monitor_geo.width, - monitor_geo.height - panel_style.panel_height); + UScreen *uscreen = UScreen::GetDefault(); + int primary_monitor = uscreen->GetMonitorWithMouse(); + auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); + + // We want to cover as much of the screen as possible to grab any mouse events outside + // of our window + panel::Style &panel_style = panel::Style::Instance(); + nux::Geometry geo(monitor_geo.x, + monitor_geo.y + panel_style.panel_height, + monitor_geo.width, + monitor_geo.height - panel_style.panel_height); + if (launcher_is_locked_out_) + { + geo.x += launcher_width; + geo.width -= launcher_width; + } + return geo; } void Controller::Relayout(GdkScreen*screen) @@ -224,6 +234,16 @@ return visible_; } +void Controller::SetLauncherIsLockedOut(bool launcher_is_locked_out) +{ + launcher_is_locked_out_ = launcher_is_locked_out; + if (launcher_is_locked_out_) + view_->SetHideIcon(IconHideState::HIDE); + else + view_->SetHideIcon(IconHideState::SHOW); + Relayout(); +} + void Controller::ShowHud() { PluginAdapter* adaptor = PluginAdapter::Default(); @@ -248,6 +268,7 @@ focused_app_icon_ = view_icon.Str(); 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_); window_->ShowWindow(true); @@ -268,13 +289,14 @@ // hide the launcher GVariant* message_data = g_variant_new("(b)", TRUE); ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); - - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, UScreen::GetDefault()->GetMonitorWithMouse()); + monitor_index_ = UScreen::GetDefault()->GetMonitorWithMouse(); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, monitor_index_); ubus.SendMessage(UBUS_OVERLAY_SHOWN, info); nux::GetWindowCompositor().SetKeyFocusArea(view_->default_focus()); window_->SetEnterFocusInputArea(view_->default_focus()); } + void Controller::HideHud(bool restore) { LOG_DEBUG (logger) << "hiding the hud"; @@ -300,7 +322,7 @@ GVariant* message_data = g_variant_new("(b)", FALSE); ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, 0); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, monitor_index_); ubus.SendMessage(UBUS_OVERLAY_HIDDEN, info); } @@ -346,20 +368,7 @@ else { // ensure the text entry is focused - g_timeout_add(500, [] (gpointer data) -> gboolean - { - //THIS IS BAD - VERY VERY BAD - LOG_DEBUG(logger) << "Last attempt, forcing window focus"; - Controller* self = static_cast(data); - if (self->visible_) - { - nux::GetWindowCompositor().SetKeyFocusArea(self->view_->default_focus()); - - self->window_->PushToFront(); - self->window_->SetInputFocus(); - } - return FALSE; - }, self); + nux::GetWindowCompositor().SetKeyFocusArea(self->view_->default_focus()); } return FALSE; } @@ -398,6 +407,7 @@ { 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())); } @@ -416,6 +426,7 @@ 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())); } // Introspectable diff -Nru unity-5.6.0/plugins/unityshell/src/HudController.h unity-5.8.0/plugins/unityshell/src/HudController.h --- unity-5.6.0/plugins/unityshell/src/HudController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudController.h 2012-03-23 11:53:16.000000000 +0000 @@ -54,6 +54,8 @@ void ShowHud(); void HideHud(bool restore_focus = true); bool IsVisible(); + void SetLauncherIsLockedOut(bool launcher_is_locked_out); + protected: std::string GetName() const; void AddProperties(GVariantBuilder* builder); @@ -99,11 +101,14 @@ guint timeline_id_; float last_opacity_; gint64 start_time_; + + bool launcher_is_locked_out_; View* view_; guint ensure_id_; std::string focused_app_icon_; nux::Layout* layout_; + uint monitor_index_; }; diff -Nru unity-5.6.0/plugins/unityshell/src/HudLauncherIcon.cpp unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.cpp --- unity-5.6.0/plugins/unityshell/src/HudLauncherIcon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,125 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Gordon Allott + */ + +#include "HudLauncherIcon.h" +#include "Launcher.h" +#include "UnityCore/GLibWrapper.h" +#include + +#include "UBusMessages.h" + +#include + +namespace unity +{ +namespace launcher +{ + +namespace +{ +nux::logging::Logger logger("unity.launcher.hudlaunchericon"); +} + +UBusManager HudLauncherIcon::ubus_manager_; + +HudLauncherIcon::HudLauncherIcon(LauncherHideMode hide_mode) + : SimpleLauncherIcon() + , launcher_hide_mode_(hide_mode) +{ + tooltip_text = _("HUD"); + icon_name = PKGDATADIR"/launcher_bfb.png"; + SetQuirk(QUIRK_VISIBLE, false); + SetQuirk(QUIRK_RUNNING, false); + SetQuirk(QUIRK_ACTIVE, true); + SetIconType(TYPE_HOME); + + background_color_ = nux::color::White; + + ubus_manager_.RegisterInterest(UBUS_HUD_ICON_CHANGED, [&](GVariant *data) + { + std::string hud_icon_name; + const gchar* data_string = g_variant_get_string(data, NULL); + if (data_string) + hud_icon_name = data_string; + LOG_DEBUG(logger) << "Hud icon change: " << hud_icon_name; + if (!hud_icon_name.empty() + && hud_icon_name != icon_name()) + { + icon_name = hud_icon_name; + EmitNeedsRedraw(); + } + }); + + 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); }); +} + +void HudLauncherIcon::SetHideMode(LauncherHideMode hide_mode) +{ + launcher_hide_mode_ = hide_mode; +} + +void HudLauncherIcon::OnOverlayShown(GVariant* data, bool visible) +{ + unity::glib::String overlay_identity; + gboolean can_maximise = FALSE; + gint32 overlay_monitor = 0; + g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, + &overlay_identity, &can_maximise, &overlay_monitor); + + // If the hud is open, we show the HUD button iff we have a locked launcher + if (!g_strcmp0(overlay_identity, "hud") && + launcher_hide_mode_ == LAUNCHER_HIDE_NEVER) + { + SetQuirk(QUIRK_VISIBLE, visible); + EmitNeedsRedraw(); + } +} + +nux::Color HudLauncherIcon::BackgroundColor() +{ + return background_color_; +} + +nux::Color HudLauncherIcon::GlowColor() +{ + return background_color_; +} + +void HudLauncherIcon::ActivateLauncherIcon(ActionArg arg) +{ + // wut? activate? noo we don't do that. +} + +std::list HudLauncherIcon::GetMenus() +{ + std::list result; + return result; +} + +std::string HudLauncherIcon::GetName() const +{ + return "HudLauncherIcon"; +} + +} // namespace launcher +} // namespace unity + diff -Nru unity-5.6.0/plugins/unityshell/src/HudLauncherIcon.h unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/HudLauncherIcon.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,60 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Gordon Allott + */ + +#ifndef UNITYSHELL_HUDLAUNCHERICON_H +#define UNITYSHELL_HUDLAUNCHERICON_H + +#include "SimpleLauncherIcon.h" + +#include "LauncherOptions.h" +#include "UBusWrapper.h" + +namespace unity +{ +namespace launcher +{ + +class HudLauncherIcon : public SimpleLauncherIcon +{ + +public: + HudLauncherIcon(LauncherHideMode hide_mode); + + virtual nux::Color BackgroundColor(); + virtual nux::Color GlowColor(); + + void ActivateLauncherIcon(ActionArg arg); + void SetHideMode(LauncherHideMode hide_mode); + +protected: + std::list GetMenus(); + std::string GetName() const; + +private: + void OnOverlayShown(GVariant *data, bool visible); + + static unity::UBusManager ubus_manager_; + nux::Color background_color_; + LauncherHideMode launcher_hide_mode_; +}; + +} +} + +#endif // UNITYSHELL_HUDLAUNCHERICON_H diff -Nru unity-5.6.0/plugins/unityshell/src/HudView.cpp unity-5.8.0/plugins/unityshell/src/HudView.cpp --- unity-5.6.0/plugins/unityshell/src/HudView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -64,9 +64,11 @@ , current_height_(0) , timeline_need_more_draw_(false) , selected_button_(0) + , icon_state_(IconHideState::SHOW) + , activated_signal_sent_(false) { renderer_.SetOwner(this); - renderer_.need_redraw.connect([this] () { + renderer_.need_redraw.connect([this] () { QueueDraw(); }); @@ -78,9 +80,10 @@ SetupViews(); search_bar_->key_down.connect (sigc::mem_fun (this, &View::OnKeyDown)); - search_bar_->activated.connect ([&]() + search_bar_->activated.connect ([&]() { - search_activated.emit(search_bar_->search_string); + if (!activated_signal_sent_) + search_activated.emit(search_bar_->search_string); }); search_bar_->text_entry()->SetLoseKeyFocusOnKeyNavDirectionUp(false); @@ -113,12 +116,12 @@ { (*it)->fake_focused = false; } - } + } } }); mouse_down.connect(sigc::mem_fun(this, &View::OnMouseButtonDown)); - + Relayout(); } @@ -141,25 +144,25 @@ float progress = (diff - pause_before_grow_length) / grow_anim_length; int last_height = last_known_height_; int new_height = 0; - + if (last_height < target_height) { // grow new_height = last_height + ((target_height - last_height) * progress); } - else + else { //shrink new_height = last_height - ((last_height - target_height) * progress); } - + LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")" << "View height: " << GetGeometry().height; current_height_ = new_height; } - - QueueDraw(); - + + QueueDraw(); + if (diff > grow_anim_length + pause_before_grow_length) { // ensure we are at our final location and update last known height @@ -185,7 +188,6 @@ layout_->SetMinimumWidth(content_geo_.width); layout_->SetMaximumWidth(content_geo_.width); layout_->SetMaximumHeight(content_geo_.height); - //layout_->SetMinMaxSize(content_geo_.width, content_geo_.height); QueueDraw(); } @@ -201,7 +203,7 @@ // already started, just reset the last known height last_known_height_ = current_height_; } - + timeline_need_more_draw_ = true; start_time_ = g_get_monotonic_time(); QueueDraw(); @@ -231,7 +233,7 @@ int found_items = 0; for (auto query = queries.begin(); query != queries.end(); query++) { - if (found_items > 5) + if (found_items >= 5) break; HudButton::Ptr button(new HudButton()); @@ -274,17 +276,38 @@ QueueDraw(); } +void View::SetHideIcon(IconHideState hide_icon) +{ + LOG_DEBUG(logger) << "Hide icon called"; + if (hide_icon == icon_state_) + return; + + icon_state_ = hide_icon; + + if (icon_state_ == IconHideState::HIDE) + layout_->RemoveChildObject(dynamic_cast(icon_layout_.GetPointer())); + else + layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN); + + Relayout(); +} + // Gives us the width and height of the contents that will give us the best "fit", // which means that the icons/views will not have uneccessary padding, everything will // look tight nux::Geometry View::GetBestFitGeometry(nux::Geometry const& for_geo) { - //FIXME - remove magic values, replace with scalable text depending on DPI + //FIXME - remove magic values, replace with scalable text depending on DPI // requires smarter font settings really... int width, height = 0; width = 1024; height = 276; - + + if (icon_state_ == IconHideState::HIDE) + { + width -= icon_layout_->GetGeometry().width; + } + LOG_DEBUG (logger) << "best fit is, " << width << ", " << height; return nux::Geometry(0, 0, width, height); @@ -319,16 +342,18 @@ void View::SetupViews() { + dash::Style& style = dash::Style::Instance(); + nux::VLayout* super_layout = new nux::VLayout(); layout_ = new nux::HLayout(); - { + { // fill icon layout with icon icon_ = new Icon("", icon_size, true); - nux::Layout* icon_layout = new nux::VLayout(); + icon_layout_ = new nux::VLayout(); { - icon_layout->SetVerticalExternalMargin(icon_vertical_margin); - icon_layout->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); - layout_->AddLayout(icon_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT); + icon_layout_->SetVerticalExternalMargin(icon_vertical_margin); + icon_layout_->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); + layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT); } // add padding to layout between icon and content @@ -336,21 +361,23 @@ spacing_between_icon_and_content, spacing_between_icon_and_content, spacing_between_icon_and_content), 0); - + // fill the content layout content_layout_ = new nux::VLayout(); { - // add the top spacing + // add the top spacing content_layout_->AddLayout(new nux::SpaceLayout(top_spacing,top_spacing,top_spacing,top_spacing), 0); // add the search bar to the composite search_bar_ = new unity::SearchBar(content_width, true); search_bar_->disable_glow = true; + search_bar_->SetMinimumHeight(style.GetSearchBarHeight() + style.SEARCH_BAR_EXTRA_PADDING * 2); + search_bar_->SetMaximumHeight(style.GetSearchBarHeight() + style.SEARCH_BAR_EXTRA_PADDING * 2); search_bar_->search_hint = default_text; search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged)); AddChild(search_bar_.GetPointer()); content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT); - + button_views_ = new nux::VLayout(); button_views_->SetMaximumWidth(content_width); @@ -363,7 +390,7 @@ layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP); } - + super_layout->AddLayout(layout_.GetPointer(), 0); SetLayout(super_layout); } @@ -420,7 +447,7 @@ draw_content_geo.height = current_height_; renderer_.DrawInner(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_); - + gfx_context.PushClippingRectangle(draw_content_geo); if (IsFullRedraw()) { @@ -438,7 +465,7 @@ if (timeline_need_more_draw_ && !timeline_id_) { - timeline_id_ = g_timeout_add(0, [] (gpointer data) -> gboolean + timeline_id_ = g_timeout_add(0, [] (gpointer data) -> gboolean { View *self = static_cast(data); self->QueueDraw(); @@ -608,8 +635,9 @@ return search_bar_->text_entry(); } - if (direction == nux::KEY_NAV_ENTER) + if (event_type == nux::NUX_KEYDOWN && direction == nux::KEY_NAV_ENTER) { + activated_signal_sent_ = false; // The "Enter" key has been received and the text entry has the key focus. // If one of the button has the fake_focus, we get it to emit the query_activated signal. if (!buttons_.empty()) @@ -620,6 +648,7 @@ if ((*it)->fake_focused) { query_activated.emit((*it)->GetQuery()); + activated_signal_sent_ = true; } } } diff -Nru unity-5.6.0/plugins/unityshell/src/HudView.h unity-5.8.0/plugins/unityshell/src/HudView.h --- unity-5.6.0/plugins/unityshell/src/HudView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/HudView.h 2012-03-23 11:53:16.000000000 +0000 @@ -44,6 +44,12 @@ namespace hud { +enum IconHideState +{ + HIDE, + SHOW +}; + class View : public nux::View, public unity::debug::Introspectable { NUX_DECLARE_OBJECT_TYPE(HudView, nux::View); @@ -59,7 +65,8 @@ void SetQueries(Hud::Queries queries); void SetIcon(std::string icon_name); - + void SetHideIcon(IconHideState hide_icon); + void AboutToShow(); void AboutToHide(); @@ -100,10 +107,11 @@ nux::ObjectPtr content_layout_; nux::ObjectPtr button_views_; std::list buttons_; - + //FIXME - replace with dash search bar once modifications to dash search bar land SearchBar::Ptr search_bar_; Icon::Ptr icon_; + nux::ObjectPtr icon_layout_; bool visible_; Hud::Queries queries_; @@ -118,6 +126,8 @@ int current_height_; bool timeline_need_more_draw_; int selected_button_; + IconHideState icon_state_; + bool activated_signal_sent_; }; diff -Nru unity-5.6.0/plugins/unityshell/src/IconRenderer.cpp unity-5.8.0/plugins/unityshell/src/IconRenderer.cpp --- unity-5.6.0/plugins/unityshell/src/IconRenderer.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/IconRenderer.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -219,7 +219,7 @@ IconRenderer::IconRenderer() { pip_style = OUTSIDE_TILE; - + if (!local::textures_created) local::generate_textures(); } @@ -1257,8 +1257,16 @@ destroy_textures(icon_selected_background); destroy_textures(icon_edge); destroy_textures(icon_glow); + destroy_textures(icon_shadow); destroy_textures(icon_shine); + squircle_base->UnReference(); + squircle_base_selected->UnReference(); + squircle_edge->UnReference(); + squircle_glow->UnReference(); + squircle_shadow->UnReference(); + squircle_shine->UnReference(); + for (auto it = label_map.begin(), end = label_map.end(); it != end; ++it) it->second->UnReference(); label_map.clear(); diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherController.cpp unity-5.8.0/plugins/unityshell/src/LauncherController.cpp --- unity-5.6.0/plugins/unityshell/src/LauncherController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -32,6 +32,7 @@ #include "DeviceLauncherIcon.h" #include "DeviceLauncherSection.h" #include "FavoriteStore.h" +#include "HudLauncherIcon.h" #include "Launcher.h" #include "LauncherController.h" #include "LauncherEntryRemote.h" @@ -80,6 +81,8 @@ void Save(); void SortAndUpdate(); + nux::ObjectPtr CurrentLauncher(); + void OnIconAdded(AbstractLauncherIcon::Ptr icon); void OnIconRemoved(AbstractLauncherIcon::Ptr icon); @@ -101,12 +104,8 @@ void InsertDesktopIcon(); void RemoveDesktopIcon(); - bool TapTimeUnderLimit(); - void SendHomeActivationRequest(); - int TimeSinceLauncherKeyPress(); - int MonitorWithMouse(); void InsertTrash(); @@ -119,6 +118,8 @@ void SetupBamf(); + void EnsureLaunchers(int primary, std::vector const& monitors); + void OnExpoActivated(); void OnScreenChanged(int primary_monitor, std::vector& monitors); @@ -167,7 +168,7 @@ UBusManager ubus; - struct timespec launcher_key_press_time_; + int launcher_key_press_time_; LauncherList launchers; @@ -187,6 +188,7 @@ { UScreen* uscreen = UScreen::GetDefault(); auto monitors = uscreen->GetMonitors(); + int primary = uscreen->GetPrimaryMonitor(); launcher_open = false; launcher_keynav = false; @@ -194,13 +196,7 @@ reactivate_keynav = false; keynav_restore_window_ = true; - int i = 0; - for (auto monitor : monitors) - { - Launcher* launcher = CreateLauncher(i); - launchers.push_back(nux::ObjectPtr (launcher)); - i++; - } + EnsureLaunchers(primary, monitors); launcher_ = launchers[0]; @@ -234,15 +230,26 @@ FavoriteStore::GetDefault().favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved)); FavoriteStore::GetDefault().reordered.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreReordered)); - RegisterIcon(AbstractLauncherIcon::Ptr(new BFBLauncherIcon())); + LauncherHideMode hide_mode = parent_->options()->hide_mode; + BFBLauncherIcon* bfb = new BFBLauncherIcon(hide_mode); + parent_->options()->hide_mode.changed.connect([bfb](LauncherHideMode mode) { + bfb->SetHideMode(mode); + }); + RegisterIcon(AbstractLauncherIcon::Ptr(bfb)); + + HudLauncherIcon* hud = new HudLauncherIcon(hide_mode); + parent_->options()->hide_mode.changed.connect([hud](LauncherHideMode mode) { + hud->SetHideMode(mode); + }); + RegisterIcon(AbstractLauncherIcon::Ptr(hud)); desktop_icon_ = AbstractLauncherIcon::Ptr(new DesktopLauncherIcon()); uscreen->changed.connect(sigc::mem_fun(this, &Controller::Impl::OnScreenChanged)); - WindowManager& plugin_adapter = *(WindowManager::Default()); + WindowManager& plugin_adapter = *(WindowManager::Default()); plugin_adapter.window_focus_changed.connect (sigc::mem_fun (this, &Controller::Impl::OnWindowFocusChanged)); - launcher_key_press_time_ = { 0, 0 }; + launcher_key_press_time_ = 0; ubus.RegisterInterest(UBUS_QUICKLIST_END_KEY_NAV, [&](GVariant * args) { if (reactivate_keynav) @@ -255,6 +262,15 @@ Controller::Impl::~Impl() { + // Since the launchers are in a window which adds a reference to the + // launcher, we need to make sure the base windows are unreferenced + // otherwise the launchers never die. + for (auto launcher_ptr : launchers) + { + if (launcher_ptr.IsValid()) + launcher_ptr->GetParent()->UnReference(); + } + if (bamf_timer_handler_id_ != 0) g_source_remove(bamf_timer_handler_id_); @@ -264,26 +280,58 @@ delete device_section_; } -void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector& monitors) +void Controller::Impl::EnsureLaunchers(int primary, std::vector const& monitors) { unsigned int num_monitors = monitors.size(); + unsigned int num_launchers = parent_->multiple_launchers ? num_monitors : 1; + unsigned int launchers_size = launchers.size(); + unsigned int last_monitor = 0; - unsigned int i; - for (i = 0; i < num_monitors; i++) + if (num_launchers == 1) { - if (i >= launchers.size()) - launchers.push_back(nux::ObjectPtr (CreateLauncher(i))); + if (launchers_size == 0) + { + launchers.push_back(nux::ObjectPtr(CreateLauncher(primary))); + } + else if (!launchers[0].IsValid()) + { + launchers[0] = nux::ObjectPtr(CreateLauncher(primary)); + } + + launchers[0]->monitor(primary); + launchers[0]->Resize(); + last_monitor = 1; + } + else + { + for (unsigned int i = 0; i < num_monitors; i++, last_monitor++) + { + if (i >= launchers_size) + { + launchers.push_back(nux::ObjectPtr(CreateLauncher(i))); + } - launchers[i]->Resize(); + launchers[i]->monitor(i); + launchers[i]->Resize(); + } } - for (; i < launchers.size(); ++i) + for (unsigned int i = last_monitor; i < launchers_size; ++i) { auto launcher = launchers[i]; if (launcher.IsValid()) + { + parent_->RemoveChild(launcher.GetPointer()); launcher->GetParent()->UnReference(); + } } - launchers.resize(num_monitors); + + launchers.resize(num_launchers); +} + +void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector& monitors) +{ + EnsureLaunchers(primary_monitor, monitors); } void Controller::Impl::OnWindowFocusChanged (guint32 xid) @@ -299,7 +347,7 @@ else if (launcher_keynav) { keynav_first_focus = true; - } + } } Launcher* Controller::Impl::CreateLauncher(int monitor) @@ -326,6 +374,7 @@ launcher->SetModel(model_.get()); launcher->launcher_addrequest.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequest)); + launcher->launcher_addrequest_special.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequestSpecial)); launcher->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest)); parent_->AddChild(launcher); @@ -371,7 +420,7 @@ std::string const& desktop_file = icon->DesktopFile(); if (!desktop_file.empty()) - desktop_paths.push_back(desktop_file.c_str()); + desktop_paths.push_back(desktop_file); } unity::FavoriteStore::GetDefault().SetFavorites(desktop_paths); @@ -602,7 +651,7 @@ on_expoicon_activate_connection_ = icon->activate.connect(sigc::mem_fun(this, &Impl::OnExpoActivated)); - + RegisterIcon(expo_icon_); } @@ -761,29 +810,23 @@ bamf_timer_handler_id_ = 0; } -int Controller::Impl::TimeSinceLauncherKeyPress() -{ - struct timespec current; - unity::TimeUtil::SetTimeStruct(¤t); - return unity::TimeUtil::TimeDelta(¤t, &launcher_key_press_time_); -} - -bool Controller::Impl::TapTimeUnderLimit() -{ - int time_difference = TimeSinceLauncherKeyPress(); - return time_difference < local::super_tap_duration; -} - void Controller::Impl::SendHomeActivationRequest() { ubus.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", 0, "")); } Controller::Controller(Display* display) -{ - options = Options::Ptr(new Options()); - // options must be set before creating pimpl which loads launchers - pimpl = new Impl(display, this); + : options(Options::Ptr(new Options())) + , multiple_launchers(true) + , pimpl(new Impl(display, this)) +{ + multiple_launchers.changed.connect([&](bool value) -> void { + UScreen* uscreen = UScreen::GetDefault(); + auto monitors = uscreen->GetMonitors(); + int primary = uscreen->GetPrimaryMonitor(); + pimpl->EnsureLaunchers(primary, monitors); + options()->show_for_all = !value; + }); } Controller::~Controller() @@ -834,6 +877,8 @@ Window Controller::LauncherWindowId(int launcher) const { + if (launcher >= (int)pimpl->launchers.size()) + return 0; return pimpl->launchers[launcher]->GetParent()->GetInputWindowId(); } @@ -868,15 +913,24 @@ return uscreen->GetMonitorWithMouse(); } -void Controller::HandleLauncherKeyPress() +nux::ObjectPtr Controller::Impl::CurrentLauncher() +{ + nux::ObjectPtr result; + int best = std::min (launchers.size() - 1, MonitorWithMouse()); + if (best >= 0) + result = launchers[best]; + return result; +} + +void Controller::HandleLauncherKeyPress(int when) { - unity::TimeUtil::SetTimeStruct(&pimpl->launcher_key_press_time_); + pimpl->launcher_key_press_time_ = when; auto show_launcher = [](gpointer user_data) -> gboolean { Impl* self = static_cast(user_data); if (self->keyboard_launcher_.IsNull()) - self->keyboard_launcher_ = self->launchers[self->MonitorWithMouse()]; + self->keyboard_launcher_ = self->CurrentLauncher(); if (self->launcher_hide_handler_id_ > 0) { @@ -897,7 +951,7 @@ if (!self->launcher_keynav) { if (self->keyboard_launcher_.IsNull()) - self->keyboard_launcher_ = self->launchers[self->MonitorWithMouse()]; + self->keyboard_launcher_ = self->CurrentLauncher(); self->keyboard_launcher_->ShowShortcuts(true); self->launcher_open = true; @@ -908,12 +962,18 @@ pimpl->launcher_label_show_handler_id_ = g_timeout_add(local::shortcuts_show_delay, show_shortcuts, pimpl); } -void Controller::HandleLauncherKeyRelease(bool was_tap) +void Controller::HandleLauncherKeyRelease(bool was_tap, int when) { - if (pimpl->TapTimeUnderLimit() && was_tap) + int tap_duration = when - pimpl->launcher_key_press_time_; + if (tap_duration < local::super_tap_duration && was_tap) { + LOG_DEBUG(logger) << "Quick tap, sending activation request."; pimpl->SendHomeActivationRequest(); } + else + { + LOG_DEBUG(logger) << "Tap too long: " << tap_duration; + } if (pimpl->launcher_label_show_handler_id_) { @@ -931,7 +991,7 @@ { pimpl->keyboard_launcher_->ShowShortcuts(false); - int ms_since_show = pimpl->TimeSinceLauncherKeyPress(); + int ms_since_show = tap_duration; if (ms_since_show > local::launcher_minimum_show_duration) { pimpl->keyboard_launcher_->ForceReveal(false); @@ -986,7 +1046,7 @@ } // disable the "tap on super" check - pimpl->launcher_key_press_time_ = { 0, 0 }; + pimpl->launcher_key_press_time_ = 0; return true; } } @@ -1021,7 +1081,7 @@ pimpl->reactivate_keynav = false; pimpl->launcher_keynav = true; pimpl->keynav_restore_window_ = true; - pimpl->keyboard_launcher_ = pimpl->launchers[pimpl->MonitorWithMouse()]; + pimpl->keyboard_launcher_ = pimpl->CurrentLauncher(); pimpl->keyboard_launcher_->EnterKeyNavMode(); pimpl->model_->SetSelection(0); @@ -1087,7 +1147,7 @@ .add("key_nav_launcher_monitor", pimpl->keyboard_launcher_.IsValid() ? pimpl->keyboard_launcher_->monitor : -1) .add("key_nav_selection", pimpl->model_->SelectionIndex()) .add("key_nav_is_grabbed", pimpl->launcher_grabbed) - .add("keyboard_launcher", pimpl->launchers[pimpl->MonitorWithMouse()]->monitor); + .add("keyboard_launcher", pimpl->CurrentLauncher()->monitor); } void Controller::Impl::ReceiveLauncherKeyPress(unsigned long eventType, @@ -1117,11 +1177,10 @@ parent_->KeyNavNext(); break; - // super/control/alt/esc/left (close quicklist or exit laucher key-focus) + // super/control/esc/left (close quicklist or exit laucher key-focus) case NUX_VK_LWIN: case NUX_VK_RWIN: case NUX_VK_CONTROL: - case NUX_VK_MENU: case NUX_VK_LEFT: case NUX_KP_LEFT: case NUX_VK_ESCAPE: @@ -1158,6 +1217,11 @@ break; default: + // ALT + ; treat it as a shortcut and exit keynav + if (state & nux::NUX_STATE_ALT) + { + parent_->KeyNavTerminate(false); + } break; } } diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherController.h unity-5.8.0/plugins/unityshell/src/LauncherController.h --- unity-5.6.0/plugins/unityshell/src/LauncherController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherController.h 2012-03-23 11:53:16.000000000 +0000 @@ -42,6 +42,7 @@ typedef std::vector > LauncherList; nux::Property options; + nux::Property multiple_launchers; Controller(Display* display); ~Controller(); @@ -59,8 +60,8 @@ void SetShowDesktopIcon(bool show_desktop_icon); - void HandleLauncherKeyPress(); - void HandleLauncherKeyRelease(bool was_tap); + void HandleLauncherKeyPress(int when); + void HandleLauncherKeyRelease(bool was_tap, int when); bool HandleLauncherKeyEvent(Display *display, unsigned int key_sym, unsigned long key_code, diff -Nru unity-5.6.0/plugins/unityshell/src/Launcher.cpp unity-5.8.0/plugins/unityshell/src/Launcher.cpp --- unity-5.6.0/plugins/unityshell/src/Launcher.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/Launcher.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -145,8 +145,8 @@ , _collection_window(NULL) , _background_color(nux::color::DimGray) , _dash_is_open(false) + , _hud_is_open(false) { - _parent = parent; _active_quicklist = nullptr; @@ -201,8 +201,7 @@ _folded_angle = 1.0f; _neg_folded_angle = -1.0f; _space_between_icons = 5; - _launcher_top_y = 0; - _launcher_bottom_y = 0; + _last_delta_y = 0.0f; _folded_z_distance = 10.0f; _launcher_action_state = ACTION_NONE; _icon_under_mouse = NULL; @@ -221,11 +220,13 @@ _autoscroll_handle = 0; _start_dragicon_handle = 0; _dnd_check_handle = 0; + _strut_hack_handle = 0; _last_reveal_progress = 0; _shortcuts_shown = false; _hovered = false; _hidden = false; + _scroll_limit_reached = false; _render_drag_window = false; _drag_edge_touching = false; _steal_drag = false; @@ -286,7 +287,7 @@ bg_effect_helper_.enabled = false; TextureCache& cache = TextureCache::GetDefault(); - TextureCache::CreateTextureCallback cb = [&](std::string const& name, int width, int height) -> nux::BaseTexture* { + TextureCache::CreateTextureCallback cb = [&](std::string const& name, int width, int height) -> nux::BaseTexture* { return nux::CreateTexture2DFromFile((PKGDATADIR"/" + name + ".png").c_str(), -1, true); }; @@ -313,6 +314,8 @@ g_source_remove(_start_dragicon_handle); if (_launcher_animation_timeout > 0) g_source_remove(_launcher_animation_timeout); + if (_strut_hack_handle) + g_source_remove(_strut_hack_handle); if (_on_data_collected_connection.connected()) _on_data_collected_connection.disconnect(); @@ -405,8 +408,8 @@ .add("height", abs_geo.height) .add("monitor", monitor()) .add("quicklist-open", _hide_machine->GetQuirk(LauncherHideMachine::QUICKLIST_OPEN)) - .add("hide-quirks", _hide_machine->DebugHideQuirks().c_str()) - .add("hover-quirks", _hover_machine->DebugHoverQuirks().c_str()) + .add("hide-quirks", _hide_machine->DebugHideQuirks()) + .add("hover-quirks", _hover_machine->DebugHoverQuirks()) .add("icon-size", _icon_size) .add("shortcuts_shown", _shortcuts_shown); } @@ -881,7 +884,6 @@ arg.colorify = nux::color::White; arg.running_arrow = icon->GetQuirk(AbstractLauncherIcon::QUIRK_RUNNING); arg.running_colored = icon->GetQuirk(AbstractLauncherIcon::QUIRK_URGENT); - arg.running_on_viewport = icon->WindowVisibleOnMonitor(monitor); arg.draw_edge_only = IconDrawEdgeOnly(icon); arg.active_colored = false; arg.x_rotation = 0.0f; @@ -900,11 +902,23 @@ icon->GetIconType() == AbstractLauncherIcon::TYPE_DEVICE || icon->GetIconType() == AbstractLauncherIcon::TYPE_EXPO; - if (_dash_is_open) + // trying to protect against flickering when icon is dragged from dash LP: #863230 + if (arg.alpha < 0.5) + { + arg.alpha = 0.5; + arg.saturation = 0.0; + } + + if (IsOverlayOpen()) arg.active_arrow = icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME; else arg.active_arrow = icon->GetQuirk(AbstractLauncherIcon::QUIRK_ACTIVE); + if (options()->show_for_all) + arg.running_on_viewport = icon->WindowVisibleOnViewport(); + else + arg.running_on_viewport = icon->WindowVisibleOnMonitor(monitor); + guint64 shortcut = icon->GetShortcut(); if (shortcut > 32) arg.shortcut_label = (char) shortcut; @@ -924,7 +938,10 @@ } else { - arg.window_indicators = std::max (icon->WindowsForMonitor(monitor).size(), 1); + if (options()->show_for_all) + arg.window_indicators = std::max (icon->WindowsOnViewport().size(), 1); + else + arg.window_indicators = std::max (icon->WindowsForMonitor(monitor).size(), 1); } arg.backlight_intensity = IconBackgroundIntensity(icon, current); @@ -979,6 +996,13 @@ if (drop_dim_value < 1.0f) arg.alpha *= drop_dim_value; + // trying to protect against flickering when icon is dragged from dash LP: #863230 + if (arg.alpha < 0.5) + { + arg.alpha = 0.5; + arg.saturation = 0.0; + } + if (icon == _drag_icon) { if (MouseBeyondDragThreshold()) @@ -1030,7 +1054,7 @@ // FIXME: this is a hack, we should have a look why SetAnimationTarget is necessary in SetAnimationTarget // we should ideally just need it at start to set the target if (!_initial_drag_animation && icon == _drag_icon && _drag_window && _drag_window->Animating()) - _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x), + _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x), (int)(_drag_icon->GetCenter(monitor).y)); center.y += (half_size * size_modifier) + spacing; // move to end @@ -1179,6 +1203,9 @@ delta_y *= hover_progress; center.y += delta_y; folding_threshold += delta_y; + + _scroll_limit_reached = (delta_y == _last_delta_y); + _last_delta_y = delta_y; } else { @@ -1294,22 +1321,31 @@ gint32 overlay_monitor = 0; g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); + std::string identity = overlay_identity.Str(); + LOG_DEBUG(logger) << "Overlay shown: " << identity + << ", " << (can_maximise ? "can maximise" : "can't maximise") + << ", on monitor " << overlay_monitor + << " (for monitor " << monitor() << ")"; - if (!g_strcmp0(overlay_identity, "dash")) + if (overlay_monitor == monitor()) { - if (overlay_monitor == monitor) + if (identity == "dash") { - LauncherModel::iterator it; - _dash_is_open = true; - bg_effect_helper_.enabled = true; _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, true); _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, true); - - DesaturateIcons(); } + if (identity == "hud") + { + _hud_is_open = true; + } + + bg_effect_helper_.enabled = true; + LOG_DEBUG(logger) << "Desaturate on monitor " << monitor(); + DesaturateIcons(); } + EnsureAnimation(); } void Launcher::OnOverlayHidden(GVariant* data) @@ -1321,26 +1357,45 @@ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); - if (!g_strcmp0(overlay_identity, "dash")) - { - if (!_dash_is_open) - return; + std::string identity = overlay_identity.Str(); - LauncherModel::iterator it; + LOG_DEBUG(logger) << "Overlay hidden: " << identity + << ", " << (can_maximise ? "can maximise" : "can't maximise") + << ", on monitor " << overlay_monitor + << " (for monitor" << monitor() << ")"; - _dash_is_open = false; - bg_effect_helper_.enabled = false; - _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false); - _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false); + if (overlay_monitor == monitor()) + { + if (identity == "dash") + { + _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false); + _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false); + _dash_is_open = false; + } + else if (identity == "hud") + { + _hud_is_open = false; + } - // as the leave event is no more received when the place is opened - // FIXME: remove when we change the mouse grab strategy in nux - nux::Point pt = nux::GetWindowCompositor().GetMousePosition(); + // If they are both now shut, then disable the effect helper and saturate the icons. + if (!IsOverlayOpen()) + { + bg_effect_helper_.enabled = false; + LOG_DEBUG(logger) << "Saturate on monitor " << monitor(); + SaturateIcons(); + } + } + EnsureAnimation(); - SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt)); + // as the leave event is no more received when the place is opened + // FIXME: remove when we change the mouse grab strategy in nux + nux::Point pt = nux::GetWindowCompositor().GetMousePosition(); + SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt)); +} - SaturateIcons(); - } +bool Launcher::IsOverlayOpen() const +{ + return _dash_is_open || _hud_is_open; } void Launcher::OnActionDone(GVariant* data) @@ -1427,7 +1482,7 @@ self->_collection_window->PushToBack(); self->_collection_window->EnableInputWindow(false, "DNDCollectionWindow"); - if (self->_dash_is_open && !self->_hovered) + if (self->IsOverlayOpen() && !self->_hovered) self->DesaturateIcons(); self->DndReset(); @@ -1447,6 +1502,9 @@ if (!_dnd_check_handle) _dnd_check_handle = g_timeout_add(200, &Launcher::OnUpdateDragManagerTimeout, this); //} + + if (GetActionState() != ACTION_NONE) + ResetMouseDragState(); } void @@ -1483,6 +1541,7 @@ if (self->options()->hide_mode == LAUNCHER_HIDE_NEVER) self->_parent->InputWindowEnableStruts(true); + self->_strut_hack_handle = 0; return false; } @@ -1506,24 +1565,37 @@ SetHideMode(options->hide_mode); SetIconSize(options->tile_size, options->icon_size); - // make the effect half as strong as specified as other values shouldn't scale - // as quickly as the max velocity multiplier - float decay_responsiveness_mult = ((options->edge_responsiveness() - 1) * .3f) + 1; - float reveal_responsiveness_mult = ((options->edge_responsiveness() - 1) * .025f) + 1; - float overcome_responsiveness_mult = ((options->edge_responsiveness() - 1) * 1.0f) + 1; - - decaymulator_->rate_of_decay = options->edge_decay_rate() * decay_responsiveness_mult; - _edge_overcome_pressure = options->edge_overcome_pressure() * overcome_responsiveness_mult; + ConfigureBarrier(); + EnsureAnimation(); +} - _pointer_barrier->threshold = options->edge_stop_velocity(); - _pointer_barrier->max_velocity_multiplier = options->edge_responsiveness(); +void Launcher::ConfigureBarrier() +{ + nux::Geometry geo = GetAbsoluteGeometry(); _pointer_barrier->DestroyBarrier(); - _pointer_barrier->ConstructBarrier(); - _hide_machine->reveal_pressure = options->edge_reveal_pressure() * reveal_responsiveness_mult; - _hide_machine->edge_decay_rate = options->edge_decay_rate() * decay_responsiveness_mult; + if (options()->edge_resist || geo.x == 0) + { + unity::panel::Style &panel_style = panel::Style::Instance(); + + _pointer_barrier->x1 = geo.x; + _pointer_barrier->x2 = geo.x; + _pointer_barrier->y1 = geo.y - panel_style.panel_height; + _pointer_barrier->y2 = geo.y + geo.height; + + float decay_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .3f) + 1; + float reveal_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .025f) + 1; + float overcome_responsiveness_mult = ((options()->edge_responsiveness() - 1) * 1.0f) + 1; + decaymulator_->rate_of_decay = options()->edge_decay_rate() * decay_responsiveness_mult; + _edge_overcome_pressure = options()->edge_overcome_pressure() * overcome_responsiveness_mult; + + _pointer_barrier->threshold = options()->edge_stop_velocity(); + _pointer_barrier->max_velocity_multiplier = options()->edge_responsiveness(); + _pointer_barrier->ConstructBarrier(); - EnsureAnimation(); + _hide_machine->reveal_pressure = options()->edge_reveal_pressure() * reveal_responsiveness_mult; + _hide_machine->edge_decay_rate = options()->edge_decay_rate() * decay_responsiveness_mult; + } } void Launcher::SetHideMode(LauncherHideMode hidemode) @@ -1535,7 +1607,8 @@ else { _parent->EnableInputWindow(true, "launcher", false, false); - g_timeout_add(1000, &Launcher::StrutHack, this); + if (!_strut_hack_handle) + _strut_hack_handle = g_timeout_add(1000, &Launcher::StrutHack, this); _parent->InputWindowEnableStruts(true); } @@ -1595,7 +1668,7 @@ TimeUtil::SetTimeStruct(&_times[TIME_LEAVE], &_times[TIME_ENTER], ANIM_DURATION); } - if (_dash_is_open && !_hide_machine->GetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE)) + if (IsOverlayOpen() && !_hide_machine->GetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE)) { if (hovered && !_hover_machine->GetQuirk(LauncherHoverMachine::SHORTCUT_KEYS_VISIBLE)) SaturateIcons(); @@ -1630,12 +1703,18 @@ { Launcher* self = (Launcher*) data; nux::Geometry geo = self->GetGeometry(); + gboolean anim = TRUE; + // + // Always check _scroll_limit_reached to ensure we don't keep spinning + // this timer if the mouse happens to be left idle over one of the autoscroll + // hotspots on the launcher. + // if (self->IsInKeyNavMode() || !self->_hovered || + self->_scroll_limit_reached || self->GetActionState() == ACTION_DRAG_LAUNCHER) - return TRUE; - - if (self->MouseOverTopScrollArea()) + anim = FALSE; + else if (self->MouseOverTopScrollArea()) { if (self->MouseOverTopScrollExtrema()) self->_launcher_drag_delta += 6; @@ -1649,9 +1728,18 @@ else self->_launcher_drag_delta -= 3; } + else + anim = FALSE; - self->EnsureAnimation(); - return TRUE; + if (anim) + self->EnsureAnimation(); + else + { + self->_autoscroll_handle = 0; + self->_scroll_limit_reached = false; + } + + return anim; } void Launcher::EnsureScrollTimer() @@ -1690,18 +1778,9 @@ nux::Geometry new_geometry(geo.x, geo.y + panel_style.panel_height, width, geo.height - panel_style.panel_height); SetMaximumHeight(new_geometry.height); _parent->SetGeometry(new_geometry); - SetGeometry(new_geometry); - - _pointer_barrier->DestroyBarrier(); - - _pointer_barrier->x1 = new_geometry.x; - _pointer_barrier->x2 = new_geometry.x; - _pointer_barrier->y1 = new_geometry.y - panel_style.panel_height; - _pointer_barrier->y2 = new_geometry.y + new_geometry.height; - _pointer_barrier->threshold = options()->edge_stop_velocity(); - - _pointer_barrier->ConstructBarrier(); + SetGeometry(nux::Geometry(0, 0, new_geometry.width, new_geometry.height)); + ConfigureBarrier(); } void Launcher::OnIconAdded(AbstractLauncherIcon::Ptr icon) @@ -1853,7 +1932,7 @@ pressure_color); } - if (_dash_is_open) + if (IsOverlayOpen()) { if (BackgroundEffectHelper::blur_type != unity::BLUR_NONE && (bkg_box.x + bkg_box.width > 0)) { @@ -1869,12 +1948,30 @@ texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height; GfxContext.PushClippingRectangle(bkg_box); - gPainter.PushDrawTextureLayer(GfxContext, base, - blur_texture, - texxform_blur_bg, - nux::color::White, - true, - ROP); + +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath()) + gPainter.PushDrawCompositionLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + _background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, ROP); + else + gPainter.PushDrawTextureLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + true, + ROP); +#else + gPainter.PushDrawCompositionLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + _background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, ROP); +#endif GfxContext.PopClippingRectangle(); push_count++; @@ -1886,11 +1983,14 @@ // apply the darkening GfxContext.GetRenderStates().SetBlend(true, GL_ZERO, GL_SRC_COLOR); - gPainter.Paint2DQuadColor(GfxContext, bkg_box, nux::Color(0.7f, 0.7f, 0.7f, 1.0f)); + gPainter.Paint2DQuadColor(GfxContext, bkg_box, nux::Color(0.9f, 0.9f, 0.9f, 1.0f)); GfxContext.GetRenderStates().SetBlend (alpha, src, dest); // apply the bg colour - gPainter.Paint2DQuadColor(GfxContext, bkg_box, _background_color); +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath() == FALSE) + gPainter.Paint2DQuadColor(GfxContext, bkg_box, _background_color); +#endif // apply the shine GfxContext.GetRenderStates().SetBlend(true, GL_DST_COLOR, GL_ONE); @@ -1933,7 +2033,7 @@ icon_renderer->RenderIcon(GfxContext, *rev_it, bkg_box, base); } - if (!_dash_is_open) + if (!IsOverlayOpen()) { const double right_line_opacity = 0.15f * launcher_alpha; @@ -2013,7 +2113,7 @@ { nux::Geometry geo = GetAbsoluteGeometry(); AbstractLauncherIcon::Ptr drag_icon = MouseIconIntersection((int)(GetGeometry().width / 2.0f), y); - + x += geo.x; y += geo.y; @@ -2089,7 +2189,7 @@ { _model->Save(); - _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x), + _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x), (int)(_drag_icon->GetCenter(monitor).y)); _drag_window->StartAnimation(); @@ -2132,6 +2232,21 @@ } } +void Launcher::ResetMouseDragState() +{ + if (GetActionState() == ACTION_DRAG_ICON) + EndIconDrag(); + + if (GetActionState() == ACTION_DRAG_LAUNCHER) + _hide_machine->SetQuirk(LauncherHideMachine::VERTICAL_SLIDE_ACTIVE, false); + + SetActionState(ACTION_NONE); + _dnd_delta_x = 0; + _dnd_delta_y = 0; + _last_button_press = 0; + EnsureAnimation(); +} + void Launcher::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { _last_button_press = nux::GetEventButton(button_flags); @@ -2147,17 +2262,7 @@ nux::Geometry geo = GetGeometry(); MouseUpLogic(x, y, button_flags, key_flags); - - if (GetActionState() == ACTION_DRAG_ICON) - EndIconDrag(); - - if (GetActionState() == ACTION_DRAG_LAUNCHER) - _hide_machine->SetQuirk(LauncherHideMachine::VERTICAL_SLIDE_ACTIVE, false); - SetActionState(ACTION_NONE); - _dnd_delta_x = 0; - _dnd_delta_y = 0; - _last_button_press = 0; - EnsureAnimation(); + ResetMouseDragState(); } void Launcher::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) @@ -2303,7 +2408,7 @@ Window root_return, child_return; Display *dpy = nux::GetGraphicsDisplay()->GetX11Display(); - if (XQueryPointer (dpy, DefaultRootWindow(dpy), &root_return, &child_return, &root_x_return, + if (XQueryPointer (dpy, DefaultRootWindow(dpy), &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return)) { if (mask_return & (Button1Mask | Button3Mask)) @@ -2553,7 +2658,7 @@ _hide_machine->SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, true); - if (_dash_is_open) + if (IsOverlayOpen()) SaturateIcons(); for (auto it : _dnd_data.Uris()) @@ -2679,7 +2784,7 @@ SetMousePosition(x - parent->GetGeometry().x, y - parent->GetGeometry().y); - if (!_dash_is_open && _mouse_position.x == 0 && _mouse_position.y <= (_parent->GetGeometry().height - _icon_size - 2 * _space_between_icons) && !_drag_edge_touching) + if (!IsOverlayOpen() && _mouse_position.x == 0 && _mouse_position.y <= (_parent->GetGeometry().height - _icon_size - 2 * _space_between_icons) && !_drag_edge_touching) { if (_dnd_hovered_icon) _dnd_hovered_icon->SendDndLeave(); diff -Nru unity-5.6.0/plugins/unityshell/src/Launcher.h unity-5.8.0/plugins/unityshell/src/Launcher.h --- unity-5.6.0/plugins/unityshell/src/Launcher.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/Launcher.h 2012-03-23 11:53:16.000000000 +0000 @@ -166,6 +166,8 @@ TIME_LAST } LauncherActionTimes; + void ConfigureBarrier(); + void OnOptionsChanged(Options::Ptr options); void OnOptionChanged(); void UpdateOptions(Options::Ptr options); @@ -266,6 +268,7 @@ void OnOverlayHidden(GVariant* data); void OnOverlayShown(GVariant* data); + bool IsOverlayOpen() const; void DesaturateIcons(); void SaturateIcons(); @@ -288,6 +291,8 @@ void EndIconDrag(); void UpdateDragWindowPosition(int x, int y); + void ResetMouseDragState(); + float GetAutohidePositionMin() const; float GetAutohidePositionMax() const; @@ -313,6 +318,7 @@ bool _hovered; bool _hidden; + bool _scroll_limit_reached; bool _render_drag_window; bool _shortcuts_shown; @@ -322,8 +328,7 @@ float _folded_angle; float _neg_folded_angle; float _folded_z_distance; - float _launcher_top_y; - float _launcher_bottom_y; + float _last_delta_y; float _edge_overcome_pressure; LauncherActionState _launcher_action_state; @@ -355,6 +360,7 @@ guint _autoscroll_handle; guint _start_dragicon_handle; guint _dnd_check_handle; + guint _strut_hack_handle; nux::Point2 _mouse_position; nux::BaseWindow* _parent; @@ -403,6 +409,7 @@ BaseTexturePtr launcher_sheen_; BaseTexturePtr launcher_pressure_effect_; bool _dash_is_open; + bool _hud_is_open; ui::AbstractIconRenderer::Ptr icon_renderer; BackgroundEffectHelper bg_effect_helper_; diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherHideMachine.cpp unity-5.8.0/plugins/unityshell/src/LauncherHideMachine.cpp --- unity-5.6.0/plugins/unityshell/src/LauncherHideMachine.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherHideMachine.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -134,16 +134,16 @@ { bool should_hide; - // early check to see if we are locking to hidden - if (GetQuirk(LOCK_HIDE)) + if (_mode == HIDE_NEVER) { - SetShouldHide(true, true); + SetShouldHide(false, skip_delay); return; } - - if (_mode == HIDE_NEVER) + + // early check to see if we are locking to hidden - but only if we are in non HIDE_NEVER + if (GetQuirk(LOCK_HIDE)) { - SetShouldHide(false, skip_delay); + SetShouldHide(true, true); return; } diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherIcon.cpp unity-5.8.0/plugins/unityshell/src/LauncherIcon.cpp --- unity-5.6.0/plugins/unityshell/src/LauncherIcon.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -166,6 +166,15 @@ return _has_visible_window[monitor]; } +const bool LauncherIcon::WindowVisibleOnViewport() +{ + for (int i = 0; i < max_num_monitors; ++i) + if (_has_visible_window[i]) + return true; + + return false; +} + std::string LauncherIcon::GetName() const { @@ -181,7 +190,7 @@ .add("z", _center[0].z) .add("related-windows", (int)Windows().size()) .add("icon-type", _icon_type) - .add("tooltip-text", tooltip_text().c_str()) + .add("tooltip-text", tooltip_text()) .add("sort-priority", _sort_priority) .add("quirk-active", GetQuirk(QUIRK_ACTIVE)) .add("quirk-visible", GetQuirk(QUIRK_VISIBLE)) diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherIcon.h unity-5.8.0/plugins/unityshell/src/LauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/LauncherIcon.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -102,14 +102,18 @@ int SortPriority(); - virtual std::vector Windows () { return std::vector (); } + virtual std::vector Windows() { return std::vector (); } - virtual std::vector WindowsForMonitor (int monitor) { return std::vector (); } + virtual std::vector WindowsOnViewport() { return std::vector (); } - virtual std::string NameForWindow (Window window) { return std::string(); } + virtual std::vector WindowsForMonitor(int monitor) { return std::vector (); } + + virtual std::string NameForWindow(Window window) { return std::string(); } const bool WindowVisibleOnMonitor(int monitor); + const bool WindowVisibleOnViewport(); + virtual bool IsSpacer() { return false; diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherOptions.cpp unity-5.8.0/plugins/unityshell/src/LauncherOptions.cpp --- unity-5.6.0/plugins/unityshell/src/LauncherOptions.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherOptions.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -42,6 +42,8 @@ reveal_trigger = RevealTrigger::EDGE; tile_size = 54; urgent_animation = URGENT_ANIMATION_WIGGLE; + edge_resist = true; + show_for_all = false; auto_hide_animation.changed.connect ([&] (AutoHideAnimation value)-> void { option_changed.emit(); }); background_alpha.changed.connect ([&] (float value) -> void { option_changed.emit(); }); @@ -57,6 +59,7 @@ reveal_trigger.changed.connect ([&] (RevealTrigger vallue) -> void { option_changed.emit(); }); tile_size.changed.connect ([&] (int value) -> void { option_changed.emit(); }); urgent_animation.changed.connect ([&] (UrgentAnimation value) -> void { option_changed.emit(); }); + edge_resist.changed.connect ([&] (bool value) -> void { option_changed.emit(); }); } diff -Nru unity-5.6.0/plugins/unityshell/src/LauncherOptions.h unity-5.8.0/plugins/unityshell/src/LauncherOptions.h --- unity-5.6.0/plugins/unityshell/src/LauncherOptions.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LauncherOptions.h 2012-03-23 11:53:16.000000000 +0000 @@ -33,42 +33,42 @@ namespace launcher { -typedef enum +enum LauncherHideMode { LAUNCHER_HIDE_NEVER, LAUNCHER_HIDE_AUTOHIDE, -} LauncherHideMode; +}; -typedef enum +enum LaunchAnimation { LAUNCH_ANIMATION_NONE, LAUNCH_ANIMATION_PULSE, LAUNCH_ANIMATION_BLINK, -} LaunchAnimation; +}; -typedef enum +enum UrgentAnimation { URGENT_ANIMATION_NONE, URGENT_ANIMATION_PULSE, URGENT_ANIMATION_WIGGLE, -} UrgentAnimation; +}; -typedef enum +enum AutoHideAnimation { FADE_OR_SLIDE, SLIDE_ONLY, FADE_ONLY, FADE_AND_SLIDE, -} AutoHideAnimation; +}; -typedef enum +enum BacklightMode { BACKLIGHT_ALWAYS_ON, BACKLIGHT_NORMAL, BACKLIGHT_ALWAYS_OFF, BACKLIGHT_EDGE_TOGGLE, BACKLIGHT_NORMAL_EDGE_TOGGLE -} BacklightMode; +}; enum RevealTrigger { @@ -97,6 +97,8 @@ nux::Property edge_stop_velocity; nux::Property edge_reveal_pressure; nux::Property edge_responsiveness; + nux::Property edge_resist; + nux::Property show_for_all; sigc::signal option_changed; }; diff -Nru unity-5.6.0/plugins/unityshell/src/LensBar.cpp unity-5.8.0/plugins/unityshell/src/LensBar.cpp --- unity-5.6.0/plugins/unityshell/src/LensBar.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LensBar.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -17,6 +17,7 @@ */ #include +#include "config.h" #include "CairoTexture.h" #include "DashStyle.h" diff -Nru unity-5.6.0/plugins/unityshell/src/LensView.cpp unity-5.8.0/plugins/unityshell/src/LensView.cpp --- unity-5.6.0/plugins/unityshell/src/LensView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LensView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -18,6 +18,7 @@ */ #include "LensView.h" +#include "LensViewPrivate.h" #include @@ -30,16 +31,15 @@ #include "UBusWrapper.h" #include "PlacesVScrollBar.h" +#include + namespace unity { namespace dash { - namespace { nux::logging::Logger logger("unity.dash.lensview"); - -const int FSCROLL_VIEW_WIDTH_ADDER = 11; } // This is so we can access some protected members in scrollview. @@ -81,7 +81,7 @@ ScrollDown (1, size); } } - + void SetRightArea(nux::Area* area) { right_area_ = area; @@ -91,7 +91,7 @@ { up_area_ = area; } - + protected: // This is so we can break the natural key navigation path. @@ -120,6 +120,7 @@ , search_string("") , filters_expanded(false) , can_refine_search(false) + , no_results_active_(false) , fix_renderering_id_(0) {} @@ -130,6 +131,7 @@ , can_refine_search(false) , lens_(lens) , initial_activation_(true) + , no_results_active_(false) , fix_renderering_id_(0) { SetupViews(show_filters); @@ -158,7 +160,7 @@ auto expand_label = category->GetHeaderFocusableView(); auto child = category->GetChildView(); - if ((child && child->HasKeyFocus()) || + if ((child && child->HasKeyFocus()) || (expand_label && expand_label->HasKeyFocus())) { @@ -182,7 +184,10 @@ void LensView::SetupViews(nux::Area* show_filters) { + dash::Style& style = dash::Style::Instance(); + layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); + layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenLensAndFilters()); scroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION); @@ -194,8 +199,11 @@ scroll_view_->SetLayout(scroll_layout_); scroll_view_->SetRightArea(show_filters); - fscroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), - NUX_TRACKER_LOCATION); + no_results_ = new nux::StaticCairoText("", NUX_TRACKER_LOCATION); + no_results_->SetTextColor(nux::color::White); + scroll_layout_->AddView(no_results_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); + + fscroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION); fscroll_view_->EnableVerticalScrollBar(true); fscroll_view_->EnableHorizontalScrollBar(false); fscroll_view_->SetVisible(false); @@ -206,8 +214,16 @@ fscroll_view_->SetLayout(fscroll_layout_); filter_bar_ = new FilterBar(); + int width = style.GetFilterBarWidth() + + style.GetFilterBarLeftPadding() + + style.GetFilterBarRightPadding(); + + fscroll_view_->SetMinimumWidth(width + style.GetFilterViewRightPadding()); + fscroll_view_->SetMaximumWidth(width + style.GetFilterViewRightPadding()); + filter_bar_->SetMinimumWidth(width); + filter_bar_->SetMaximumWidth(width); AddChild(filter_bar_); - fscroll_layout_->AddView(filter_bar_); + fscroll_layout_->AddView(filter_bar_, 0); SetLayout(layout_); } @@ -345,23 +361,69 @@ gboolean LensView::FixRenderering(LensView* self) { std::list children = self->scroll_layout_->GetChildren(); - std::list::reverse_iterator rit; - bool found_one = false; + std::list groups; - for (rit = children.rbegin(); rit != children.rend(); ++rit) + for (auto child : children) { - PlacesGroup* group = static_cast(*rit); - - if (group->IsVisible()) - group->SetDrawSeparator(found_one); - - found_one = group->IsVisible(); + if (child == self->no_results_) + continue; + groups.push_back(static_cast(child)); } + dash::impl::UpdateDrawSeparators(groups); + self->fix_renderering_id_ = 0; return FALSE; } +void LensView::CheckNoResults(Lens::Hints const& hints) +{ + gint count = lens_->results()->count(); + + if (!count && !no_results_active_) + { + std::stringstream markup; + Lens::Hints::const_iterator it; + + it = hints.find("no-results-hint"); + markup << ""; + + if (it != hints.end()) + { + markup << it->second.GetString(); + } + else + { + markup << _("Sorry, there is nothing that matches your search."); + } + markup << ""; + + LOG_DEBUG(logger) << "The no-result-hint is: " << markup.str(); + + scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_CENTER); + + no_results_active_ = true; + no_results_->SetText(markup.str()); + } + else if (count && no_results_active_) + { + scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START); + + no_results_active_ = false; + no_results_->SetText(""); + } +} + +void LensView::HideResultsMessage() +{ + if (no_results_active_) + { + scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START); + no_results_active_ = false; + no_results_->SetText(""); + } +} + void LensView::OnGroupExpanded(PlacesGroup* group) { ResultViewGrid* grid = static_cast(group->GetChildView()); @@ -382,13 +444,7 @@ void LensView::OnFilterAdded(Filter::Ptr filter) { - std::string id = filter->id; filter_bar_->AddFilter(filter); - - int width = dash::Style::Instance().GetTileWidth(); - fscroll_view_->SetMinimumWidth(width * 2 + FSCROLL_VIEW_WIDTH_ADDER); - fscroll_view_->SetMaximumWidth(width * 2 + FSCROLL_VIEW_WIDTH_ADDER); - can_refine_search = true; } @@ -402,7 +458,7 @@ if (view_type != HIDDEN && initial_activation_) { /* We reset the lens for ourselves, in case this is a restart or something */ - lens_->Search(""); + lens_->Search(search_string); initial_activation_ = false; } @@ -421,9 +477,7 @@ void LensView::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw) { gfx_context.PushClippingRectangle(GetGeometry()); - layout_->ProcessDraw(gfx_context, force_draw); - gfx_context.PopClippingRectangle(); } @@ -459,6 +513,11 @@ return num_rows; } +void LensView::JumpToTop() +{ + scroll_view_->ScrollToPosition(nux::Geometry(0, 0, 0, 0)); +} + void LensView::ActivateFirst() { Results::Ptr results = lens_->results; @@ -503,7 +562,8 @@ { unity::variant::BuilderWrapper(builder) .add("name", lens_->id) - .add("lens-name", lens_->name); + .add("lens-name", lens_->name) + .add("no-results-active", no_results_active_); } diff -Nru unity-5.6.0/plugins/unityshell/src/LensView.h unity-5.8.0/plugins/unityshell/src/LensView.h --- unity-5.6.0/plugins/unityshell/src/LensView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LensView.h 2012-03-23 11:53:16.000000000 +0000 @@ -59,6 +59,7 @@ nux::Area* fscroll_view() const; int GetNumRows(); + void JumpToTop(); virtual void ActivateFirst(); @@ -69,6 +70,9 @@ sigc::signal uri_activated; + void CheckNoResults(Lens::Hints const& hints); + void HideResultsMessage(); + private: void SetupViews(nux::Area* show_filters); void SetupCategories(); @@ -101,6 +105,7 @@ CategoryGroups categories_; ResultCounts counts_; bool initial_activation_; + bool no_results_active_; nux::HLayout* layout_; LensScrollView* scroll_view_; @@ -108,6 +113,7 @@ LensScrollView* fscroll_view_; nux::VLayout* fscroll_layout_; FilterBar* filter_bar_; + nux::StaticCairoText* no_results_; guint fix_renderering_id_; diff -Nru unity-5.6.0/plugins/unityshell/src/LensViewPrivate.cpp unity-5.8.0/plugins/unityshell/src/LensViewPrivate.cpp --- unity-5.6.0/plugins/unityshell/src/LensViewPrivate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LensViewPrivate.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Andrea Azzarone + */ + +#include "LensViewPrivate.h" +#include "AbstractPlacesGroup.h" + +namespace unity +{ +namespace dash +{ +namespace impl +{ + +void UpdateDrawSeparators(std::list groups) +{ + std::list::reverse_iterator rit; + bool found_one = false; + + for (rit = groups.rbegin(); rit != groups.rend(); ++rit) + { + if ((*rit)->IsVisible()) + { + (*rit)->draw_separator = found_one; + found_one = true; + } + } +} + +} +} +} + + diff -Nru unity-5.6.0/plugins/unityshell/src/LensViewPrivate.h unity-5.8.0/plugins/unityshell/src/LensViewPrivate.h --- unity-5.6.0/plugins/unityshell/src/LensViewPrivate.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LensViewPrivate.h 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Andrea Azzarone + */ + +#ifndef UNITYSHELL_LENS_VIEW_PRIVATE_H +#define UNITYSHELL_LENS_VIEW_PRIVATE_H + +#include + +namespace unity +{ +namespace dash +{ + +class AbstractPlacesGroup; + +namespace impl +{ + +void UpdateDrawSeparators(std::list groups); + +} // namespace impl +} // namespace dash +} // namespace unity + +#endif diff -Nru unity-5.6.0/plugins/unityshell/src/LineSeparator.cpp unity-5.8.0/plugins/unityshell/src/LineSeparator.cpp --- unity-5.6.0/plugins/unityshell/src/LineSeparator.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LineSeparator.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -23,7 +23,7 @@ namespace unity { - + HSeparator::HSeparator() { SetMinimumHeight(1); @@ -43,31 +43,28 @@ void HSeparator::Draw(nux::GraphicsEngine &GfxContext, bool force_draw) { - nux::Geometry base = GetGeometry(); - base.OffsetPosition(3, 0); - base.OffsetSize(-6, 0); + nux::Geometry const& base = GetGeometry(); int y0 = base.y + base.GetHeight() / 2; - nux::GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend(TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + unsigned int alpha = 0, src = 0, dest = 0; + GfxContext.GetRenderStates().GetBlend(alpha, src, dest); + nux::GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (base.GetWidth() - 2 * border_size_ > 0) { - nux::Color color0 = color_; - nux::Color color1 = color_; - color0.alpha = alpha0_; - color1.alpha = alpha1_; + nux::Color color0 = color_ * alpha0_; + nux::Color color1 = color_ * alpha1_; nux::GetPainter().Draw2DLine(GfxContext, base.x, y0, base.x + border_size_, y0, color0, color1); nux::GetPainter().Draw2DLine(GfxContext, base.x + border_size_, y0, base.x + base.GetWidth() - border_size_, y0, color1, color1); nux::GetPainter().Draw2DLine(GfxContext, base.x + base.GetWidth() - border_size_, y0, base.x + base.GetWidth(), y0, color1, color0); } else { - nux::Color color1 = color_; - color1.alpha = alpha1_; + nux::Color color1 = color_ * alpha1_; nux::GetPainter().Draw2DLine(GfxContext, base.x, y0, base.x + base.GetWidth(), y0, color1, color1); } - nux::GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend(FALSE); + GfxContext.GetRenderStates().SetBlend(alpha, src, dest); } } // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/src/LineSeparator.h unity-5.8.0/plugins/unityshell/src/LineSeparator.h --- unity-5.6.0/plugins/unityshell/src/LineSeparator.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/LineSeparator.h 2012-03-23 11:53:16.000000000 +0000 @@ -34,6 +34,7 @@ ~HSeparator(); protected: + virtual bool AcceptKeyNavFocus() { return false; } virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) {}; diff -Nru unity-5.6.0/plugins/unityshell/src/MockLauncherIcon.h unity-5.8.0/plugins/unityshell/src/MockLauncherIcon.h --- unity-5.6.0/plugins/unityshell/src/MockLauncherIcon.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/MockLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 @@ -81,6 +81,22 @@ return result; } + std::vector WindowsOnViewport () + { + std::vector result; + + result.push_back ((100 << 16) + 200); + result.push_back ((500 << 16) + 200); + result.push_back ((300 << 16) + 200); + result.push_back ((200 << 16) + 200); + result.push_back ((300 << 16) + 200); + result.push_back ((100 << 16) + 200); + result.push_back ((300 << 16) + 200); + result.push_back ((600 << 16) + 200); + + return result; + } + std::vector WindowsForMonitor (int monitor) { std::vector result; @@ -137,6 +153,11 @@ return 7; } + const bool WindowVisibleOnViewport() + { + return false; + } + const bool WindowVisibleOnMonitor(int monitor) { return false; diff -Nru unity-5.6.0/plugins/unityshell/src/MockShortcutHint.h unity-5.8.0/plugins/unityshell/src/MockShortcutHint.h --- unity-5.6.0/plugins/unityshell/src/MockShortcutHint.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/MockShortcutHint.h 2012-03-23 11:53:16.000000000 +0000 @@ -52,6 +52,7 @@ { case COMPIZ_MOUSE_OPTION: case COMPIZ_KEY_OPTION: + case COMPIZ_METAKEY_OPTION: value = arg1() + "-" + arg2(); shortkey = prefix() + value() + postfix(); return true; diff -Nru unity-5.6.0/plugins/unityshell/src/OverlayRenderer.cpp unity-5.8.0/plugins/unityshell/src/OverlayRenderer.cpp --- unity-5.6.0/plugins/unityshell/src/OverlayRenderer.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/OverlayRenderer.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -31,7 +31,7 @@ #include "UBusMessages.h" #include "UBusWrapper.h" -namespace unity +namespace unity { namespace { @@ -46,29 +46,29 @@ public: OverlayRendererImpl(OverlayRenderer *parent_); ~OverlayRendererImpl(); - + void Init(); void OnBackgroundColorChanged(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); void DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry); - + BackgroundEffectHelper bg_effect_helper_; nux::ColorLayer* bg_layer_; nux::ColorLayer* bg_darken_layer_; nux::Color bg_color_; - + nux::Geometry content_geo; nux::ObjectPtr bg_blur_texture_; nux::ObjectPtr bg_shine_texture_; - + // temporary variable that stores the number of backgrounds we have rendered int bgs; bool visible; - + UBusManager ubus_manager_; - + OverlayRenderer *parent; }; @@ -93,16 +93,16 @@ rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; bg_layer_ = new nux::ColorLayer(nux::Color(0.0f, 0.0f, 0.0f, 0.9), true, rop); - + rop.Blend = true; rop.SrcBlend = GL_ZERO; rop.DstBlend = GL_SRC_COLOR; - bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.7f, 0.7f, 0.7f, 1.0f), false, rop); + bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.9f, 0.9f, 0.9f, 1.0f), false, rop); bg_shine_texture_ = unity::dash::Style::Instance().GetDashShine()->GetDeviceTexture(); - + ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &OverlayRendererImpl::OnBackgroundColorChanged)); - + ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT); } @@ -114,14 +114,14 @@ nux::Color color = nux::Color(red, green, blue, alpha); bg_layer_->SetColor(color); bg_color_ = color; - + parent->need_redraw.emit(); } void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_edges) { bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE; - nux::Geometry geo = content_geo; + nux::Geometry geo(content_geo); if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges) { @@ -242,46 +242,63 @@ } } } - - + + nux::TexCoordXForm texxform_absolute_bg; texxform_absolute_bg.flip_v_coord = true; texxform_absolute_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform_absolute_bg.uoffset = ((float) content_geo.x) / absolute_geo.width; texxform_absolute_bg.voffset = ((float) content_geo.y) / absolute_geo.height; texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); - + if (paint_blur) { nux::Geometry blur_geo(absolute_geo.x, absolute_geo.y, content_geo.width, content_geo.height); bg_blur_texture_ = bg_effect_helper_.GetBlurRegion(blur_geo); - + if (bg_blur_texture_.IsValid()) { nux::Geometry bg_clip = geo; gfx_context.PushClippingRectangle(bg_clip); - + gfx_context.GetRenderStates().SetBlend(false); - gfx_context.QRP_1Tex (content_geo.x, content_geo.y, - content_geo.width, content_geo.height, - bg_blur_texture_, texxform_absolute_bg, nux::color::White); +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath()) + gfx_context.QRP_GLSL_ColorBlendOverTex (content_geo.x, content_geo.y, + content_geo.width, content_geo.height, + bg_blur_texture_, texxform_absolute_bg, nux::color::White, + bg_color_, nux::LAYER_BLEND_MODE_OVERLAY); + + else + gfx_context.QRP_1Tex (content_geo.x, content_geo.y, + content_geo.width, content_geo.height, + bg_blur_texture_, texxform_absolute_bg, nux::color::White); +#else + gfx_context.QRP_GLSL_ColorBlendOverTex (content_geo.x, content_geo.y, + content_geo.width, content_geo.height, + bg_blur_texture_, texxform_absolute_bg, nux::color::White, + bg_color_, nux::LAYER_BLEND_MODE_OVERLAY); + +#endif gPainter.PopBackground(); - + gfx_context.PopClippingRectangle(); } } // Draw the left and top lines + dash::Style& style = dash::Style::Instance(); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); gfx_context.GetRenderStates().SetBlend(true); gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - const double line_opacity = 0.22; + const double line_opacity = 0.22f; nux::Color line_color = nux::color::White * line_opacity; nux::GetPainter().Paint2DQuadColor(gfx_context, nux::Geometry(geometry.x, geometry.y, - 1, + style.GetVSeparatorSize(), content_geo.height + INNER_CORNER_RADIUS), nux::color::Transparent, line_color, @@ -292,31 +309,36 @@ nux::Geometry(geometry.x, geometry.y, content_geo.width + INNER_CORNER_RADIUS, - 1), + style.GetHSeparatorSize()), nux::color::Transparent, nux::color::Transparent, line_color, line_color); - + // Draw the background bg_darken_layer_->SetGeometry(content_geo); nux::GetPainter().RenderSinglePaintLayer(gfx_context, content_geo, bg_darken_layer_); - - bg_layer_->SetGeometry(content_geo); - nux::GetPainter().RenderSinglePaintLayer(gfx_context, content_geo, bg_layer_); - - + +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath() == FALSE) + { + bg_layer_->SetGeometry(content_geo); + nux::GetPainter().RenderSinglePaintLayer(gfx_context, content_geo, bg_layer_); + } +#endif + + texxform_absolute_bg.flip_v_coord = false; texxform_absolute_bg.uoffset = (1.0f / bg_shine_texture_->GetWidth()) * parent->x_offset; texxform_absolute_bg.voffset = (1.0f / bg_shine_texture_->GetHeight()) * parent->y_offset; - + gfx_context.GetRenderStates().SetColorMask(true, true, true, false); gfx_context.GetRenderStates().SetBlend(true, GL_DST_COLOR, GL_ONE); - + gfx_context.QRP_1Tex (content_geo.x, content_geo.y, content_geo.width, content_geo.height, bg_shine_texture_, texxform_absolute_bg, nux::color::White); - + if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) { // Make bottom-right corner rounded @@ -343,7 +365,7 @@ { nux::Geometry fill_geo (geo.x + geo.width, geo.y + i, INNER_CORNER_RADIUS - i, 1); nux::GetPainter().Paint2DQuadColor(gfx_context, fill_geo, bg_color_); - + nux::Color dark = bg_color_ * 0.8f; dark.alpha = bg_color_.alpha; fill_geo = nux::Geometry(geo.x + i, geo.y + geo.height, 1, INNER_CORNER_RADIUS - i); @@ -357,42 +379,64 @@ bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE; nux::Geometry geo = geometry; bgs = 0; - + gfx_context.PushClippingRectangle(geo); - + gfx_context.GetRenderStates().SetBlend(true); gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - + nux::TexCoordXForm texxform_absolute_bg; texxform_absolute_bg.flip_v_coord = true; texxform_absolute_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform_absolute_bg.uoffset = ((float) content_geo.x) / absolute_geo.width; texxform_absolute_bg.voffset = ((float) content_geo.y) / absolute_geo.height; texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); - + nux::ROPConfig rop; rop.Blend = false; rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - + if (bg_blur_texture_.IsValid() && paint_blur) { - gPainter.PushTextureLayer(gfx_context, content_geo, - bg_blur_texture_, - texxform_absolute_bg, - nux::color::White, - true, // write alpha? - rop); +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath()) + gPainter.PushCompositionLayer(gfx_context, content_geo, + bg_blur_texture_, + texxform_absolute_bg, + nux::color::White, + bg_color_, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); + else + gPainter.PushTextureLayer(gfx_context, content_geo, + bg_blur_texture_, + texxform_absolute_bg, + nux::color::White, + true, // write alpha? + rop); +#else + gPainter.PushCompositionLayer(gfx_context, content_geo, + bg_blur_texture_, + texxform_absolute_bg, + nux::color::White, + bg_color_, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); +#endif bgs++; } - + // draw the darkening behind our paint nux::GetPainter().PushLayer(gfx_context, bg_darken_layer_->GetGeometry(), bg_darken_layer_); bgs++; - - nux::GetPainter().PushLayer(gfx_context, bg_layer_->GetGeometry(), bg_layer_); - bgs++; - + +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath() == FALSE) + { + nux::GetPainter().PushLayer(gfx_context, bg_layer_->GetGeometry(), bg_layer_); + bgs++; + } +#endif + // apply the shine rop.Blend = true; rop.SrcBlend = GL_DST_COLOR; @@ -400,8 +444,8 @@ texxform_absolute_bg.flip_v_coord = false; texxform_absolute_bg.uoffset = (1.0f / bg_shine_texture_->GetWidth()) * parent->x_offset; texxform_absolute_bg.voffset = (1.0f / bg_shine_texture_->GetHeight()) * parent->y_offset; - - nux::GetPainter().PushTextureLayer(gfx_context, bg_layer_->GetGeometry(), + + nux::GetPainter().PushTextureLayer(gfx_context, content_geo, bg_shine_texture_, texxform_absolute_bg, nux::color::White, @@ -413,10 +457,10 @@ void OverlayRendererImpl::DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry) { nux::GetPainter().PopBackground(bgs); - + gfx_context.GetRenderStates().SetBlend(false); gfx_context.PopClippingRectangle(); - + if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) { // Make bottom-right corner rounded @@ -432,16 +476,16 @@ true, rop); } - + bgs = 0; } - + OverlayRenderer::OverlayRenderer() : pimpl_(new OverlayRendererImpl(this)) { - + } @@ -478,18 +522,27 @@ void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges) { pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo, force_edges); + LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): content_geo: " << content_geo.width << "/" << content_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): geo: " << geo.width << "/" << geo.height; } void OverlayRenderer::DrawInner(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo) { pimpl_->DrawContent(gfx_context, content_geo, absolute_geo, geo); + LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): content_geo: " << content_geo.width << "/" << content_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): geo: " << geo.width << "/" << geo.height; } void OverlayRenderer::DrawInnerCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo) { pimpl_->DrawContentCleanup(gfx_context, content_geo, absolute_geo, geo); + LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): content_geo: " << content_geo.width << "/" << content_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height; + LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): geo: " << geo.width << "/" << geo.height; } - + } diff -Nru unity-5.6.0/plugins/unityshell/src/PanelController.cpp unity-5.8.0/plugins/unityshell/src/PanelController.cpp --- unity-5.6.0/plugins/unityshell/src/PanelController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -43,8 +43,7 @@ Impl(); ~Impl(); - void StartFirstMenuShow(); - void EndFirstMenuShow(); + void FirstMenuShow(); void QueueRedraw(); unsigned int GetTrayXid(); @@ -72,7 +71,6 @@ std::vector windows_; float opacity_; bool opacity_maximized_toggle_; - bool open_menu_start_received_; int menus_fadein_; int menus_fadeout_; int menus_discovery_; @@ -84,7 +82,6 @@ Controller::Impl::Impl() : opacity_(1.0f) , opacity_maximized_toggle_(false) - , open_menu_start_received_(false) , menus_fadein_(0) , menus_fadeout_(0) , menus_discovery_(0) @@ -121,27 +118,12 @@ return geometries; } -void Controller::Impl::StartFirstMenuShow() +void Controller::Impl::FirstMenuShow() { for (auto window: windows_) { - PanelView* view = ViewForWindow(window); - view->StartFirstMenuShow(); - } - - open_menu_start_received_ = true; -} - -void Controller::Impl::EndFirstMenuShow() -{ - if (!open_menu_start_received_) - return; - open_menu_start_received_ = false; - - for (auto window: windows_) - { - PanelView* view = ViewForWindow(window); - view->EndFirstMenuShow(); + if (ViewForWindow(window)->FirstMenuShow()) + break; } } @@ -317,14 +299,9 @@ delete pimpl; } -void Controller::StartFirstMenuShow() -{ - pimpl->StartFirstMenuShow(); -} - -void Controller::EndFirstMenuShow() +void Controller::FirstMenuShow() { - pimpl->EndFirstMenuShow(); + pimpl->FirstMenuShow(); } void Controller::SetOpacity(float opacity) diff -Nru unity-5.6.0/plugins/unityshell/src/PanelController.h unity-5.8.0/plugins/unityshell/src/PanelController.h --- unity-5.6.0/plugins/unityshell/src/PanelController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelController.h 2012-03-23 11:53:16.000000000 +0000 @@ -39,8 +39,7 @@ Controller(); ~Controller(); - void StartFirstMenuShow(); - void EndFirstMenuShow(); + void FirstMenuShow(); void QueueRedraw(); unsigned int GetTrayXid (); diff -Nru unity-5.6.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp --- unity-5.6.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -110,8 +110,8 @@ { proxy_->ShowMenu(GetAbsoluteX(), GetAbsoluteY() + PANEL_HEIGHT, - time(NULL), - button); + button, + time(NULL)); } void PanelIndicatorEntryView::OnMouseDown(int x, int y, long button_flags, long key_flags) @@ -193,6 +193,14 @@ // 3. Paint something void PanelIndicatorEntryView::Refresh() { + if (!IsVisible()) + { + SetVisible(false); + return; + } + + SetVisible(true); + PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoAttrList* attrs = NULL; @@ -472,10 +480,7 @@ std::string PanelIndicatorEntryView::GetName() const { - if (proxy_->IsUnused()) - return ""; - else - return proxy_->id().c_str(); + return proxy_->id(); } void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder) @@ -498,7 +503,7 @@ void PanelIndicatorEntryView::GetGeometryForSync(indicator::EntryLocationMap& locations) { - if (proxy_->IsUnused()) + if (!IsVisible()) return; locations[proxy_->id()] = GetAbsoluteGeometry(); @@ -546,6 +551,15 @@ return (disabled_ || !proxy_.get() || !IsSensitive()); } +bool PanelIndicatorEntryView::IsVisible() +{ + if (proxy_.get()) + { + return proxy_->visible(); + } + return false; +} + void PanelIndicatorEntryView::OnFontChanged(GObject* gobject, GParamSpec* pspec, gpointer data) { diff -Nru unity-5.6.0/plugins/unityshell/src/PanelIndicatorEntryView.h unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.h --- unity-5.6.0/plugins/unityshell/src/PanelIndicatorEntryView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.h 2012-03-23 11:53:16.000000000 +0000 @@ -60,6 +60,7 @@ bool IsEntryValid() const; bool IsSensitive() const; bool IsActive() const; + bool IsVisible(); int GetEntryPriority() const; void DashShown(); diff -Nru unity-5.6.0/plugins/unityshell/src/PanelIndicatorsView.cpp unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.cpp --- unity-5.6.0/plugins/unityshell/src/PanelIndicatorsView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -180,7 +180,7 @@ { PanelIndicatorEntryView* view = entry.second; - if (!target && view->GetAbsoluteGeometry().IsPointInside(x, y)) + if (!target && view->IsVisible() && view->GetAbsoluteGeometry().IsPointInside(x, y)) { view->Activate(0); target = view; diff -Nru unity-5.6.0/plugins/unityshell/src/PanelIndicatorsView.h unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.h --- unity-5.6.0/plugins/unityshell/src/PanelIndicatorsView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.h 2012-03-23 11:53:16.000000000 +0000 @@ -83,7 +83,7 @@ Entries entries_; std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void AddProperties(GVariantBuilder* builder); private: typedef std::vector Indicators; diff -Nru unity-5.6.0/plugins/unityshell/src/PanelMenuView.cpp unity-5.8.0/plugins/unityshell/src/PanelMenuView.cpp --- unity-5.6.0/plugins/unityshell/src/PanelMenuView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelMenuView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -124,7 +124,6 @@ _panel_titlebar_grab_area = new PanelTitlebarGrabArea(); _panel_titlebar_grab_area->SetParentObject(this); - _panel_titlebar_grab_area->SinkReference(); _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseClicked)); _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseMiddleClicked)); _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart)); diff -Nru unity-5.6.0/plugins/unityshell/src/PanelView.cpp unity-5.8.0/plugins/unityshell/src/PanelView.cpp --- unity-5.6.0/plugins/unityshell/src/PanelView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -61,7 +61,7 @@ _opacity_maximized_toggle(false), _is_primary(false), _monitor(0), - _dash_is_open(false) + _overlay_is_open(false) { _needs_geo_sync = false; panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelView::ForceUpdateBackground)); @@ -72,7 +72,7 @@ rop.Blend = true; rop.SrcBlend = GL_ZERO; rop.DstBlend = GL_SRC_COLOR; - _bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.7f, 0.7f, 0.7f, 1.0f), false, rop); + _bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.9f, 0.9f, 0.9f, 1.0f), false, rop); _layout = new nux::HLayout("", NUX_TRACKER_LOCATION); @@ -173,11 +173,22 @@ void PanelView::OnDashHidden(GVariant* data, PanelView* self) { - if (self->_opacity >= 1.0f) - self->bg_effect_helper_.enabled = false; - self->_dash_is_open = false; - self->_indicators->DashHidden(); - self->ForceUpdateBackground(); + unity::glib::String overlay_identity; + gboolean can_maximise = FALSE; + gint32 overlay_monitor = 0; + g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, + &overlay_identity, &can_maximise, &overlay_monitor); + + if (self->_monitor == overlay_monitor && + overlay_identity.Str() == self->_active_overlay) + { + if (self->_opacity >= 1.0f) + self->bg_effect_helper_.enabled = false; + self->_overlay_is_open = false; + self->_active_overlay = ""; + self->_indicators->DashHidden(); + self->ForceUpdateBackground(); + } } void PanelView::OnDashShown(GVariant* data, PanelView* self) @@ -185,13 +196,14 @@ unity::glib::String overlay_identity; gboolean can_maximise = FALSE; gint32 overlay_monitor = 0; - g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, + g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); if (self->_monitor == overlay_monitor) { self->bg_effect_helper_.enabled = true; - self->_dash_is_open = true; + self->_overlay_is_open = true; + self->_active_overlay = overlay_identity.Str(); self->_indicators->DashShown(); self->ForceUpdateBackground(); } @@ -215,9 +227,6 @@ { variant::BuilderWrapper(builder) .add("backend", "remote") - .add("service-name", _remote->name()) - .add("service-unique-name", _remote->owner_name()) - .add("using-local-service", _remote->using_local_service()) .add(GetGeometry()); } @@ -230,12 +239,12 @@ GfxContext.PushClippingRectangle(GetGeometry()); - if (BackgroundEffectHelper::blur_type != BLUR_NONE && (_dash_is_open || (_opacity != 1.0f && _opacity != 0.0f))) + if (BackgroundEffectHelper::blur_type != BLUR_NONE && (_overlay_is_open || (_opacity != 1.0f && _opacity != 0.0f))) { nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, geo.width, geo.height); bg_blur_texture_ = bg_effect_helper_.GetBlurRegion(blur_geo); - if (bg_blur_texture_.IsValid() && BackgroundEffectHelper::blur_type != BLUR_NONE && (_dash_is_open || _opacity != 1.0f)) + if (bg_blur_texture_.IsValid() && BackgroundEffectHelper::blur_type != BLUR_NONE && (_overlay_is_open || _opacity != 1.0f)) { nux::TexCoordXForm texxform_blur_bg; texxform_blur_bg.flip_v_coord = true; @@ -251,17 +260,36 @@ nux::Geometry bg_clip = geo; GfxContext.PushClippingRectangle(bg_clip); - gPainter.PushDrawTextureLayer(GfxContext, geo, - bg_blur_texture_, - texxform_blur_bg, - nux::color::White, - true, - rop); +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath()) + gPainter.PushDrawCompositionLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + _bg_color, + nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); + else + gPainter.PushDrawTextureLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + true, + rop); +#else + gPainter.PushDrawCompositionLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + _bg_color, + nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); +#endif GfxContext.PopClippingRectangle(); } - if (_dash_is_open) + if (_overlay_is_open) { nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_darken_layer_); } @@ -269,7 +297,8 @@ - nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_layer); + if (_overlay_is_open == false) + nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_layer); GfxContext.PopClippingRectangle(); @@ -291,7 +320,7 @@ GfxContext.GetRenderStates().SetBlend(true); GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - if (bg_blur_texture_.IsValid() && BackgroundEffectHelper::blur_type != BLUR_NONE && (_dash_is_open || (_opacity != 1.0f && _opacity != 0.0f))) + if (bg_blur_texture_.IsValid() && BackgroundEffectHelper::blur_type != BLUR_NONE && (_overlay_is_open || (_opacity != 1.0f && _opacity != 0.0f))) { nux::Geometry geo_absolute = GetAbsoluteGeometry (); nux::TexCoordXForm texxform_blur_bg; @@ -305,23 +334,47 @@ rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - gPainter.PushTextureLayer(GfxContext, geo, - bg_blur_texture_, - texxform_blur_bg, - nux::color::White, - true, - rop); +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath()) + gPainter.PushCompositionLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + _bg_color, + nux::LAYER_BLEND_MODE_OVERLAY, + true, + rop); + else + gPainter.PushTextureLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + true, + rop); + +#else + gPainter.PushCompositionLayer(GfxContext, geo, + bg_blur_texture_, + texxform_blur_bg, + nux::color::White, + _bg_color, + nux::LAYER_BLEND_MODE_OVERLAY, + true, + rop); +#endif bgs++; - if (_dash_is_open) + if (_overlay_is_open) { nux::GetPainter().PushLayer(GfxContext, GetGeometry(), _bg_darken_layer_); + bgs++; } } - gPainter.PushLayer(GfxContext, GetGeometry(), _bg_layer); + if (_overlay_is_open == FALSE) + gPainter.PushLayer(GfxContext, GetGeometry(), _bg_layer); - if (_dash_is_open) + if (_overlay_is_open) { // apply the shine nux::TexCoordXForm texxform; @@ -373,7 +426,7 @@ guint32 maximized_win = _menu_view->GetMaximizedWindow(); - if (_dash_is_open) + if (_overlay_is_open) { if (_bg_layer) delete _bg_layer; @@ -439,7 +492,7 @@ { // Appmenu is treated differently as it needs to expand // We could do this in a more special way, but who has the time for special? - if (proxy->name().find("appmenu") != std::string::npos) + if (proxy->IsAppmenu()) { _menu_view->AddIndicator(proxy); } @@ -456,7 +509,7 @@ void PanelView::OnObjectRemoved(indicator::Indicator::Ptr const& proxy) { - if (proxy->name().find("appmenu") != std::string::npos) + if (proxy->IsAppmenu()) { _menu_view->RemoveIndicator(proxy); } @@ -525,7 +578,7 @@ return TRUE; } -void PanelView::OnEntryActivated(std::string const& entry_id) +void PanelView::OnEntryActivated(std::string const& entry_id, nux::Rect const& geo) { bool active = (entry_id.size() > 0); if (active && !_track_menu_pointer_id) @@ -561,8 +614,9 @@ _needs_geo_sync = true; } -void PanelView::OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button) +void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp) { Display* d = nux::GetGraphicsDisplay()->GetX11Display(); XUngrabPointer(d, CurrentTime); @@ -595,18 +649,17 @@ // // Useful Public Methods // -void PanelView::StartFirstMenuShow() +bool PanelView::FirstMenuShow() { -} + bool ret = false; -void PanelView::EndFirstMenuShow() -{ if (!_menu_view->GetControlsActive()) - return; + return ret; - bool ret; ret = _menu_view->ActivateIfSensitive(); if (!ret) _indicators->ActivateIfSensitive(); + + return ret; } void @@ -617,7 +670,7 @@ _opacity = opacity; - bg_effect_helper_.enabled = (_opacity < 1.0f || _dash_is_open); + bg_effect_helper_.enabled = (_opacity < 1.0f || _overlay_is_open); ForceUpdateBackground(); } diff -Nru unity-5.6.0/plugins/unityshell/src/PanelView.h unity-5.8.0/plugins/unityshell/src/PanelView.h --- unity-5.6.0/plugins/unityshell/src/PanelView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PanelView.h 2012-03-23 11:53:16.000000000 +0000 @@ -57,17 +57,16 @@ void OnIndicatorViewUpdated(PanelIndicatorEntryView* view); void OnMenuPointerMoved(int x, int y); void OnEntryActivateRequest(std::string const& entry_id); - void OnEntryActivated(std::string const& entry_id); + void OnEntryActivated(std::string const& entry_id, nux::Rect const& geo); void OnSynced(); - void OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button); + void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, int x, int y, + unsigned int button, unsigned int timestamp); void SetPrimary(bool primary); bool GetPrimary(); void SetMonitor(int monitor); - void StartFirstMenuShow(); - void EndFirstMenuShow(); + bool FirstMenuShow(); void SetOpacity(float opacity); void SetOpacityMaximizedToggle(bool enabled); @@ -117,7 +116,8 @@ bool _is_primary; int _monitor; - bool _dash_is_open; + bool _overlay_is_open; + std::string _active_overlay; guint _handle_dash_hidden; guint _handle_dash_shown; guint _handle_bg_color_update; diff -Nru unity-5.6.0/plugins/unityshell/src/PlacesGroup.cpp unity-5.8.0/plugins/unityshell/src/PlacesGroup.cpp --- unity-5.6.0/plugins/unityshell/src/PlacesGroup.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PlacesGroup.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -41,28 +42,32 @@ #include #include #include "DashStyle.h" +#include "LineSeparator.h" #include "ubus-server.h" #include "UBusMessages.h" - #include "Introspectable.h" + + +namespace +{ +nux::logging::Logger logger("unity.dash.placesgroup"); +} namespace unity { namespace { -const nux::Color kExpandDefaultTextColor(1.0f, 1.0f, 1.0f, 1.0f); -const nux::Color kExpandHoverTextColor(1.0f, 1.0f, 1.0f, 1.0f); -const float kExpandDefaultIconOpacity = 1.0f; -const float kExpandHoverIconOpacity = 1.0f; +const nux::Color kExpandDefaultTextColor(1.0f, 1.0f, 1.0f, 0.5f); +const float kExpandDefaultIconOpacity = 0.5f; // Category highlight const int kHighlightHeight = 24; -const int kHighlightWidthSubtractor = 16; -const int kHighlightLeftPadding = 11; +const int kHighlightRightPadding = 10 - 3; // -3 because the scrollbar is not a real overlay scrollbar! +const int kHighlightLeftPadding = 10; -// Line Separator -const int kSeparatorLeftPadding = 16; -const int kSeparatorWidthSubtractor = 10; +// Font +const char* const NAME_LABEL_FONT = "Ubuntu 13"; // 17px = 13 +const char* const EXPANDER_LABEL_FONT = "Ubuntu 10"; // 13px = 10 class HeaderView : public nux::View { @@ -106,32 +111,34 @@ NUX_IMPLEMENT_OBJECT_TYPE(PlacesGroup); PlacesGroup::PlacesGroup() - : View(NUX_TRACKER_LOCATION), + : AbstractPlacesGroup(), _child_view(nullptr), _focus_layer(nullptr), _idle_id(0), _is_expanded(true), _n_visible_items_in_unexpand_mode(0), - _n_total_items(0), - _draw_sep(true) + _n_total_items(0) { + dash::Style& style = dash::Style::Instance(); + SetAcceptKeyNavFocusOnMouseDown(false); SetAcceptKeyNavFocusOnMouseEnter(false); - nux::BaseTexture* arrow = dash::Style::Instance().GetGroupUnexpandIcon(); + nux::BaseTexture* arrow = style.GetGroupUnexpandIcon(); _cached_name = NULL; _group_layout = new nux::VLayout("", NUX_TRACKER_LOCATION); - _group_layout->SetHorizontalExternalMargin(20); - _group_layout->SetVerticalExternalMargin(1); - _group_layout->AddLayout(new nux::SpaceLayout(15,15,15,15), 0); + // -2 because the icons have an useless border. + int top_space = style.GetPlacesGroupTopSpace() - 2; + _group_layout->AddLayout(new nux::SpaceLayout(top_space, top_space, top_space, top_space), 0); _header_view = new HeaderView(NUX_TRACKER_LOCATION); _group_layout->AddView(_header_view, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FIX); _header_layout = new nux::HLayout(NUX_TRACKER_LOCATION); - _header_layout->SetHorizontalInternalMargin(10); + _header_layout->SetLeftAndRightPadding(style.GetCategoryHeaderLeftPadding(), 0); + _header_layout->SetSpaceBetweenChildren(10); _header_view->SetLayout(_header_layout); _icon = new IconTexture("", 24); @@ -143,6 +150,7 @@ _header_layout->AddLayout(_text_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); _name = new nux::StaticCairoText("", NUX_TRACKER_LOCATION); + _name->SetFont(NAME_LABEL_FONT); _name->SetTextEllipsize(nux::StaticCairoText::NUX_ELLIPSIZE_END); _name->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); _text_layout->AddView(_name, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); @@ -151,12 +159,15 @@ _expand_layout->SetHorizontalInternalMargin(8); _text_layout->AddLayout(_expand_layout, 0, nux::MINOR_POSITION_END, nux::MINOR_SIZE_MATCHCONTENT); + _expand_label_layout = new nux::HLayout(NUX_TRACKER_LOCATION); + _expand_layout->AddLayout(_expand_label_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); + _expand_label = new nux::StaticCairoText("", NUX_TRACKER_LOCATION); + _expand_label->SetFont(EXPANDER_LABEL_FONT); _expand_label->SetTextEllipsize(nux::StaticCairoText::NUX_ELLIPSIZE_END); _expand_label->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); _expand_label->SetTextColor(kExpandDefaultTextColor); - - _expand_layout->AddView(_expand_label, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); + _expand_label_layout->AddView(_expand_label, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); _expand_icon = new IconTexture(arrow, arrow->GetWidth(), arrow->GetHeight()); _expand_icon->SetOpacity(kExpandDefaultIconOpacity); @@ -164,6 +175,16 @@ _expand_icon->SetVisible(false); _expand_layout->AddView(_expand_icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); + separator_layout_ = new nux::HLayout(); + separator_layout_->SinkReference(); + separator_layout_->SetLeftAndRightPadding(style.GetCategorySeparatorLeftPadding(), + style.GetCategorySeparatorRightPadding() - style.GetScrollbarWidth()); + + separator_ = new HSeparator; + separator_layout_->AddView(separator_, 1); + + draw_separator.changed.connect(sigc::mem_fun(this, &PlacesGroup::DrawSeparatorChanged)); + SetLayout(_group_layout); // don't need to disconnect these signals as they are disconnected when this object destroys the contents @@ -195,9 +216,21 @@ if (_cached_name != NULL) g_free(_cached_name); + if (separator_layout_) + separator_layout_->UnReference(); + delete _focus_layer; } +void PlacesGroup::DrawSeparatorChanged(bool draw) +{ + if (draw and !separator_layout_->IsChildOf(_group_layout)) + _group_layout->AddView(separator_layout_, 0); + else if (!draw and separator_layout_->IsChildOf(_group_layout)) + _group_layout->RemoveChildObject(separator_layout_); + QueueDraw(); +} + void PlacesGroup::OnLabelActivated(nux::Area* label) { @@ -254,13 +287,26 @@ } void -PlacesGroup::SetChildView(nux::View* view) +PlacesGroup::SetChildView(dash::ResultView* view) { debug::Introspectable *i = dynamic_cast(view); if (i) AddChild(i); _child_view = view; - _group_layout->AddView(_child_view, 1); + + nux::VLayout* layout = new nux::VLayout(); + layout->AddView(_child_view, 0); + + layout->SetLeftAndRightPadding(25, 0); + _group_layout->AddLayout(new nux::SpaceLayout(8,8,8,8), 0); // top padding + _group_layout->AddLayout(layout, 1); + + view->results_per_row.changed.connect([&] (int results_per_row) + { + _n_visible_items_in_unexpand_mode = results_per_row; + RefreshLabel(); + }); + QueueDraw(); } @@ -279,9 +325,7 @@ void PlacesGroup::RefreshLabel() { - const char* temp = "%s"; char* result_string; - char* final; if (_n_visible_items_in_unexpand_mode >= _n_total_items) { @@ -293,6 +337,7 @@ } else { + LOG_DEBUG(logger) << _n_total_items << " - " << _n_visible_items_in_unexpand_mode; result_string = g_strdup_printf(g_dngettext(GETTEXT_PACKAGE, "See one more result", "See %d more results", @@ -306,15 +351,22 @@ SetName(tmpname); g_free(tmpname); - final = g_strdup_printf(temp, result_string); - _expand_label->SetText(final); + _expand_label->SetText(result_string); _expand_label->SetVisible(_n_visible_items_in_unexpand_mode < _n_total_items); + // See bug #748101 ("Dash - "See more..." line should be base-aligned with section header") + // We're making two assumptions here: + // [a] The font size _name is bigger than the font size of _expand_label + // [b] The bottom sides have the same y coordinate + int bottom_padding = _name->GetBaseHeight() - _name->GetBaseline() - + (_expand_label->GetBaseHeight() - _expand_label->GetBaseline()); + + _expand_label_layout->SetTopAndBottomPadding(0, bottom_padding); + QueueDraw(); - g_free((result_string)); - g_free(final); + g_free(result_string); } void @@ -360,7 +412,7 @@ if (_focus_layer) delete _focus_layer; - _focus_layer = dash::Style::Instance().FocusOverlay(geo.width - kHighlightWidthSubtractor, kHighlightHeight); + _focus_layer = dash::Style::Instance().FocusOverlay(geo.width - kHighlightLeftPadding - kHighlightRightPadding, kHighlightHeight); _cached_geometry = geo; } @@ -376,27 +428,11 @@ nux::GetPainter().PaintBackground(graphics_engine, base); - graphics_engine.GetRenderStates().SetColorMask(true, true, true, false); - graphics_engine.GetRenderStates().SetBlend(true); - graphics_engine.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - - if (_draw_sep) - { - nux::Color col(0.15f, 0.15f, 0.15f, 0.15f); - - nux::GetPainter().Draw2DLine(graphics_engine, - base.x + kSeparatorLeftPadding, base.y + base.height - 1, - base.x + base.width - kSeparatorWidthSubtractor, base.y + base.height - 1, - col); - } - - graphics_engine.GetRenderStates().SetColorMask(true, true, true, true); - if (ShouldBeHighlighted()) { nux::Geometry geo(_header_layout->GetGeometry()); - geo.x = base.x + kHighlightLeftPadding; - geo.width = base.width - kHighlightWidthSubtractor; + geo.width = base.width - kHighlightRightPadding - kHighlightLeftPadding; + geo.x += kHighlightLeftPadding; _focus_layer->SetGeometry(geo); _focus_layer->Renderlayer(graphics_engine); @@ -430,7 +466,6 @@ void PlacesGroup::SetCounts(guint n_visible_items_in_unexpand_mode, guint n_total_items) { - _n_visible_items_in_unexpand_mode = n_visible_items_in_unexpand_mode; _n_total_items = n_total_items; Relayout(); @@ -488,14 +523,6 @@ return _header_layout->GetGeometry().height; } -void -PlacesGroup::SetDrawSeparator(bool draw_it) -{ - _draw_sep = draw_it; - - QueueDraw(); -} - bool PlacesGroup::HeaderHasKeyFocus() const { return (_header_view && _header_view->HasKeyFocus()); @@ -546,6 +573,11 @@ wrapper.add("name", _name->GetText()); wrapper.add("is-visible", IsVisible()); wrapper.add("is-expanded", GetExpanded()); + wrapper.add("expand-label-is-visible", _expand_label->IsVisible()); + wrapper.add("expand-label-y", _expand_label->GetAbsoluteY()); + wrapper.add("expand-label-baseline", _expand_label->GetBaseline()); + wrapper.add("name-label-y", _name->GetAbsoluteY()); + wrapper.add("name-label-baseline", _name->GetBaseline()); } } // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/src/PlacesGroup.h unity-5.8.0/plugins/unityshell/src/PlacesGroup.h --- unity-5.6.0/plugins/unityshell/src/PlacesGroup.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PlacesGroup.h 2012-03-23 11:53:16.000000000 +0000 @@ -27,10 +27,12 @@ #include +#include "AbstractPlacesGroup.h" #include "IconTexture.h" #include "Introspectable.h" #include "StaticCairoText.h" #include "UBusWrapper.h" +#include "ResultView.h" namespace nux { @@ -40,9 +42,12 @@ namespace unity { -class PlacesGroup : public nux::View , public debug::Introspectable + +class HSeparator; + +class PlacesGroup : public dash::AbstractPlacesGroup, public debug::Introspectable { - NUX_DECLARE_OBJECT_TYPE(PlacesGroup, nux::View); + NUX_DECLARE_OBJECT_TYPE(PlacesGroup, dash::AbstractPlacesGroup); public: PlacesGroup(); @@ -54,7 +59,7 @@ nux::StaticCairoText* GetLabel(); nux::StaticCairoText* GetExpandLabel(); - void SetChildView(nux::View* view); + void SetChildView(dash::ResultView* view); nux::View* GetChildView(); void SetChildLayout(nux::Layout* layout); @@ -70,8 +75,6 @@ bool HeaderIsFocusable() const; nux::View* GetHeaderFocusableView() const; - void SetDrawSeparator(bool draw_it); - sigc::signal expanded; protected: @@ -94,6 +97,7 @@ bool HeaderHasKeyFocus() const; bool ShouldBeHighlighted() const; + void DrawSeparatorChanged(bool draw); void RecvMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags); 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); @@ -106,9 +110,12 @@ nux::View* _header_view; nux::HLayout* _header_layout; nux::HLayout* _text_layout; + nux::HLayout* _expand_label_layout; nux::HLayout* _expand_layout; nux::View* _child_view; nux::AbstractPaintLayer* _focus_layer; + nux::HLayout* separator_layout_; + HSeparator* separator_; IconTexture* _icon; nux::StaticCairoText* _name; @@ -121,7 +128,6 @@ guint _n_visible_items_in_unexpand_mode; guint _n_total_items; char* _cached_name; - bool _draw_sep; nux::Geometry _cached_geometry; UBusManager _ubus; diff -Nru unity-5.6.0/plugins/unityshell/src/PlacesVScrollBar.cpp unity-5.8.0/plugins/unityshell/src/PlacesVScrollBar.cpp --- unity-5.6.0/plugins/unityshell/src/PlacesVScrollBar.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PlacesVScrollBar.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -28,8 +28,16 @@ : VScrollBar(NUX_FILE_LINE_PARAM), _slider_texture(NULL) { - _slider->SetMinimumSize(3, 3); - SetMinimumSize(3, 3); + _scroll_up_button->SetMaximumHeight(15); + _scroll_up_button->SetMinimumHeight(15); + + _scroll_down_button->SetMaximumHeight(15); + _scroll_down_button->SetMinimumHeight(15); + + _slider->SetMinimumWidth(3); + _slider->SetMaximumWidth(3); + SetMinimumWidth(3); + SetMaximumWidth(3); } PlacesVScrollBar::~PlacesVScrollBar() @@ -56,8 +64,8 @@ void PlacesVScrollBar::Draw(nux::GraphicsEngine& gfxContext, bool force_draw) { - nux::Color color = nux::color::White; - nux::Geometry base = GetGeometry(); + nux::Color color = nux::color::White; + nux::Geometry const& base = GetGeometry(); nux::TexCoordXForm texxform; gfxContext.PushClippingRectangle(base); @@ -75,7 +83,8 @@ if (content_height_ > container_height_) { - nux::Geometry slider_geo = _slider->GetGeometry(); + nux::Geometry const& slider_geo = _slider->GetGeometry(); + gfxContext.QRP_1Tex(slider_geo.x, slider_geo.y, slider_geo.width, diff -Nru unity-5.6.0/plugins/unityshell/src/PreviewApplications.cpp unity-5.8.0/plugins/unityshell/src/PreviewApplications.cpp --- unity-5.6.0/plugins/unityshell/src/PreviewApplications.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PreviewApplications.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -56,27 +56,27 @@ { IconTexture *screenshot = new IconTexture (preview_->screenshot_icon_hint.c_str(), 420); IconTexture *icon = new IconTexture (preview_->icon_hint.c_str(), 80); - nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name, NUX_TRACKER_LOCATION); name->SetFont("Ubuntu 25"); - nux::StaticCairoText *version = new nux::StaticCairoText (preview_->version.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *version = new nux::StaticCairoText (preview_->version, NUX_TRACKER_LOCATION); version->SetFont("Ubuntu 15"); - nux::StaticCairoText *size = new nux::StaticCairoText (preview_->size.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *size = new nux::StaticCairoText (preview_->size, NUX_TRACKER_LOCATION); size->SetFont("Ubuntu 15"); - nux::StaticCairoText *licence = new nux::StaticCairoText (preview_->license.c_str(), NUX_TRACKER_LOCATION); - nux::StaticCairoText *last_updated = new nux::StaticCairoText (preview_->last_updated.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *licence = new nux::StaticCairoText (preview_->license, NUX_TRACKER_LOCATION); + nux::StaticCairoText *last_updated = new nux::StaticCairoText (preview_->last_updated, NUX_TRACKER_LOCATION); description = new nux::StaticCairoText ("", NUX_TRACKER_LOCATION); //description->SetBaseWidth(350); description->SetMaximumWidth(350); description->SetLines(99999999); - description->SetText(preview_->description.c_str()); + description->SetText(preview_->description); std::ostringstream number_of_reviews; number_of_reviews << preview_->n_ratings << " Reviews"; - nux::StaticCairoText *review_total = new nux::StaticCairoText (number_of_reviews.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *review_total = new nux::StaticCairoText (number_of_reviews.str(), NUX_TRACKER_LOCATION); nux::HLayout *large_container = new nux::HLayout(NUX_TRACKER_LOCATION); nux::VLayout *screenshot_container = new nux::VLayout(NUX_TRACKER_LOCATION); @@ -87,7 +87,7 @@ nux::HLayout *button_container = new nux::HLayout(NUX_TRACKER_LOCATION); // create the action buttons - PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name, NUX_TRACKER_LOCATION); //FIXME - add secondary action when we have the backend for it primary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->primary_action_uri); }); button_container->AddLayout (new nux::SpaceLayout(6,6,6,6), 0); @@ -153,7 +153,7 @@ g_debug ("layout recomputing"); description->SetBaseWidth((GetGeometry().width / 2) - 16 - 12 ); description->SetMaximumWidth((GetGeometry().width / 2) - 16 - 12 ); - description->SetText(preview_->description.c_str()); + description->SetText(preview_->description); } void PreviewApplications::Draw (nux::GraphicsEngine &GfxContext, bool force_draw) { diff -Nru unity-5.6.0/plugins/unityshell/src/PreviewGeneric.cpp unity-5.8.0/plugins/unityshell/src/PreviewGeneric.cpp --- unity-5.6.0/plugins/unityshell/src/PreviewGeneric.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PreviewGeneric.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -55,7 +55,7 @@ void PreviewGeneric::BuildLayout() { IconTexture *icon = new IconTexture (preview_->icon_hint.c_str(), 300); - nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name, NUX_TRACKER_LOCATION); name->SetFont("Ubuntu 25"); //get date @@ -71,14 +71,14 @@ std::stringstream size_and_type_str; size_and_type_str << formatted_size << ", " << preview_->type; - nux::StaticCairoText *size_and_type = new nux::StaticCairoText(size_and_type_str.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *size_and_type = new nux::StaticCairoText(size_and_type_str.str(), NUX_TRACKER_LOCATION); g_free (formatted_size); nux::StaticCairoText *description = new nux::StaticCairoText ("", NUX_TRACKER_LOCATION); description->SetBaseWidth(400); description->SetMaximumWidth(400); description->SetLines(99999999); - description->SetText(preview_->description.c_str()); + description->SetText(preview_->description); nux::HLayout *large_container = new nux::HLayout(NUX_TRACKER_LOCATION); nux::VLayout *screenshot_container = new nux::VLayout(NUX_TRACKER_LOCATION); @@ -88,7 +88,7 @@ // create the action buttons if (preview_->tertiary_action_name.empty() == false) { - PreviewBasicButton* tertiary_button = new PreviewBasicButton(preview_->tertiary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* tertiary_button = new PreviewBasicButton(preview_->tertiary_action_name, NUX_TRACKER_LOCATION); tertiary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->tertiary_action_uri); }); button_container->AddLayout (new nux::SpaceLayout(6,6,6,6), 0); button_container->AddView (tertiary_button, 1); @@ -96,7 +96,7 @@ if (preview_->secondary_action_name.empty() == false) { - PreviewBasicButton* secondary_button = new PreviewBasicButton(preview_->secondary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* secondary_button = new PreviewBasicButton(preview_->secondary_action_name, NUX_TRACKER_LOCATION); secondary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->secondary_action_uri); }); button_container->AddLayout (new nux::SpaceLayout(6,6,6,6), 0); button_container->AddView (secondary_button, 1); @@ -104,7 +104,7 @@ if (preview_->primary_action_name.empty() == false) { - PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name, NUX_TRACKER_LOCATION); primary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->primary_action_uri); }); button_container->AddLayout (new nux::SpaceLayout(6,6,6,6), 0); button_container->AddView (primary_button, 1); diff -Nru unity-5.6.0/plugins/unityshell/src/PreviewMusic.cpp unity-5.8.0/plugins/unityshell/src/PreviewMusic.cpp --- unity-5.6.0/plugins/unityshell/src/PreviewMusic.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PreviewMusic.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -58,11 +58,11 @@ void PreviewMusicAlbum::BuildLayout() { IconTexture *cover = new IconTexture (preview_->album_cover.c_str(), 400); - nux::StaticCairoText *title = new nux::StaticCairoText(preview_->name.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *title = new nux::StaticCairoText(preview_->name, NUX_TRACKER_LOCATION); title->SetFont("Ubuntu 25"); std::string artist_year = preview_->artist + ", " + preview_->year; - nux::StaticCairoText *artist = new nux::StaticCairoText(artist_year.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *artist = new nux::StaticCairoText(artist_year, NUX_TRACKER_LOCATION); artist->SetFont("Ubuntu 15"); std::ostringstream album_length_string; @@ -71,7 +71,7 @@ << preview_->length / 60 << ":" << preview_->length % 60 << " " << _("min"); - nux::StaticCairoText *album_length = new nux::StaticCairoText(album_length_string.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *album_length = new nux::StaticCairoText(album_length_string.str(), NUX_TRACKER_LOCATION); std::ostringstream genres_string; dash::AlbumPreview::Genres::iterator genre_it; @@ -86,7 +86,7 @@ genres_string << (*genre_it); } - nux::StaticCairoText *genres = new nux::StaticCairoText(genres_string.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *genres = new nux::StaticCairoText(genres_string.str(), NUX_TRACKER_LOCATION); nux::VLayout* tracks = new nux::VLayout(NUX_TRACKER_LOCATION); @@ -112,7 +112,7 @@ tracks->AddView(track_widget, 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); } - PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name, NUX_TRACKER_LOCATION); //FIXME - add secondary action when we have the backend for it primary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->primary_action_uri); }); diff -Nru unity-5.6.0/plugins/unityshell/src/PreviewMusicTrack.cpp unity-5.8.0/plugins/unityshell/src/PreviewMusicTrack.cpp --- unity-5.6.0/plugins/unityshell/src/PreviewMusicTrack.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PreviewMusicTrack.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -57,11 +57,11 @@ void PreviewMusicTrack::BuildLayout() { IconTexture *cover = new IconTexture (preview_->album_cover.c_str(), 400); - nux::StaticCairoText *title = new nux::StaticCairoText(preview_->title.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *title = new nux::StaticCairoText(preview_->title, NUX_TRACKER_LOCATION); title->SetFont("Ubuntu 25"); std::string artist_year = preview_->artist; // no year in model + ", " + preview_->year; - nux::StaticCairoText *artist = new nux::StaticCairoText(artist_year.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *artist = new nux::StaticCairoText(artist_year, NUX_TRACKER_LOCATION); artist->SetFont("Ubuntu 15"); std::ostringstream album_length_string; @@ -69,7 +69,7 @@ album_length_string << preview_->length / 60 << ":" << preview_->length % 60 << " " << _("min"); - nux::StaticCairoText *album_length = new nux::StaticCairoText(album_length_string.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *album_length = new nux::StaticCairoText(album_length_string.str(), NUX_TRACKER_LOCATION); std::ostringstream genres_string; dash::AlbumPreview::Genres::iterator genre_it; @@ -84,7 +84,7 @@ genres_string << (*genre_it); } - nux::StaticCairoText *genres = new nux::StaticCairoText(genres_string.str().c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *genres = new nux::StaticCairoText(genres_string.str(), NUX_TRACKER_LOCATION); nux::VLayout* tracks = new nux::VLayout(NUX_TRACKER_LOCATION); @@ -104,7 +104,7 @@ tracks->AddView(track_widget, 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); - PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name.c_str(), NUX_TRACKER_LOCATION); + PreviewBasicButton* primary_button = new PreviewBasicButton(preview_->primary_action_name, NUX_TRACKER_LOCATION); //FIXME - add secondary action when we have the backend for it primary_button->state_change.connect ([&] (nux::View *view) { UriActivated.emit (preview_->primary_action_uri); }); diff -Nru unity-5.6.0/plugins/unityshell/src/PreviewMusicTrackWidget.cpp unity-5.8.0/plugins/unityshell/src/PreviewMusicTrackWidget.cpp --- unity-5.6.0/plugins/unityshell/src/PreviewMusicTrackWidget.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/PreviewMusicTrackWidget.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -81,7 +81,7 @@ { nux::HLayout *track_layout = new nux::HLayout(NUX_TRACKER_LOCATION); //FIXME - use a button subclass for absolute renderering - play_button_ = new nux::Button(number_.c_str()); + play_button_ = new nux::Button(number_); play_button_->state_change.connect ([&] (nux::View *view) { if (track_is_active) @@ -97,8 +97,8 @@ }); //FIXME - hook up pressing button to activation URI - nux::StaticCairoText *track_title = new nux::StaticCairoText(name_.c_str(), NUX_TRACKER_LOCATION); - nux::StaticCairoText *track_length = new nux::StaticCairoText(time_.c_str(), NUX_TRACKER_LOCATION); + nux::StaticCairoText *track_title = new nux::StaticCairoText(name_, NUX_TRACKER_LOCATION); + nux::StaticCairoText *track_length = new nux::StaticCairoText(time_, NUX_TRACKER_LOCATION); track_layout->AddView(play_button_, 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); track_layout->AddLayout (new nux::SpaceLayout(6,6,6,6), 1); diff -Nru unity-5.6.0/plugins/unityshell/src/QuicklistMenuItem.cpp unity-5.8.0/plugins/unityshell/src/QuicklistMenuItem.cpp --- unity-5.6.0/plugins/unityshell/src/QuicklistMenuItem.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/QuicklistMenuItem.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -484,7 +484,11 @@ 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("text", _text) .add("x", GetBaseX()) .add("y", GetBaseY()) diff -Nru unity-5.6.0/plugins/unityshell/src/QuicklistView.cpp unity-5.8.0/plugins/unityshell/src/QuicklistView.cpp --- unity-5.6.0/plugins/unityshell/src/QuicklistView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/QuicklistView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -1400,9 +1400,13 @@ void QuicklistView::AddProperties(GVariantBuilder* builder) { + nux::Geometry abs_geo = GetAbsoluteGeometry(); + variant::BuilderWrapper(builder) - .add("x", GetBaseX()) - .add("y", GetBaseY()) + .add("x", abs_geo.x) + .add("y", abs_geo.y) + .add("base_x", GetBaseX()) + .add("base_y", GetBaseY()) .add("width", GetBaseWidth()) .add("height", GetBaseHeight()) .add("active", IsVisible()); diff -Nru unity-5.6.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp --- unity-5.6.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -95,7 +95,7 @@ style.GetTileIconSize() + 10, container->blurred_icon->GetDeviceTexture(), texxform, - nux::Color(0.5f, 0.5f, 0.5f, 0.5f)); + nux::Color(0.15f, 0.15f, 0.15f, 0.15f)); } // render highlight if its needed diff -Nru unity-5.6.0/plugins/unityshell/src/ResultRendererTile.cpp unity-5.8.0/plugins/unityshell/src/ResultRendererTile.cpp --- unity-5.6.0/plugins/unityshell/src/ResultRendererTile.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ResultRendererTile.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -51,6 +51,9 @@ namespace { nux::logging::Logger logger("unity.dash.results"); + +const int FONT_SIZE = 10; + } namespace dash @@ -114,7 +117,7 @@ tile_icon_size + 10, container->blurred_icon->GetDeviceTexture(), texxform, - nux::Color(0.5f, 0.5f, 0.5f, 0.5f)); + nux::Color(0.15f, 0.15f, 0.15f, 0.15f)); } // render highlight if its needed @@ -265,15 +268,15 @@ if (g_strrstr(icon_name.c_str(), "://")) { - container->slot_handle = IconLoader::GetDefault().LoadFromURI(icon_name.c_str(), style.GetTileIconSize(), slot); + container->slot_handle = IconLoader::GetDefault().LoadFromURI(icon_name, style.GetTileIconSize(), slot); } else if (G_IS_ICON(icon)) { - container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name.c_str(), style.GetTileIconSize(), slot); + container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name, style.GetTileIconSize(), slot); } else { - container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name.c_str(), style.GetTileIconSize(), slot); + container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name, style.GetTileIconSize(), slot); } if (icon != NULL) @@ -423,7 +426,7 @@ cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); layout = pango_cairo_create_layout(cr); desc = pango_font_description_from_string(font.Value()); - pango_font_description_set_size (desc, 9 * PANGO_SCALE); + pango_font_description_set_size (desc, FONT_SIZE * PANGO_SCALE); pango_layout_set_font_description(layout, desc); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); diff -Nru unity-5.6.0/plugins/unityshell/src/ResultViewGrid.cpp unity-5.8.0/plugins/unityshell/src/ResultViewGrid.cpp --- unity-5.6.0/plugins/unityshell/src/ResultViewGrid.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ResultViewGrid.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -61,9 +61,10 @@ , recorded_dash_height_(-1) , mouse_last_x_(-1) , mouse_last_y_(-1) + , extra_horizontal_spacing_(0) { SetAcceptKeyNavFocusOnMouseDown(false); - + auto needredraw_lambda = [&](int value) { NeedRedraw(); @@ -268,11 +269,22 @@ { total_height = renderer_->height; } + + int width = (items_per_row * renderer_->width) + (padding*2) + ((items_per_row - 1) * horizontal_spacing); + int geo_width = GetBaseWidth(); + int extra_width = geo_width - (width + 25-3); + + if (items_per_row != 1) + extra_horizontal_spacing_ = extra_width / (items_per_row - 1); + if (extra_horizontal_spacing_ < 0) + extra_horizontal_spacing_ = 0; + SetMinimumHeight(total_height + (padding * 2)); SetMaximumHeight(total_height + (padding * 2)); PositionPreview(); mouse_over_index_ = GetIndexAtPosition(mouse_last_x_, mouse_last_y_); + results_per_row = items_per_row; } void ResultViewGrid::PositionPreview() @@ -477,7 +489,7 @@ selected_index_ = std::min(static_cast(results_.size() - 1), selected_index_); focused_uri_ = results_[selected_index_].uri; - int focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); + int focused_x = (renderer_->width + horizontal_spacing + extra_horizontal_spacing_) * (selected_index_ % items_per_row); int focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); ubus_.SendMessage(UBUS_RESULT_VIEW_KEYNAV_CHANGED, @@ -510,19 +522,19 @@ if (direction == nux::KEY_NAV_UP && expanded) { // This View just got focused through keyboard navigation and the - // focus is comming from the bottom. We want to focus the + // focus is comming from the bottom. We want to focus the // first item (on the left) of the last row in this grid. int total_rows = std::ceil(results_.size() / (double)items_per_row); selected_index_ = items_per_row * (total_rows-1); - focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); + focused_x = (renderer_->width + horizontal_spacing + extra_horizontal_spacing_) * (selected_index_ % items_per_row); focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); } else { - focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); + focused_x = (renderer_->width + horizontal_spacing + extra_horizontal_spacing_) * (selected_index_ % items_per_row); focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); } @@ -611,7 +623,6 @@ gPainter.PaintBackground(GfxContext, GetGeometry()); int items_per_row = GetItemsPerRow(); - uint total_rows = (!expanded) ? 0 : (results_.size() / items_per_row) + 1; ResultView::ResultList::iterator it; @@ -670,9 +681,10 @@ offset_y = 0; } nux::Geometry render_geo(x_position, y_position, renderer_->width, renderer_->height); +//nux::GetPainter().Paint2DQuadColor(GfxContext, render_geo, nux::color::Blue*0.20); renderer_->Render(GfxContext, results_[index], state, render_geo, offset_x, offset_y); - x_position += renderer_->width + horizontal_spacing; + x_position += renderer_->width + horizontal_spacing + extra_horizontal_spacing_; } } @@ -734,7 +746,7 @@ { uint items_per_row = GetItemsPerRow(); - uint column_size = renderer_->width + horizontal_spacing; + uint column_size = renderer_->width + horizontal_spacing + extra_horizontal_spacing_; uint row_size = renderer_->height + vertical_spacing; if (preview_layout_ != NULL && (y - padding) / row_size > preview_row_) @@ -908,11 +920,11 @@ last_mouse_down_y_ = -1; current_drag_uri_.clear(); current_drag_icon_name_.clear(); - + // We need this because the drag can start in a ResultViewGrid and can // end in another ResultViewGrid EmitMouseLeaveSignal(0, 0, 0, 0); - + // We need an extra mouse motion to highlight the icon under the mouse // as soon as dnd finish Display* display = nux::GetGraphicsDisplay()->GetX11Display(); diff -Nru unity-5.6.0/plugins/unityshell/src/ResultViewGrid.h unity-5.8.0/plugins/unityshell/src/ResultViewGrid.h --- unity-5.6.0/plugins/unityshell/src/ResultViewGrid.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ResultViewGrid.h 2012-03-23 11:53:16.000000000 +0000 @@ -106,6 +106,8 @@ int mouse_last_x_; int mouse_last_y_; + int extra_horizontal_spacing_; + UBusManager ubus_; }; diff -Nru unity-5.6.0/plugins/unityshell/src/ResultView.h unity-5.8.0/plugins/unityshell/src/ResultView.h --- unity-5.6.0/plugins/unityshell/src/ResultView.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ResultView.h 2012-03-23 11:53:16.000000000 +0000 @@ -58,6 +58,8 @@ void SetPreview(PreviewBase* preview, Result& related_result); nux::Property expanded; + nux::Property results_per_row; + sigc::signal UriActivated; sigc::signal ChangePreview; // request a new preview, string is the uri diff -Nru unity-5.6.0/plugins/unityshell/src/SearchBar.cpp unity-5.8.0/plugins/unityshell/src/SearchBar.cpp --- unity-5.6.0/plugins/unityshell/src/SearchBar.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SearchBar.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -46,16 +46,26 @@ namespace { const float kExpandDefaultIconOpacity = 1.0f; -const int external_margin_vertical = 8; -const int external_margin_horizontal = 7; const int LIVE_SEARCH_TIMEOUT = 40; const int SPINNER_TIMEOUT = 100; -// Highlight +const int SPACE_BETWEEN_SPINNER_AND_TEXT = 5; +const int LEFT_INTERNAL_PADDING = 7; + const int HIGHLIGHT_HEIGHT = 24; -const int HIGHLIGHT_WIDTH = 292; -const int HIGHLIGHT_LEFT_PADDING = 5; -const int HIGHLIGHT_RIGHT_PADDING = 4; + +// Fonts +const std::string HINT_LABEL_FONT_SIZE = "20px"; +const std::string HINT_LABEL_FONT_STYLE = "Italic"; +const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE; + +const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu"; +const int PANGO_ENTRY_FONT_SIZE = 22; + +const std::string SHOW_FILTERS_LABEL_FONT_SIZE = "13"; +const std::string SHOW_FILTERS_LABEL_FONT_STYLE = "Bold"; +const std::string SHOW_FILTERS_LABEL_DEFAULT_FONT = "Ubuntu " + SHOW_FILTERS_LABEL_FONT_STYLE + " " + SHOW_FILTERS_LABEL_FONT_SIZE; + } namespace @@ -115,7 +125,7 @@ , show_filter_hint_(true) , expander_view_(nullptr) , show_filters_(nullptr) - , search_bar_width_(642) + , search_bar_width_(621) , live_search_timeout_(0) , start_spinner_timeout_(0) { @@ -160,9 +170,8 @@ bg_layer_ = new nux::ColorLayer(nux::Color(0xff595853), true); layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); - layout_->SetHorizontalInternalMargin(0); - layout_->SetVerticalExternalMargin(external_margin_vertical); - layout_->SetHorizontalExternalMargin(external_margin_horizontal); + layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, 10); + layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_SPINNER_AND_TEXT); SetLayout(layout_); spinner_ = new SearchBarSpinner(); @@ -170,11 +179,17 @@ spinner_->mouse_click.connect(sigc::mem_fun(this, &SearchBar::OnClearClicked)); layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION); + hint_ = new nux::StaticCairoText(" "); hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f)); hint_->SetMaximumWidth(search_bar_width_ - icon->GetWidth()); + hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str()); + hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); pango_entry_ = new IMTextEntry(); + pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str()); + pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE); pango_entry_->text_changed.connect(sigc::mem_fun(this, &SearchBar::OnSearchChanged)); pango_entry_->activated.connect([&]() { activated.emit(); }); pango_entry_->cursor_moved.connect([&](int i) { QueueDraw(); }); @@ -183,7 +198,7 @@ pango_entry_->SetMaximumWidth(search_bar_width_ - 1.5 * icon->GetWidth()); layered_layout_ = new nux::LayeredLayout(); - layered_layout_->AddLayer(hint_); + layered_layout_->AddLayout(hint_layout); layered_layout_->AddLayer(pango_entry_); layered_layout_->SetPaintAll(true); layered_layout_->SetActiveLayerN(1); @@ -193,12 +208,13 @@ if (show_filter_hint_) { - std::string filter_str(_("Filter results")); - show_filters_ = new nux::StaticCairoText(filter_str.c_str()); + std::string filter_str(_("Filter results")); + show_filters_ = new nux::StaticCairoText(filter_str); show_filters_->SetVisible(false); - show_filters_->SetFont("Ubuntu 10"); - show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); - show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); + show_filters_->SetFont(SHOW_FILTERS_LABEL_DEFAULT_FONT.c_str()); + show_filters_->SetTextColor(nux::color::White); + show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_RIGHT); + show_filters_->SetLines(1); nux::BaseTexture* arrow; arrow = dash::Style::Instance().GetGroupExpandIcon(); @@ -211,7 +227,6 @@ filter_layout_ = new nux::HLayout(); filter_layout_->SetHorizontalInternalMargin(8); - filter_layout_->SetHorizontalExternalMargin(6); filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER); arrow_layout_ = new nux::VLayout(); @@ -230,6 +245,10 @@ expander_view_->SetLayout(filter_layout_); layout_->AddView(expander_view_, 0, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL); + // Fix bug #917047 + show_filters_->SetMaximumWidth(dash::Style::Instance().GetFilterBarWidth() - 60); + show_filters_->SetMinimumWidth(dash::Style::Instance().GetFilterBarWidth() - 60); + // Lambda functions auto mouse_expand = [&](int, int, unsigned long, unsigned long) { @@ -298,44 +317,35 @@ void SearchBar::OnFontChanged(GtkSettings* settings, GParamSpec* pspec) { - static const int HOW_LARGE = 8; gchar* font_name = NULL; PangoFontDescription* desc; - gint size; - gchar* font_desc; + std::ostringstream font_desc; g_object_get(settings, "gtk-font-name", &font_name, NULL); desc = pango_font_description_from_string(font_name); pango_entry_->SetFontFamily(pango_font_description_get_family(desc)); - - size = pango_font_description_get_size(desc); - size /= pango_font_description_get_size_is_absolute(desc) ? 1 : PANGO_SCALE; - pango_entry_->SetFontSize(size + HOW_LARGE); - + pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE); pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default())); - font_desc = g_strdup_printf("%s %d", pango_font_description_get_family(desc), size + HOW_LARGE); - hint_->SetFont(font_desc); + font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE; + hint_->SetFont(font_desc.str().c_str()); - g_free(font_desc); - font_desc = g_strdup_printf("%s %d", pango_font_description_get_family(desc), size + HOW_LARGE/2); - show_filters_->SetFont(font_desc); + font_desc.str(""); + font_desc.clear(); + font_desc << pango_font_description_get_family(desc) << " " << SHOW_FILTERS_LABEL_FONT_STYLE << " " << SHOW_FILTERS_LABEL_FONT_SIZE; + show_filters_->SetFont(font_desc.str().c_str()); pango_font_description_free(desc); g_free(font_name); - g_free(font_desc); } void SearchBar::OnSearchHintChanged() { - std::string hint = search_hint; - gchar* tmp = g_markup_escape_text(hint.c_str(), -1); + gchar* tmp = g_markup_escape_text(search_hint().c_str(), -1); - gchar* markup = g_strdup_printf(" %s ", tmp); - hint_->SetText(markup); + hint_->SetText(tmp); - g_free(markup); g_free(tmp); } @@ -407,23 +417,25 @@ GfxContext.PushClippingRectangle(base); nux::GetPainter().PaintBackground(GfxContext, base); - bg_layer_->SetGeometry(nux::Geometry(base.x, base.y, last_width_, base.height)); + bg_layer_->SetGeometry(nux::Geometry(base.x, base.y, last_width_, last_height_)); nux::GetPainter().RenderSinglePaintLayer(GfxContext, bg_layer_->GetGeometry(), bg_layer_); if (ShouldBeHighlighted()) { + dash::Style& style = dash::Style::Instance(); + nux::Geometry geo(show_filters_->GetGeometry()); nux::Geometry const& geo_arrow = arrow_layout_->GetGeometry(); geo.y -= (HIGHLIGHT_HEIGHT- geo.height) / 2; geo.height = HIGHLIGHT_HEIGHT; - geo.width = HIGHLIGHT_WIDTH + HIGHLIGHT_LEFT_PADDING + HIGHLIGHT_RIGHT_PADDING; - geo.x = geo_arrow.x + (geo_arrow.width - 1) - geo.width + HIGHLIGHT_RIGHT_PADDING; + geo.width = style.GetFilterBarWidth() + style.GetFilterBarLeftPadding() + style.GetFilterBarRightPadding(); + geo.x = geo_arrow.x + (geo_arrow.width - 1) - geo.width + style.GetFilterBarLeftPadding(); if (!highlight_layer_) - highlight_layer_.reset(dash::Style::Instance().FocusOverlay(geo.width, geo.height)); + highlight_layer_.reset(style.FocusOverlay(geo.width, geo.height)); highlight_layer_->SetGeometry(geo); highlight_layer_->Renderlayer(GfxContext); @@ -500,9 +512,7 @@ void SearchBar::UpdateBackground(bool force) { - int PADDING = 12; int RADIUS = 5; - int x, y, width, height; nux::Geometry geo(GetGeometry()); geo.width = layered_layout_->GetGeometry().width; @@ -519,43 +529,21 @@ last_width_ = geo.width; last_height_ = geo.height; - if (disable_glow) - PADDING = 2; - - x = y = PADDING - 1; - - width = last_width_ - (2 * PADDING); - height = last_height_ - (2 * PADDING) + 1; - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, last_width_, last_height_); cairo_t* cr = cairo_graphics.GetContext(); cairo_graphics.DrawRoundedRectangle(cr, 1.0f, - x, - y, + 1 + 0.5, 1 + 0.5, RADIUS, - width, - height, - true); - - // Disable glow effect #929183 - //cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f); - //cairo_set_line_width(cr, 1.0); - //cairo_stroke_preserve(cr); - //cairo_graphics.BlurSurface (3, cairo_get_target (cr)); - - // XXX: Not sure this code is 100% correct. - cairo_operator_t op = CAIRO_OPERATOR_OVER; - op = cairo_get_operator (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f); - cairo_fill_preserve(cr); - cairo_set_operator (cr, op); - cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f); + last_width_ - 1 - 2, last_height_ - 1 - 2, + false); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.57f); cairo_fill_preserve(cr); + cairo_set_line_width(cr, 1); cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.8f); - cairo_set_line_width(cr, 1.0); cairo_stroke(cr); cairo_destroy(cr); @@ -564,6 +552,7 @@ nux::TexCoordXForm texxform; texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + if (bg_layer_) delete bg_layer_; @@ -583,14 +572,15 @@ void SearchBar::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key) { - search_hint = ""; + hint_->SetVisible(false); } void SearchBar::OnEndKeyFocus() { - search_hint = _("Search"); + hint_->SetVisible(search_string().empty()); } + nux::TextEntry* SearchBar::text_entry() const { return pango_entry_; diff -Nru unity-5.6.0/plugins/unityshell/src/SearchBarSpinner.cpp unity-5.8.0/plugins/unityshell/src/SearchBarSpinner.cpp --- unity-5.6.0/plugins/unityshell/src/SearchBarSpinner.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SearchBarSpinner.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,6 +39,7 @@ dash::Style& style = dash::Style::Instance(); _magnify = style.GetSearchMagnifyIcon(); + _circle = style.GetSearchCircleIcon(); _close = style.GetSearchCloseIcon(); _spin = style.GetSearchSpinIcon(); @@ -86,8 +87,11 @@ geo.y + ((geo.height - _spin->GetHeight()) / 2), _spin->GetWidth(), _spin->GetHeight()); - int spin_offset_w = (geo.width % 2) ? 0 : 1; - int spin_offset_h = (geo.height % 2) ? 0 : 1; + // Geometry (== Rect) uses integers which were rounded above, + // hence an extra 0.5 offset for odd sizes is needed + // because pure floating point is not being used. + int spin_offset_w = !(geo.width % 2) ? 0 : 1; + int spin_offset_h = !(geo.height % 2) ? 0 : 1; GfxContext.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0)); @@ -109,25 +113,14 @@ } else { - texxform.FlipVCoord(true); - GfxContext.QRP_1Tex(geo.x + ((geo.width - _spin->GetWidth()) / 2), - geo.y + ((geo.height - _spin->GetHeight()) / 2), - _spin->GetWidth(), - _spin->GetHeight(), - _spin->GetDeviceTexture(), - texxform, - nux::color::White); - texxform.FlipVCoord(false); - - GfxContext.QRP_1Tex(geo.x + ((geo.width - _spin->GetWidth()) / 2), - geo.y + ((geo.height - _spin->GetHeight()) / 2), - _spin->GetWidth(), - _spin->GetHeight(), - _spin->GetDeviceTexture(), + GfxContext.QRP_1Tex(geo.x + ((geo.width - _circle->GetWidth()) / 2), + geo.y + ((geo.height - _circle->GetHeight()) / 2), + _circle->GetWidth(), + _circle->GetHeight(), + _circle->GetDeviceTexture(), texxform, nux::color::White); - GfxContext.QRP_1Tex(geo.x + ((geo.width - _close->GetWidth()) / 2), geo.y + ((geo.height - _close->GetHeight()) / 2), _close->GetWidth(), diff -Nru unity-5.6.0/plugins/unityshell/src/SearchBarSpinner.h unity-5.8.0/plugins/unityshell/src/SearchBarSpinner.h --- unity-5.6.0/plugins/unityshell/src/SearchBarSpinner.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SearchBarSpinner.h 2012-03-23 11:53:16.000000000 +0000 @@ -65,10 +65,9 @@ SpinnerState _state; nux::BaseTexture* _magnify; + nux::BaseTexture* _circle; nux::BaseTexture* _close; - nux::BaseTexture* _close_glow; nux::BaseTexture* _spin; - nux::BaseTexture* _spin_glow; nux::Matrix4 _2d_rotate; float _rotation; diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutController.cpp unity-5.8.0/plugins/unityshell/src/ShortcutController.cpp --- unity-5.6.0/plugins/unityshell/src/ShortcutController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -28,6 +28,7 @@ namespace { const unsigned int SUPER_TAP_DURATION = 650; +const unsigned int FADE_DURATION = 100; } // anonymouse namespace; Controller::Controller(std::list& hints) @@ -35,8 +36,8 @@ , visible_(false) , enabled_(true) , show_timer_(0) - , fade_in_animator_(100) - , fade_out_animator_(100) + , fade_in_animator_(FADE_DURATION) + , fade_out_animator_(FADE_DURATION) { bg_color_ = nux::Color(0.0, 0.0, 0.0, 0.5); @@ -185,16 +186,18 @@ visible_ = false; + if (show_timer_) + { + g_source_remove(show_timer_); + show_timer_ = 0; + } + if (view_window_) { view_->SetupBackground(false); fade_in_animator_.Stop(); fade_out_animator_.Start(1.0 - view_window_->GetOpacity()); } - - if (show_timer_) - g_source_remove(show_timer_); - show_timer_ = 0; } bool Controller::Visible() @@ -212,5 +215,21 @@ enabled_ = enabled; } +std::string Controller::GetName() const +{ + return "ShortcutController"; +} + +void Controller::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper(builder) + .add(workarea_) + .add("timeout_duration", SUPER_TAP_DURATION + FADE_DURATION) + .add("enabled", IsEnabled()) + .add("about_to_show", (Visible() && !fade_out_animator_.IsRunning() && view_window_ && view_window_->GetOpacity() != 1.0f)) + .add("about_to_hide", (Visible() && !fade_in_animator_.IsRunning() && view_window_ && view_window_->GetOpacity() != 1.0f)) + .add("visible", (Visible() && view_window_ && view_window_->GetOpacity() == 1.0f)); +} + } // namespace shortcut } // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutController.h unity-5.8.0/plugins/unityshell/src/ShortcutController.h --- unity-5.6.0/plugins/unityshell/src/ShortcutController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutController.h 2012-03-23 11:53:16.000000000 +0000 @@ -25,8 +25,10 @@ #include #include #include +#include #include "Animator.h" +#include "Introspectable.h" #include "ShortcutModel.h" #include "ShortcutView.h" #include "UBusWrapper.h" @@ -36,7 +38,7 @@ namespace shortcut { -class Controller +class Controller : public debug::Introspectable { public: typedef std::shared_ptr Ptr; @@ -55,6 +57,10 @@ void SetWorkspace(nux::Geometry const& geo); void SetEnabled(bool enabled); +protected: + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + private: // Private Methods void ConstructView(); diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutHint.cpp unity-5.8.0/plugins/unityshell/src/ShortcutHint.cpp --- unity-5.6.0/plugins/unityshell/src/ShortcutHint.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutHint.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -118,6 +118,35 @@ break; } + case COMPIZ_METAKEY_OPTION: + { + // Arg1 = Plugin name + // Arg2 = key Option name + CompPlugin* p = CompPlugin::find(arg1().c_str()); + + if (!p) + return false; + + foreach (CompOption &opt, p->vTable->getOptions()) + { + if (opt.name() == arg2()) + { + std::string temp(impl::GetMetaKey(opt.value().action().keyToString())); + temp = impl::FixShortcutFormat(temp); + temp = impl::ProperCase(temp); + + if (value() != temp) + { + value = temp; + shortkey = prefix() + value() + postfix(); + } + + return true; + } + } + + break; + } case HARDCODED_OPTION: if (value != arg1()) { diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutHintPrivate.cpp unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.cpp --- unity-5.6.0/plugins/unityshell/src/ShortcutHintPrivate.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -29,6 +29,15 @@ namespace impl { +std::string GetMetaKey(std::string const& scut) +{ + size_t index = scut.find_last_of( ">"); + if (index >= 0) + return std::string(scut.begin(), scut.begin() + index + 1); + else + return ""; +} + std::string FixShortcutFormat(std::string const& scut) { std::string ret(scut.begin(), scut.end() - 1); diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutHintPrivate.h unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.h --- unity-5.6.0/plugins/unityshell/src/ShortcutHintPrivate.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.h 2012-03-23 11:53:16.000000000 +0000 @@ -28,6 +28,7 @@ namespace impl { +std::string GetMetaKey(std::string const& scut); std::string FixShortcutFormat(std::string const& scut); std::string FixMouseShortcut(std::string const& scut); std::string ProperCase(std::string const& str); diff -Nru unity-5.6.0/plugins/unityshell/src/ShortcutView.cpp unity-5.8.0/plugins/unityshell/src/ShortcutView.cpp --- unity-5.6.0/plugins/unityshell/src/ShortcutView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ShortcutView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -16,7 +16,7 @@ * Authored by: Andrea Azzarone * Jay Taoko */ - + #include "ShortcutView.h" #include @@ -53,22 +53,22 @@ std::string header = ""; header += _("Keyboard Shortcuts"); header += ""; - - nux::StaticText* header_view = new nux::StaticText(header.c_str(), NUX_TRACKER_LOCATION); + + nux::StaticText* header_view = new nux::StaticText(header, NUX_TRACKER_LOCATION); header_view->SetTextPointSize(20/1.33); header_view->SetFontName("Ubuntu"); layout_->AddView(header_view, 1 , nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); - - layout_->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); - - columns_layout_ = new nux::HLayout(); + + layout_->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + + columns_layout_ = new nux::HLayout(); columns_layout_->SetSpaceBetweenChildren(30); layout_->AddLayout(columns_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); - + // Column 1... columns_.push_back(new nux::VLayout()); columns_layout_->AddLayout(columns_[0], 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); - + // Column 2... columns_.push_back(new nux::VLayout()); columns_layout_->AddLayout(columns_[1], 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); @@ -94,13 +94,12 @@ nux::LinearLayout* View::CreateSectionLayout(const char* section_name) { nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); - - std::string name = ""; - name += std::string(section_name); - name += ""; + std::string name(""); + name += glib::String(g_markup_escape_text(section_name, -1)).Str(); + name += ""; - nux::StaticText* section_name_view = new nux::StaticText(name.c_str(), NUX_TRACKER_LOCATION); + nux::StaticText* section_name_view = new nux::StaticText(name, NUX_TRACKER_LOCATION); section_name_view->SetTextPointSize(SECTION_NAME_FONT_SIZE); section_name_view->SetFontName("Ubuntu"); layout->AddView(new nux::SpaceLayout(10, 10, 10, 10), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT); @@ -117,7 +116,7 @@ nux::HLayout* description_layout = new nux::HLayout(NUX_TRACKER_LOCATION); glib::String shortkey(g_markup_escape_text(hint->shortkey().c_str(), -1)); - + std::string skey = ""; skey += shortkey.Str(); skey += ""; @@ -128,7 +127,7 @@ shortkey_view->SetTextPointSize(SHORTKEY_ENTRY_FONT_SIZE); shortkey_view->SetMinimumWidth(SHORTKEY_COLUMN_WIDTH); shortkey_view->SetMaximumWidth(SHORTKEY_COLUMN_WIDTH); - + glib::String es_desc(g_markup_escape_text(hint->description().c_str(), -1)); nux::StaticText* description_view = new nux::StaticText(es_desc.Value(), NUX_TRACKER_LOCATION); @@ -152,15 +151,15 @@ layout->AddLayout(description_layout, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetSpaceBetweenChildren(INTER_SPACE_SHORTKEY_DESCRIPTION); description_layout->SetContentDistribution(nux::MAJOR_POSITION_START); - + auto on_shortkey_changed = [](std::string const& new_shortkey, nux::StaticText* view) { std::string skey = ""; skey += new_shortkey; skey += ""; - + view->SetText(skey); }; - + hint->shortkey.changed.connect(sigc::bind(sigc::slot(on_shortkey_changed), shortkey_view)); return layout; @@ -178,7 +177,7 @@ { nux::Geometry base = GetGeometry(); nux::Geometry background_geo; - + background_geo.width = base.width; background_geo.height = base.height; background_geo.x = (base.width - background_geo.width)/2; @@ -188,7 +187,7 @@ } void View::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry clip) -{ +{ layout_->ProcessDraw(GfxContext, force_draw); } @@ -196,27 +195,27 @@ { int i = 0; int column = 0; - + for (auto category : model_->categories()) { // Three sections in the fist column... if (i > 2) column = 1; - + nux::LinearLayout* section_layout = CreateSectionLayout(category.c_str()); nux::LinearLayout* intermediate_layout = CreateIntermediateLayout(); intermediate_layout->SetContentDistribution(nux::MAJOR_POSITION_START); - + for (auto hint : model_->hints()[category]) { //std::string str_value = hint->prefix() + hint->value() + hint->postfix(); //boost::replace_all(str_value, "&", "&"); //boost::replace_all(str_value, "<", "<"); //boost::replace_all(str_value, ">", ">"); - + intermediate_layout->AddLayout(CreateShortKeyEntryLayout(hint), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); } - + section_layout->AddLayout(intermediate_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); if (i == 0 or i==1 or i==3 or i==4) @@ -229,10 +228,10 @@ } columns_[column]->AddView(section_layout, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); - + i++; } } - + } // namespace shortcut } // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp --- unity-5.6.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -44,7 +44,7 @@ }); SetIconType(TYPE_APPLICATION); - icon_name = icon_path.c_str(); + icon_name = icon_path; tooltip_text = _("Waiting to install"); } diff -Nru unity-5.6.0/plugins/unityshell/src/StaticCairoText.cpp unity-5.8.0/plugins/unityshell/src/StaticCairoText.cpp --- unity-5.6.0/plugins/unityshell/src/StaticCairoText.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/StaticCairoText.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -42,12 +42,12 @@ StaticCairoText::StaticCairoText(std::string const& text, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM), + _baseline(0), _fontstring(NULL), _cairoGraphics(NULL), _texture2D(NULL), _lines(-2), _actual_lines(0) - { _textColor = Color(1.0f, 1.0f, 1.0f, 1.0f); _text = text; @@ -276,6 +276,11 @@ return _actual_lines; } +int StaticCairoText::GetBaseline() const +{ + return _baseline; +} + void StaticCairoText::GetTextExtents(int& width, int& height) { GtkSettings* settings = gtk_settings_get_default(); // not ref'ed @@ -303,6 +308,7 @@ PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; + PangoRectangle inkRect = {0, 0, 0, 0}; PangoRectangle logRect = {0, 0, 0, 0}; int dpi = 0; GdkScreen* screen = gdk_screen_get_default(); // is not ref'ed @@ -365,12 +371,18 @@ (float) dpi / (float) PANGO_SCALE); } pango_layout_context_changed(layout); - pango_layout_get_extents(layout, NULL, &logRect); + pango_layout_get_extents(layout, &inkRect, &logRect); + + // 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; + else + width = logRect.width / PANGO_SCALE; - width = logRect.width / PANGO_SCALE; height = logRect.height / PANGO_SCALE; _cached_extent_height = height; _cached_extent_width = width; + _baseline = pango_layout_get_baseline(layout) / PANGO_SCALE; // clean up pango_font_description_free(desc); diff -Nru unity-5.6.0/plugins/unityshell/src/StaticCairoText.h unity-5.8.0/plugins/unityshell/src/StaticCairoText.h --- unity-5.6.0/plugins/unityshell/src/StaticCairoText.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/StaticCairoText.h 2012-03-23 11:53:16.000000000 +0000 @@ -88,6 +88,7 @@ std::string GetText() const; int GetLineCount(); + int GetBaseline() const; void GetTextExtents(int& width, int& height); @@ -107,6 +108,7 @@ bool _need_new_extent_cache; int _cached_base_width; int _cached_base_height; + int _baseline; std::string _text; Color _textColor; diff -Nru unity-5.6.0/plugins/unityshell/src/SwitcherController.cpp unity-5.8.0/plugins/unityshell/src/SwitcherController.cpp --- unity-5.6.0/plugins/unityshell/src/SwitcherController.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SwitcherController.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -22,7 +22,6 @@ #include #include "UBusMessages.h" -#include "ubus-server.h" #include "WindowManager.h" #include "SwitcherController.h" @@ -36,41 +35,53 @@ namespace switcher { -Controller::Controller() - : view_window_(0) +Controller::Controller(unsigned int load_timeout) + : construct_timeout_(load_timeout) + , view_window_(nullptr) + , main_layout_(nullptr) + , monitor_(0) , visible_(false) , show_timer_(0) , detail_timer_(0) + , lazy_timer_(0) + , view_idle_timer_(0) + , bg_color_(0, 0, 0, 0.5) { timeout_length = 75; detail_on_timeout = true; detail_timeout_length = 1500; - monitor_ = 0; - bg_color_ = nux::Color(0.0, 0.0, 0.0, 0.5); + ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &Controller::OnBackgroundUpdate)); - UBusServer *ubus = ubus_server_get_default(); - bg_update_handle_ = - ubus_server_register_interest(ubus, UBUS_BACKGROUND_COLOR_CHANGED, - (UBusCallback)&Controller::OnBackgroundUpdate, - this); + /* Construct the view after a prefixed timeout, to improve the startup time */ + lazy_timer_ = g_timeout_add_seconds_full(G_PRIORITY_LOW, construct_timeout_, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + self->lazy_timer_ = 0; + self->ConstructWindow(); + return FALSE; + }, this, nullptr); } Controller::~Controller() { - ubus_server_unregister_interest(ubus_server_get_default(), bg_update_handle_); if (view_window_) view_window_->UnReference(); + + if (lazy_timer_) + g_source_remove(lazy_timer_); + + if (view_idle_timer_) + g_source_remove(view_idle_timer_); } -void Controller::OnBackgroundUpdate(GVariant* data, Controller* self) +void Controller::OnBackgroundUpdate(GVariant* data) { gdouble red, green, blue, alpha; g_variant_get(data, "(dddd)", &red, &green, &blue, &alpha); - self->bg_color_ = nux::Color(red, green, blue, alpha); + bg_color_ = nux::Color(red, green, blue, alpha); - if (self->view_) - self->view_->background_color = self->bg_color_; + if (view_) + view_->background_color = bg_color_; } void Controller::Show(ShowMode show, SortMode sort, bool reverse, @@ -92,13 +103,29 @@ if (timeout_length > 0) { + if (view_idle_timer_) + g_source_remove(view_idle_timer_); + + view_idle_timer_ = g_idle_add_full(G_PRIORITY_LOW, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + self->ConstructView(); + self->view_idle_timer_ = 0; + return FALSE; + }, this, NULL); + if (show_timer_) g_source_remove (show_timer_); - show_timer_ = g_timeout_add(timeout_length, &Controller::OnShowTimer, this); + + show_timer_ = g_timeout_add(timeout_length, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + self->ShowView(); + self->show_timer_ = 0; + return FALSE; + }, this); } else { - ConstructView(); + ShowView(); } if (detail_on_timeout) @@ -108,12 +135,8 @@ detail_timer_ = g_timeout_add(detail_timeout_length, &Controller::OnDetailTimer, this); } - ubus_server_send_message(ubus_server_get_default(), - UBUS_PLACE_VIEW_CLOSE_REQUEST, - NULL); - - ubus_server_send_message(ubus_server_get_default(), - UBUS_SWITCHER_SHOWN, g_variant_new_boolean(true)); + ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); + ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new_boolean(true)); } void Controller::Select(int index) @@ -122,17 +145,6 @@ model_->Select(index); } -gboolean Controller::OnShowTimer(gpointer data) -{ - Controller* self = static_cast(data); - - if (self->visible_) - self->ConstructView(); - - self->show_timer_ = 0; - return FALSE; -} - gboolean Controller::OnDetailTimer(gpointer data) { Controller* self = static_cast(data); @@ -157,18 +169,28 @@ detail_timer_ = g_timeout_add(detail_timeout_length, &Controller::OnDetailTimer, this); } - ubus_server_send_message(ubus_server_get_default(), - UBUS_SWITCHER_SELECTION_CHANGED, - g_variant_new_string(icon->tooltip_text().c_str())); + ubus_manager_.SendMessage(UBUS_SWITCHER_SELECTION_CHANGED, + g_variant_new_string(icon->tooltip_text().c_str())); } -void Controller::ConstructView() +void Controller::ShowView() { - view_ = SwitcherView::Ptr(new SwitcherView()); - AddChild(view_.GetPointer()); - view_->SetModel(model_); - view_->background_color = bg_color_; - view_->monitor = monitor_; + if (!visible_) + return; + + ConstructView(); + + if (view_window_) + view_window_->SetOpacity(1.0f); +} + +void Controller::ConstructWindow() +{ + if (lazy_timer_) + { + g_source_remove(lazy_timer_); + lazy_timer_ = 0; + } if (!view_window_) { @@ -180,12 +202,32 @@ view_window_->SinkReference(); view_window_->SetLayout(main_layout_); view_window_->SetBackgroundColor(nux::Color(0x00000000)); + view_window_->SetGeometry(workarea_); } +} - main_layout_->AddView(view_.GetPointer(), 1); +void Controller::ConstructView() +{ + if (view_ || !model_) + return; - view_window_->SetGeometry(workarea_); + if (view_idle_timer_) + { + g_source_remove(view_idle_timer_); + view_idle_timer_ = 0; + } + + view_ = SwitcherView::Ptr(new SwitcherView()); + AddChild(view_.GetPointer()); + view_->SetModel(model_); + view_->background_color = bg_color_; + view_->monitor = monitor_; view_->SetupBackground(); + + ConstructWindow(); + main_layout_->AddView(view_.GetPointer(), 1); + view_window_->SetGeometry(workarea_); + view_window_->SetOpacity(0.0f); view_window_->ShowWindow(true); } @@ -227,6 +269,12 @@ } } + if (view_idle_timer_) + { + g_source_remove(view_idle_timer_); + view_idle_timer_ = 0; + } + model_.reset(); visible_ = false; @@ -234,7 +282,10 @@ main_layout_->RemoveChildObject(view_.GetPointer()); if (view_window_) + { + view_window_->SetOpacity(0.0f); view_window_->ShowWindow(false); + } if (show_timer_) g_source_remove(show_timer_); @@ -244,8 +295,7 @@ g_source_remove(detail_timer_); detail_timer_ = 0; - ubus_server_send_message(ubus_server_get_default(), - UBUS_SWITCHER_SHOWN, g_variant_new_boolean(false)); + ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new_boolean(false)); view_.Release(); } diff -Nru unity-5.6.0/plugins/unityshell/src/SwitcherController.h unity-5.8.0/plugins/unityshell/src/SwitcherController.h --- unity-5.6.0/plugins/unityshell/src/SwitcherController.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SwitcherController.h 2012-03-23 11:53:16.000000000 +0000 @@ -27,6 +27,7 @@ #include "SwitcherModel.h" #include "SwitcherView.h" +#include "UBusWrapper.h" #include #include @@ -62,11 +63,10 @@ public: typedef std::shared_ptr Ptr; - Controller(); + Controller(unsigned int load_timeout = 20); virtual ~Controller(); nux::Property timeout_length; - nux::Property detail_on_timeout; nux::Property detail_timeout_length; @@ -98,6 +98,12 @@ std::string GetName() const; void AddProperties(GVariantBuilder* builder); + virtual void ConstructWindow(); + virtual void ConstructView(); + virtual void ShowView(); + + unsigned int construct_timeout_; + private: enum DetailMode { @@ -106,15 +112,13 @@ TAB_NEXT_TILE, }; - void ConstructView(); - void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr icon); - - static void OnBackgroundUpdate(GVariant* data, Controller* self); + void OnBackgroundUpdate(GVariant* data); SwitcherModel::Ptr model_; SwitcherView::Ptr view_; + UBusManager ubus_manager_; nux::Geometry workarea_; nux::BaseWindow* view_window_; @@ -124,11 +128,11 @@ bool visible_; guint show_timer_; guint detail_timer_; + guint lazy_timer_; + guint view_idle_timer_; nux::Color bg_color_; DetailMode detail_mode_; - guint bg_update_handle_; - static gboolean OnShowTimer(gpointer data); static gboolean OnDetailTimer(gpointer data); static bool CompareSwitcherItemsPriority(launcher::AbstractLauncherIcon::Ptr first, launcher::AbstractLauncherIcon::Ptr second); diff -Nru unity-5.6.0/plugins/unityshell/src/SwitcherView.cpp unity-5.8.0/plugins/unityshell/src/SwitcherView.cpp --- unity-5.6.0/plugins/unityshell/src/SwitcherView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/SwitcherView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -125,7 +125,7 @@ model->detail_selection_index.changed.connect (sigc::mem_fun (this, &SwitcherView::OnDetailSelectionIndexChanged)); if (model->Selection()) - text_view_->SetText(model->Selection()->tooltip_text().c_str()); + text_view_->SetText(model->Selection()->tooltip_text()); } void SwitcherView::OnIconSizeChanged (int size) @@ -151,7 +151,7 @@ if (model_->detail_selection) { Window detail_window = model_->DetailSelectionWindow(); - text_view_->SetText(model_->Selection()->NameForWindow (detail_window)); + text_view_->SetText(model_->Selection()->NameForWindow(detail_window)); } QueueDraw (); } @@ -162,11 +162,11 @@ if (detail) { Window detail_window = model_->DetailSelectionWindow(); - text_view_->SetText(model_->Selection()->NameForWindow (detail_window)); + text_view_->SetText(model_->Selection()->NameForWindow(detail_window)); } else { - text_view_->SetText(model_->Selection()->tooltip_text().c_str()); + text_view_->SetText(model_->Selection()->tooltip_text()); } SaveLast (); QueueDraw (); @@ -175,7 +175,7 @@ void SwitcherView::OnSelectionChanged(AbstractLauncherIcon::Ptr selection) { if (selection) - text_view_->SetText(selection->tooltip_text().c_str()); + text_view_->SetText(selection->tooltip_text()); SaveLast (); QueueDraw(); } @@ -217,7 +217,7 @@ { // easing progress = -pow(progress - 1.0f, 2) + 1; - + RenderArg result = end; result.x_rotation = start.x_rotation + (end.x_rotation - start.x_rotation) * progress; @@ -262,7 +262,7 @@ layout_window->alpha = 1.0f * progress; else layout_window->alpha = 0.9f * progress; - + render_targets_.push_back (layout_window); } @@ -294,22 +294,22 @@ { nux::Geometry base = GetGeometry(); nux::Size result (base.width - border_size * 2, base.height - border_size * 2); - + int width_padding = std::max(model_->Size() - 1, 0) * minimum_spacing + tile_size; int height_padding = text_size; result.width -= width_padding; result.height -= height_padding; - + return result; } -void SwitcherView::GetFlatIconPositions (int n_flat_icons, - int size, - int selection, - int &first_flat, - int &last_flat, - int &half_fold_left, +void SwitcherView::GetFlatIconPositions (int n_flat_icons, + int size, + int selection, + int &first_flat, + int &last_flat, + int &half_fold_left, int &half_fold_right) { half_fold_left = -1; @@ -388,7 +388,7 @@ bool detail_selection = model_->detail_selection; background_geo.y = base.y + base.height / 2 - (vertical_size / 2); - background_geo.height = vertical_size + text_size; + background_geo.height = vertical_size + text_size; if (model_) @@ -440,7 +440,7 @@ int half_fold_left; int half_fold_right; - GetFlatIconPositions (n_flat_icons, size, selection, first_flat, last_flat, half_fold_left, half_fold_right); + GetFlatIconPositions (n_flat_icons, size, selection, first_flat, last_flat, half_fold_left, half_fold_right); SwitcherModel::iterator it; int i = 0; diff -Nru unity-5.6.0/plugins/unityshell/src/UBusMessages.h unity-5.8.0/plugins/unityshell/src/UBusMessages.h --- unity-5.6.0/plugins/unityshell/src/UBusMessages.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/UBusMessages.h 2012-03-23 11:53:16.000000000 +0000 @@ -64,6 +64,9 @@ // Signal to force the launcher into locked mode, (b) #define UBUS_LAUNCHER_LOCK_HIDE "LAUNCHER_LOCK_HIDE" +// Signal to emit changes to the launcher hide mode behaviour (b), true = locked out, false = unlocked +#define UBUS_LAUNCHER_HIDE_MODE_CHANGE "LAUNCHER_HIDE_MODE_CHANGE" + // Signal sent when a quicklist is shown. #define UBUS_QUICKLIST_SHOWN "QUICKLIST_SHOWN" @@ -78,6 +81,8 @@ // FIXME - fix the nux focus api so we don't need this #define UBUS_RESULT_VIEW_KEYNAV_CHANGED "RESULT_VIEW_KEYNAV_CHANGED" +// Sends a string datatype containing the new icon name +#define UBUS_HUD_ICON_CHANGED "HUD_ICON_CHANGED" #define UBUS_HUD_CLOSE_REQUEST "HUD_CLOSE_REQUEST" // Signals sent when the switcher is shown, hidden or changes selection diff -Nru unity-5.6.0/plugins/unityshell/src/ubus-server.cpp unity-5.8.0/plugins/unityshell/src/ubus-server.cpp --- unity-5.6.0/plugins/unityshell/src/ubus-server.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/ubus-server.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -195,6 +195,9 @@ UBusServer* server; static gsize singleton; + // Ensure GType has been initialized + g_type_init(); + if (g_once_init_enter(&singleton)) { server = (UBusServer*)g_object_new(UBUS_TYPE_SERVER, NULL); diff -Nru unity-5.6.0/plugins/unityshell/src/unityshell.cpp unity-5.8.0/plugins/unityshell/src/unityshell.cpp --- unity-5.6.0/plugins/unityshell/src/unityshell.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/unityshell.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -81,6 +81,7 @@ UnityScreen* uScreen = 0; +void reset_glib_logging(); void configure_logging(); void capture_g_log_calls(const gchar* log_domain, GLogLevelFlags log_level, @@ -93,6 +94,8 @@ { // Tap duration in milliseconds. const int ALT_TAP_DURATION = 250; +const unsigned int SCROLL_DOWN_BUTTON = 6; +const unsigned int SCROLL_UP_BUTTON = 7; } // namespace local } // anon namespace @@ -111,7 +114,6 @@ , _in_paint(false) , relayoutSourceId(0) , _redraw_handle(0) - , alt_tap_timeout_id_(0) , newFocusedWindow(nullptr) , doShellRepaint(false) , allowWindowPaint(false) @@ -124,7 +126,8 @@ , dash_is_open_ (false) , grab_index_ (0) , painting_tray_ (false) - , last_hud_show_time_(0) + , last_scroll_event_(0) + , hud_keypress_time_(0) { Timer timer; gfloat version; @@ -334,6 +337,9 @@ optionSetDecayRateNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); optionSetShowMinimizedWindowsNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); + optionSetNumLaunchersNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); + optionSetLauncherCaptureMouseNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); + ubus_manager_.RegisterInterest(UBUS_LAUNCHER_START_KEY_NAV, sigc::mem_fun(this, &UnityScreen::OnLauncherStartKeyNav)); @@ -372,13 +378,15 @@ if (relayoutSourceId != 0) g_source_remove(relayoutSourceId); - if (alt_tap_timeout_id_) - g_source_remove(alt_tap_timeout_id_); + if (_redraw_handle) + g_source_remove(_redraw_handle); ::unity::ui::IconRenderer::DestroyTextures(); QuicklistManager::Destroy(); - + // We need to delete the launchers before the window thread. + launcher_controller_.reset(); delete wt; + reset_glib_logging(); } void UnityScreen::initAltTabNextWindow() @@ -870,22 +878,25 @@ geo.height); } -void UnityScreen::EnableCancelAction(bool enabled, int modifiers) +void UnityScreen::EnableCancelAction(CancelActionTarget target, bool enabled, int modifiers) { if (enabled) { - /* Create a new keybinding for the Escape key and the current modifiers */ - CompAction::KeyBinding binding(9, modifiers); + /* Create a new keybinding for the Escape key and the current modifiers, + * compiz will take of the ref-counting of the repeated actions */ + KeyCode escape = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Escape")); + CompAction::KeyBinding binding(escape, modifiers); - _escape_action = CompActionPtr(new CompAction()); - _escape_action->setKey(binding); + CompActionPtr &escape_action = _escape_actions[target]; + escape_action = CompActionPtr(new CompAction()); + escape_action->setKey(binding); - screen->addAction(_escape_action.get()); + screen->addAction(escape_action.get()); } - else if (!enabled && _escape_action.get()) + else if (!enabled && _escape_actions[target].get()) { - screen->removeAction(_escape_action.get()); - _escape_action = nullptr; + screen->removeAction(_escape_actions[target].get()); + _escape_actions.erase(target); } } @@ -1226,7 +1237,7 @@ #ifdef USE_GLES void UnityScreen::glPaintCompositedOutput (const CompRegion ®ion, - GLFramebufferObject *fbo, + ::GLFramebufferObject *fbo, unsigned int mask) { bool useFbo = false; @@ -1237,11 +1248,11 @@ useFbo = fbo->checkStatus () && fbo->tex (); if (!useFbo) { printf ("bailing from UnityScreen::glPaintCompositedOutput"); - GLFramebufferObject::rebind (oldFbo); + ::GLFramebufferObject::rebind (oldFbo); return; } paintDisplay(); - GLFramebufferObject::rebind (oldFbo); + ::GLFramebufferObject::rebind (oldFbo); } gScreen->glPaintCompositedOutput(region, fbo, mask); @@ -1337,7 +1348,26 @@ if (super_keypressed_) { launcher_controller_->KeyNavTerminate(false); - EnableCancelAction(false); + EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false); + } + break; + case ButtonRelease: + if (switcher_controller_ && switcher_controller_->Visible()) + { + XButtonEvent *bev = reinterpret_cast(event); + if (bev->time - last_scroll_event_ > 150) + { + if (bev->button == Button4 || bev->button == local::SCROLL_UP_BUTTON) + { + switcher_controller_->Prev(); + last_scroll_event_ = bev->time; + } + else if (bev->button == Button5 || bev->button == local::SCROLL_DOWN_BUTTON) + { + switcher_controller_->Next(); + last_scroll_event_ = bev->time; + } + } } break; case KeyPress: @@ -1345,23 +1375,45 @@ KeySym key_sym; char key_string[2]; int result = XLookupString(&(event->xkey), key_string, 2, &key_sym, 0); + + if (launcher_controller_->KeyNavIsActive()) + { + if (key_sym == XK_Up) + { + launcher_controller_->KeyNavPrevious(); + break; + } + else if (key_sym == XK_Down) + { + launcher_controller_->KeyNavNext(); + break; + } + } + if (result > 0) { // NOTE: does this have the potential to do an invalid write? Perhaps // we should just say "key_string[1] = 0" because that is the only // thing that could possibly make sense here. key_string[result] = 0; - if (super_keypressed_ && key_sym != XK_Escape) + + if (super_keypressed_) { - g_idle_add([] (gpointer data) -> gboolean { - auto self = static_cast(data); - if (!self->launcher_controller_->KeyNavIsActive()) - { - self->shortcut_controller_->SetEnabled(false); - self->shortcut_controller_->Hide(); - } - return FALSE; - }, this); + if (key_sym != XK_Escape || (key_sym == XK_Escape && !launcher_controller_->KeyNavIsActive())) + { + /* We need an idle to postpone this action, after the current event + * has been processed */ + g_idle_add([] (gpointer data) -> gboolean { + auto self = static_cast(data); + if (!self->launcher_controller_->KeyNavIsActive()) + { + self->shortcut_controller_->SetEnabled(false); + self->shortcut_controller_->Hide(); + self->EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, false); + } + return FALSE; + }, this); + } skip_other_plugins = launcher_controller_->HandleLauncherKeyEvent(screen->dpy(), key_sym, event->xkey.keycode, event->xkey.state, key_string); if (!skip_other_plugins) @@ -1370,7 +1422,7 @@ if (skip_other_plugins && launcher_controller_->KeyNavIsActive()) { launcher_controller_->KeyNavTerminate(false); - EnableCancelAction(false); + EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false); } } } @@ -1485,7 +1537,8 @@ action->setState(action->state() | CompAction::StateTermKey); super_keypressed_ = true; - launcher_controller_->HandleLauncherKeyPress(); + int when = options[7].value().i(); // XEvent time in millisec + launcher_controller_->HandleLauncherKeyPress(when); EnsureSuperKeybindings (); if (!shortcut_controller_->Visible() && shortcut_controller_->IsEnabled()) @@ -1511,7 +1564,10 @@ } if (last_geo.x > monitor_geo.x and last_geo.y > monitor_geo.y) + { + EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, true, action->key().modifiers()); shortcut_controller_->Show(); + } } return true; @@ -1521,18 +1577,27 @@ CompAction::State state, CompOption::Vector& options) { + // Remember StateCancel and StateCommit will be broadcast to all actions + // so we need to verify that we are actually being toggled... + if (!(state & CompAction::StateTermKey)) + return false; + if (state & CompAction::StateCancel) return false; bool was_tap = state & CompAction::StateTermTapped; + LOG_DEBUG(logger) << "Super released: " << (was_tap ? "tapped" : "released"); + int when = options[7].value().i(); // XEvent time in millisec super_keypressed_ = false; launcher_controller_->KeyNavTerminate(true); - launcher_controller_->HandleLauncherKeyRelease(was_tap); - EnableCancelAction(false); + launcher_controller_->HandleLauncherKeyRelease(was_tap, when); + EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false); shortcut_controller_->SetEnabled(enable_shortcut_overlay_); shortcut_controller_->Hide(); + EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, false); + action->setState (action->state() & (unsigned)~(CompAction::StateTermKey)); return true; } @@ -1541,10 +1606,24 @@ CompAction::State state, CompOption::Vector& options) { - grab_index_ = screen->pushGrab (None, "unityshell"); - // to receive the Terminate event + /* In order to avoid too many events when keeping the keybinding pressed, + * that would make the unity-panel-service to go crazy (see bug #948522) + * we need to filter them, just considering an event every 750 ms */ + int event_time = options[7].value().i(); // XEvent time in millisec + + if (event_time - first_menu_keypress_time_ < 750) + { + first_menu_keypress_time_ = event_time; + return false; + } + + first_menu_keypress_time_ = event_time; + + /* Even if we do nothing on key terminate, we must enable it, not to to hide + * the menus entries after that a menu has been shown and hidden via the + * keyboard and the Alt key is still pressed */ action->setState(action->state() | CompAction::StateTermKey); - panel_controller_->StartFirstMenuShow(); + panel_controller_->FirstMenuShow(); return true; } @@ -1552,9 +1631,7 @@ CompAction::State state, CompOption::Vector& options) { - screen->removeGrab(grab_index_, NULL); action->setState (action->state() & (unsigned)~(CompAction::StateTermKey)); - panel_controller_->EndFirstMenuShow(); return true; } @@ -1601,24 +1678,26 @@ return true; } -bool UnityScreen::altTabInitiateCommon(switcher::ShowMode show_mode) +bool UnityScreen::altTabInitiateCommon(CompAction* action, switcher::ShowMode show_mode) { if (!grab_index_) grab_index_ = screen->pushGrab (screen->invisibleCursor(), "unity-switcher"); if (!grab_index_) return false; - if (alt_tap_timeout_id_) - { - g_source_remove(alt_tap_timeout_id_); - alt_tap_timeout_id_ = 0; - } - screen->addAction(&optionGetAltTabRight()); screen->addAction(&optionGetAltTabDetailStart()); screen->addAction(&optionGetAltTabDetailStop()); screen->addAction(&optionGetAltTabLeft()); + /* Create a new keybinding for scroll buttons and current modifiers */ + CompAction scroll_up; + CompAction scroll_down; + scroll_up.setButton(CompAction::ButtonBinding(local::SCROLL_UP_BUTTON, action->key().modifiers())); + scroll_down.setButton(CompAction::ButtonBinding(local::SCROLL_DOWN_BUTTON, action->key().modifiers())); + screen->addAction(&scroll_up); + screen->addAction(&scroll_down); + // maybe check launcher position/hide state? int device = screen->outputDeviceForPoint (pointerX, pointerY); @@ -1655,10 +1734,18 @@ screen->removeGrab(grab_index_, NULL); grab_index_ = 0; - screen->removeAction (&optionGetAltTabRight ()); - screen->removeAction (&optionGetAltTabDetailStart ()); - screen->removeAction (&optionGetAltTabDetailStop ()); - screen->removeAction (&optionGetAltTabLeft ()); + screen->removeAction(&optionGetAltTabRight ()); + screen->removeAction(&optionGetAltTabDetailStart ()); + screen->removeAction(&optionGetAltTabDetailStop ()); + screen->removeAction(&optionGetAltTabLeft ()); + + /* Removing the scroll actions */ + CompAction scroll_up; + CompAction scroll_down; + scroll_up.setButton(CompAction::ButtonBinding(local::SCROLL_UP_BUTTON, action->key().modifiers())); + scroll_down.setButton(CompAction::ButtonBinding(local::SCROLL_DOWN_BUTTON, action->key().modifiers())); + screen->removeAction(&scroll_up); + screen->removeAction(&scroll_down); bool accept_state = (state & CompAction::StateCancel) == 0; switcher_controller_->Hide(accept_state); @@ -1675,7 +1762,7 @@ if (switcher_controller_->Visible()) switcher_controller_->Next(); else - altTabInitiateCommon(switcher::ShowMode::CURRENT_VIEWPORT); + altTabInitiateCommon(action, switcher::ShowMode::CURRENT_VIEWPORT); action->setState(action->state() | CompAction::StateTermKey); return true; @@ -1688,7 +1775,7 @@ if (switcher_controller_->Visible()) switcher_controller_->Next(); else - altTabInitiateCommon(switcher::ShowMode::ALL); + altTabInitiateCommon(action, switcher::ShowMode::ALL); action->setState(action->state() | CompAction::StateTermKey); return true; @@ -1697,40 +1784,52 @@ bool UnityScreen::altTabPrevAllInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (switcher_controller_->Visible()) + { switcher_controller_->Prev(); + return true; + } - return true; + return false; } bool UnityScreen::altTabPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (switcher_controller_->Visible()) + { switcher_controller_->Prev(); + return true; + } - return true; + return false; } bool UnityScreen::altTabDetailStartInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (switcher_controller_->Visible()) + { switcher_controller_->SetDetail(true); + return true; + } - return true; + return false; } bool UnityScreen::altTabDetailStopInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (switcher_controller_->Visible()) + { switcher_controller_->SetDetail(false); + return true; + } - return true; + return false; } bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (!switcher_controller_->Visible()) { - altTabInitiateCommon(switcher::ShowMode::CURRENT_VIEWPORT); + altTabInitiateCommon(action, switcher::ShowMode::CURRENT_VIEWPORT); switcher_controller_->Select(1); // always select the current application } @@ -1743,17 +1842,34 @@ bool UnityScreen::altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (switcher_controller_->Visible()) + { switcher_controller_->PrevDetail(); + return true; + } - return true; + return false; } bool UnityScreen::launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { if (!launcher_controller_->KeyNavIsActive()) { + int modifiers = action->key().modifiers(); + launcher_controller_->KeyNavActivate(); - EnableCancelAction(true, action->key().modifiers()); + + EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, true, modifiers); + + KeyCode down_key = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Down")); + KeyCode up_key = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Up")); + + CompAction down_action; + down_action.setKey(CompAction::KeyBinding(down_key, modifiers)); + screen->addAction(&down_action); + + CompAction up_action; + up_action.setKey(CompAction::KeyBinding(up_key, modifiers)); + screen->addAction(&up_action); } else { @@ -1774,7 +1890,19 @@ bool accept_state = (state & CompAction::StateCancel) == 0; launcher_controller_->KeyNavTerminate(accept_state); - EnableCancelAction(false); + EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false); + + KeyCode down_key = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Down")); + KeyCode up_key = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Up")); + + CompAction down_action; + down_action.setKey(CompAction::KeyBinding(down_key, action->key().modifiers())); + screen->removeAction(&down_action); + + CompAction up_action; + up_action.setKey(CompAction::KeyBinding(up_key, action->key().modifiers())); + screen->removeAction(&up_action); + action->setState (action->state() & (unsigned)~(CompAction::StateTermKey)); return true; } @@ -1806,20 +1934,7 @@ // to receive the Terminate event if (state & CompAction::StateInitKey) action->setState(action->state() | CompAction::StateTermKey); - last_hud_show_time_ = g_get_monotonic_time(); - - /* Workaround to fix #943194 */ - alt_tap_timeout_id_ = g_timeout_add(local::ALT_TAP_DURATION, [] (gpointer data) -> gboolean { - auto self = static_cast(data); - - if (!self->switcher_controller_->Visible()) - { - XUngrabKeyboard(self->screen->dpy(), CurrentTime); - } - - self->alt_tap_timeout_id_ = 0; - return FALSE; - }, this); + hud_keypress_time_ = options[7].value().i(); // XEvent time in millisec // pass key through return false; @@ -1840,14 +1955,9 @@ if (!(state & CompAction::StateTermTapped)) return false; - if (alt_tap_timeout_id_) - { - g_source_remove(alt_tap_timeout_id_); - alt_tap_timeout_id_ = 0; - } - - gint64 current_time = g_get_monotonic_time(); - if (current_time - last_hud_show_time_ > (local::ALT_TAP_DURATION * 1000)) + int release_time = options[7].value().i(); // XEvent time in millisec + int tap_duration = release_time - hud_keypress_time_; + if (tap_duration > local::ALT_TAP_DURATION) { LOG_DEBUG(logger) << "Tap too long"; return false; @@ -1865,6 +1975,11 @@ } else { + // Handles closing KeyNav (Alt+F1) if the hud is about to show + if (launcher_controller_->KeyNavIsActive()) + { + launcher_controller_->KeyNavTerminate(false); + } hud_controller_->ShowHud(); } @@ -2402,6 +2517,13 @@ unity::launcher::Options::Ptr launcher_options = launcher_controller_->options(); switch (num) { + case UnityshellOptions::NumLaunchers: + launcher_controller_->multiple_launchers = optionGetNumLaunchers() == 0; + dash_controller_->use_primary = !launcher_controller_->multiple_launchers(); + break; + case UnityshellOptions::LauncherCaptureMouse: + launcher_options->edge_resist = optionGetLauncherCaptureMouse(); + break; case UnityshellOptions::BackgroundColor: { nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f, @@ -2416,8 +2538,11 @@ break; } case UnityshellOptions::LauncherHideMode: + { launcher_options->hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode(); + hud_controller_->SetLauncherIsLockedOut(launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); break; + } case UnityshellOptions::BacklightMode: launcher_options->backlight_mode = (unity::launcher::BacklightMode) optionGetBacklightMode(); break; @@ -2649,12 +2774,15 @@ /* Setup Hud */ hud_controller_.reset(new hud::Controller()); + auto hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode(); + hud_controller_->SetLauncherIsLockedOut(hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); AddChild(hud_controller_.get()); LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s"; // Setup Shortcut Hint InitHints(); shortcut_controller_.reset(new shortcut::Controller(hints_)); + AddChild(shortcut_controller_.get()); AddChild(dash_controller_.get()); @@ -2666,17 +2794,17 @@ // TODO move category text into a vector... // Launcher... - std::string const launcher = _("Launcher"); + std::string const launcher(_("Launcher")); hints_.push_back(new shortcut::Hint(launcher, "", _(" (Press)"), _("Open Launcher, displays shortcuts."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher" )); hints_.push_back(new shortcut::Hint(launcher, "", "", _("Open Launcher keyboard navigation mode."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "keyboard_focus")); - hints_.push_back(new shortcut::Hint(launcher, "", "", _("Switch applications via Launcher."), shortcut::HARDCODED_OPTION, _("Super + Tab"))); + hints_.push_back(new shortcut::Hint(launcher, "", "", _("Switch applications via Launcher."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "launcher_switcher_forward")); hints_.push_back(new shortcut::Hint(launcher, "", _(" + 1 to 9"), _("Same as clicking on a Launcher icon."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); hints_.push_back(new shortcut::Hint(launcher, "", _(" + Shift + 1 to 9"), _("Open new window of the app."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); hints_.push_back(new shortcut::Hint(launcher, "", " + T", _("Open the Trash."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); // Dash... - std::string const dash = _("Dash"); + std::string const dash( _("Dash")); hints_.push_back(new shortcut::Hint(dash, "", _(" (Tap)"), _("Open the Dash Home."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); hints_.push_back(new shortcut::Hint(dash, "", " + A", _("Open the Dash App Lens."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); @@ -2685,30 +2813,31 @@ hints_.push_back(new shortcut::Hint(dash, "", "", _("Switches between Lenses."), shortcut::HARDCODED_OPTION, _("Ctrl + Tab"))); hints_.push_back(new shortcut::Hint(dash, "", "", _("Moves the focus."), shortcut::HARDCODED_OPTION, _("Cursor Keys"))); hints_.push_back(new shortcut::Hint(dash, "", "", _("Open currently focused item."), shortcut::HARDCODED_OPTION, _("Enter & Return"))); - hints_.push_back(new shortcut::Hint(dash, "", "", _("'Run Command' mode."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "execute_command")); // Menu Bar - std::string const menubar = _("Menu Bar"); - - hints_.push_back(new shortcut::Hint(menubar, "", "", _("Reveals application menu."), shortcut::HARDCODED_OPTION, "Alt")); + std::string const menubar(_("HUD & Menu Bar")); + + hints_.push_back(new shortcut::Hint(menubar, "", " (Tap)", _("Open the HUD."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_hud")); + hints_.push_back(new shortcut::Hint(menubar, "", " (Press)", _("Reveals application menu."), shortcut::HARDCODED_OPTION, "Alt")); hints_.push_back(new shortcut::Hint(menubar, "", "", _("Opens the indicator menu."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "panel_first_menu")); hints_.push_back(new shortcut::Hint(menubar, "", "", _("Moves focus between indicators."), shortcut::HARDCODED_OPTION, _("Cursor Left or Right"))); // Switching - std::string const switching = _("Switching"); + std::string const switching(_("Switching")); hints_.push_back(new shortcut::Hint(switching, "", "", _("Switch between applications."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "alt_tab_forward")); hints_.push_back(new shortcut::Hint(switching, "", "", _("Switch windows of current application."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "alt_tab_next_window")); hints_.push_back(new shortcut::Hint(switching, "", "", _("Moves the focus."), shortcut::HARDCODED_OPTION, _("Cursor Left or Right"))); // Workspaces - std::string const workspaces = _("Workspaces"); + std::string const workspaces(_("Workspaces")); + hints_.push_back(new shortcut::Hint(workspaces, "", "", _("Spread workspaces."), shortcut::COMPIZ_KEY_OPTION, "expo", "expo_key")); - hints_.push_back(new shortcut::Hint(workspaces, "", "", _("Switch workspaces."), shortcut::HARDCODED_OPTION, _("Control + Alt + Cursor Keys"))); - hints_.push_back(new shortcut::Hint(workspaces, "", "", _("Move focused window to different workspace."), shortcut::HARDCODED_OPTION, _("Control + Alt + Shift + Cursor Keys"))); + hints_.push_back(new shortcut::Hint(workspaces, "", _(" + Cursor Keys"), _("Switch workspaces."), shortcut::COMPIZ_METAKEY_OPTION, "wall", "left_key")); + hints_.push_back(new shortcut::Hint(workspaces, "", _(" + Cursor Keys"), _("Move focused window to different workspace."), shortcut::COMPIZ_METAKEY_OPTION, "wall", "left_window_key")); // Windows - std::string const windows = _("Windows"); + std::string const windows(_("Windows")); hints_.push_back(new shortcut::Hint(windows, "", "", _("Spreads all windows in the current workspace."), shortcut::COMPIZ_KEY_OPTION, "scale", "initiate_all_key")); hints_.push_back(new shortcut::Hint(windows, "", "", _("Minimises all windows."), shortcut::COMPIZ_KEY_OPTION, "core", "show_desktop_key")); hints_.push_back(new shortcut::Hint(windows, "", "", _("Maximises the current window."), shortcut::COMPIZ_KEY_OPTION, "core", "maximize_window_key")); @@ -2841,6 +2970,12 @@ namespace { +void reset_glib_logging() +{ + // Reinstate the default glib logger. + g_log_set_default_handler(g_log_default_handler, NULL); +} + void configure_logging() { // The default behaviour of the logging infrastructure is to send all output diff -Nru unity-5.6.0/plugins/unityshell/src/unityshell.h unity-5.8.0/plugins/unityshell/src/unityshell.h --- unity-5.6.0/plugins/unityshell/src/unityshell.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/unityshell.h 2012-03-23 11:53:16.000000000 +0000 @@ -163,7 +163,7 @@ unsigned int); #ifdef USE_GLES void glPaintCompositedOutput (const CompRegion ®ion, - GLFramebufferObject *fbo, + ::GLFramebufferObject *fbo, unsigned int mask); #endif @@ -192,7 +192,7 @@ bool executeCommand(CompAction* action, CompAction::State state, CompOption::Vector& options); bool setKeyboardFocusKeyInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); - bool altTabInitiateCommon(switcher::ShowMode mode); + bool altTabInitiateCommon(CompAction* action, switcher::ShowMode mode); bool altTabTerminateCommon(CompAction* action, CompAction::State state, CompOption::Vector& options); @@ -236,13 +236,19 @@ void AddProperties(GVariantBuilder* builder); private: + enum CancelActionTarget + { + LAUNCHER_SWITCHER, + SHORTCUT_HINT + }; + void initAltTabNextWindow (); void SendExecuteCommand(); void EnsureSuperKeybindings(); void CreateSuperNewAction(char shortcut, impl::ActionModifiers flag); - void EnableCancelAction(bool enabled, int modifiers = 0); + void EnableCancelAction(CancelActionTarget target, bool enabled, int modifiers = 0); static gboolean initPluginActions(gpointer data); void initLauncher(); @@ -290,12 +296,11 @@ bool _in_paint; guint32 relayoutSourceId; guint32 _redraw_handle; - guint32 alt_tap_timeout_id_; typedef std::shared_ptr CompActionPtr; typedef std::vector ShortcutActions; ShortcutActions _shortcut_actions; bool super_keypressed_; - CompActionPtr _escape_action; + std::map _escape_actions; /* keyboard-nav mode */ CompWindow* newFocusedWindow; @@ -316,7 +321,7 @@ unity::BGHash _bghash; #ifdef USE_GLES - GLFramebufferObject *oldFbo; + ::GLFramebufferObject *oldFbo; #else ScreenEffectFramebufferObject::Ptr _fbo; GLuint _active_fbo; @@ -331,7 +336,9 @@ CompWindowList fullscreen_windows_; bool painting_tray_; unsigned int tray_paint_mask_; - gint64 last_hud_show_time_; + unsigned int last_scroll_event_; + int hud_keypress_time_; + int first_menu_keypress_time_; GLMatrix panel_shadow_matrix_; diff -Nru unity-5.6.0/plugins/unityshell/src/UnityWindowStyle.cpp unity-5.8.0/plugins/unityshell/src/UnityWindowStyle.cpp --- unity-5.6.0/plugins/unityshell/src/UnityWindowStyle.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/UnityWindowStyle.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -18,6 +18,7 @@ */ #include "UnityWindowStyle.h" +#include "config.h" namespace unity { namespace ui { diff -Nru unity-5.6.0/plugins/unityshell/src/UnityWindowView.cpp unity-5.8.0/plugins/unityshell/src/UnityWindowView.cpp --- unity-5.6.0/plugins/unityshell/src/UnityWindowView.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/UnityWindowView.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -67,6 +67,8 @@ nux::Geometry geo_absolute = GetAbsoluteGeometry (); + + if (BackgroundEffectHelper::blur_type != BLUR_NONE) { nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, base.width, base.height); @@ -85,20 +87,44 @@ rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - gPainter.PushDrawTextureLayer(GfxContext, base, - blur_texture, - texxform_blur_bg, - nux::color::White, - true, - rop); +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath()) + gPainter.PushDrawCompositionLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); + else + gPainter.PushDrawTextureLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + true, + rop); +#else + gPainter.PushDrawCompositionLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); +#endif + } } nux::ROPConfig rop; rop.Blend = true; - rop.SrcBlend = GL_ONE; - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - gPainter.PushDrawColorLayer (GfxContext, internal_clip, background_color, false, rop); + +#ifndef NUX_OPENGLES_20 + if (GfxContext.UsingGLSLCodePath() == FALSE) + { + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + gPainter.PushDrawColorLayer (GfxContext, internal_clip, background_color, false, rop); + } +#endif // Make round corners rop.Blend = true; @@ -107,7 +133,7 @@ gPainter.PaintShapeCornerROP(GfxContext, internal_clip, nux::color::White, - nux::eSHAPE_CORNER_ROUND4, + nux::eSHAPE_CORNER_ROUND5, nux::eCornerTopLeft | nux::eCornerTopRight | nux::eCornerBottomLeft | nux::eCornerBottomRight, true, diff -Nru unity-5.6.0/plugins/unityshell/src/UScreen.cpp unity-5.8.0/plugins/unityshell/src/UScreen.cpp --- unity-5.6.0/plugins/unityshell/src/UScreen.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/UScreen.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -119,8 +119,7 @@ g_print("\nScreen geometry changed:\n"); - int lowest_x = std::numeric_limits::max(); - int highest_y = std::numeric_limits::min(); + primary_ = gdk_screen_get_primary_monitor(screen); for (int i = 0; i < gdk_screen_get_n_monitors(screen); i++) { GdkRectangle rect = { 0 }; @@ -136,13 +135,6 @@ _monitors.push_back(geo); - if (geo.x < lowest_x || (geo.x == lowest_x && geo.y > highest_y)) - { - lowest_x = geo.x; - highest_y = geo.y; - primary_ = i; - } - g_print(" %dx%dx%dx%d\n", geo.x, geo.y, geo.width, geo.height); } diff -Nru unity-5.6.0/plugins/unityshell/src/WindowButtons.cpp unity-5.8.0/plugins/unityshell/src/WindowButtons.cpp --- unity-5.6.0/plugins/unityshell/src/WindowButtons.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/src/WindowButtons.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,7 +39,8 @@ #include -using namespace unity; +namespace unity +{ class WindowButton : public nux::Button { @@ -48,12 +49,6 @@ WindowButton(panel::WindowButtonType type) : nux::Button("", NUX_TRACKER_LOCATION), _type(type), - _normal_tex(NULL), - _prelight_tex(NULL), - _pressed_tex(NULL), - _normal_dash_tex(NULL), - _prelight_dash_tex(NULL), - _pressed_dash_tex(NULL), _overlay_is_open(false), _mouse_is_down(false), _place_shown_interest(0), @@ -84,13 +79,6 @@ ~WindowButton() { - _normal_tex->UnReference(); - _prelight_tex->UnReference(); - _pressed_tex->UnReference(); - _normal_dash_tex->UnReference(); - _prelight_dash_tex->UnReference(); - _pressed_dash_tex->UnReference(); - UBusServer* ubus = ubus_server_get_default(); if (_place_shown_interest != 0) ubus_server_unregister_interest(ubus, _place_shown_interest); @@ -101,7 +89,7 @@ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { nux::Geometry geo = GetGeometry(); - nux::BaseTexture* tex; + nux::BaseTexture* tex = nullptr; nux::TexCoordXForm texxform; GfxContext.PushClippingRectangle(geo); @@ -110,28 +98,28 @@ { if (_type == panel::WindowButtonType::UNMAXIMIZE && !_overlay_can_maximize) { - tex = _disabled_dash_tex; + tex = _disabled_dash_tex.GetPointer(); } else { //FIXME should use HasMouseFocus() if (_mouse_is_down && IsMouseInside()) - tex = _pressed_dash_tex; + tex = _pressed_dash_tex.GetPointer(); else if (IsMouseInside()) - tex = _prelight_dash_tex; + tex = _prelight_dash_tex.GetPointer(); else - tex = _normal_dash_tex; + tex = _normal_dash_tex.GetPointer(); } } else { //FIXME should use HasMouseFocus() if (_mouse_is_down && IsMouseInside()) - tex = _pressed_tex; + tex = _pressed_tex.GetPointer(); else if (IsMouseInside()) - tex = _prelight_tex; + tex = _prelight_tex.GetPointer(); else - tex = _normal_tex; + tex = _normal_tex.GetPointer(); } if (tex) @@ -150,25 +138,12 @@ { panel::Style& style = panel::Style::Instance(); - if (_normal_tex) - _normal_tex->UnReference(); - if (_prelight_tex) - _prelight_tex->UnReference(); - if (_pressed_tex) - _pressed_tex->UnReference(); - if (_normal_dash_tex) - _normal_dash_tex->UnReference(); - if (_prelight_dash_tex) - _prelight_dash_tex->UnReference(); - if (_pressed_dash_tex) - _pressed_dash_tex->UnReference(); - - _normal_tex = style.GetWindowButton(_type, panel::WindowState::NORMAL); - _prelight_tex = style.GetWindowButton(_type, panel::WindowState::PRELIGHT); - _pressed_tex = style.GetWindowButton(_type, panel::WindowState::PRESSED); - _normal_dash_tex = GetDashWindowButton(_type, panel::WindowState::NORMAL); - _prelight_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRELIGHT); - _pressed_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRESSED); + _normal_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::NORMAL)); + _prelight_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::PRELIGHT)); + _pressed_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::PRESSED)); + _normal_dash_tex.Adopt(GetDashWindowButton(_type, panel::WindowState::NORMAL)); + _prelight_dash_tex.Adopt(GetDashWindowButton(_type, panel::WindowState::PRELIGHT)); + _pressed_dash_tex.Adopt(GetDashWindowButton(_type, panel::WindowState::PRESSED)); if (_overlay_is_open) { @@ -197,19 +172,12 @@ real_type = panel::WindowButtonType::MAXIMIZE; } - if (_normal_dash_tex) - _normal_dash_tex->UnReference(); - if (_prelight_dash_tex) - _prelight_dash_tex->UnReference(); - if (_pressed_dash_tex) - _pressed_dash_tex->UnReference(); - //!!FIXME!! - don't have disabled instances of the (un)maximize buttons // get (un)maximize buttons - _normal_dash_tex = GetDashWindowButton(real_type, panel::WindowState::NORMAL); - _prelight_dash_tex = GetDashWindowButton(real_type, panel::WindowState::PRELIGHT); - _pressed_dash_tex = GetDashWindowButton(real_type, panel::WindowState::PRESSED); - _disabled_dash_tex = GetDashWindowButton(real_type, panel::WindowState::DISABLED); + _normal_dash_tex.Adopt(GetDashWindowButton(real_type, panel::WindowState::NORMAL)); + _prelight_dash_tex.Adopt(GetDashWindowButton(real_type, panel::WindowState::PRELIGHT)); + _pressed_dash_tex.Adopt(GetDashWindowButton(real_type, panel::WindowState::PRESSED)); + _disabled_dash_tex.Adopt(GetDashWindowButton(real_type, panel::WindowState::DISABLED)); // still check if the dash is really opened, // someone could change the form factor through dconf @@ -239,14 +207,14 @@ private: panel::WindowButtonType _type; - // FIXME - replace with objectptr varients - nux::BaseTexture* _normal_tex; - nux::BaseTexture* _prelight_tex; - nux::BaseTexture* _pressed_tex; - nux::BaseTexture* _normal_dash_tex; - nux::BaseTexture* _prelight_dash_tex; - nux::BaseTexture* _pressed_dash_tex; - nux::BaseTexture* _disabled_dash_tex; + typedef nux::ObjectPtr BaseTexturePtr; + BaseTexturePtr _normal_tex; + BaseTexturePtr _prelight_tex; + BaseTexturePtr _pressed_tex; + BaseTexturePtr _normal_dash_tex; + BaseTexturePtr _prelight_dash_tex; + BaseTexturePtr _pressed_dash_tex; + BaseTexturePtr _disabled_dash_tex; bool _overlay_is_open; bool _overlay_can_maximize; @@ -260,7 +228,7 @@ unity::glib::String overlay_identity; gboolean can_maximise = FALSE; gint32 overlay_monitor = 0; - g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, + g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); WindowButton* self = (WindowButton*)val; @@ -423,3 +391,6 @@ { unity::variant::BuilderWrapper(builder).add(GetGeometry()); } + + +} // namespace unity diff -Nru unity-5.6.0/plugins/unityshell/unityshell.xml.in unity-5.8.0/plugins/unityshell/unityshell.xml.in --- unity-5.6.0/plugins/unityshell/unityshell.xml.in 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/plugins/unityshell/unityshell.xml.in 2012-03-23 11:53:16.000000000 +0000 @@ -111,70 +111,70 @@ <_short>Switcher + + + diff -Nru unity-5.6.0/po/POTFILES.in unity-5.8.0/po/POTFILES.in --- unity-5.6.0/po/POTFILES.in 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/po/POTFILES.in 2012-03-23 11:53:16.000000000 +0000 @@ -1,22 +1,37 @@ +plugins/gtkloader/gtkloader.xml.in +plugins/networkarearegion/networkarearegion.xml.in +plugins/unitydialog/unitydialog.xml.in +plugins/unity-mt-grab-handles/unitymtgrabhandles.xml.in plugins/unityshell/src/BamfLauncherIcon.cpp -plugins/unityshell/src/DeviceLauncherIcon.cpp -plugins/unityshell/src/LauncherController.cpp -plugins/unityshell/src/PanelMenuView.cpp -plugins/unityshell/src/PlacesGroup.cpp -plugins/unityshell/src/SpacerLauncherIcon.cpp -plugins/unityshell/src/TrashLauncherIcon.cpp plugins/unityshell/src/BFBLauncherIcon.cpp -plugins/unityshell/src/SearchBar.cpp +plugins/unityshell/src/DashStyle.cpp plugins/unityshell/src/DashView.cpp plugins/unityshell/src/DesktopLauncherIcon.cpp +plugins/unityshell/src/DeviceLauncherIcon.cpp +plugins/unityshell/src/FilterAllButton.cpp plugins/unityshell/src/FilterExpanderLabel.cpp plugins/unityshell/src/FilterGenreWidget.cpp plugins/unityshell/src/FilterMultiRangeWidget.cpp plugins/unityshell/src/FilterRatingsWidget.cpp +plugins/unityshell/src/HudController.cpp +plugins/unityshell/src/HudView.cpp +plugins/unityshell/src/LauncherController.cpp +plugins/unityshell/src/LensView.cpp +plugins/unityshell/src/PanelMenuView.cpp +plugins/unityshell/src/PlacesGroup.cpp plugins/unityshell/src/PreviewMusic.cpp plugins/unityshell/src/PreviewMusicTrack.cpp +plugins/unityshell/src/SearchBar.cpp plugins/unityshell/src/ShortcutHintPrivate.cpp +plugins/unityshell/src/ShortcutView.cpp +plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp +plugins/unityshell/src/SpacerLauncherIcon.cpp +plugins/unityshell/src/TrashLauncherIcon.cpp +plugins/unityshell/src/unity-dash-view-accessible.cpp plugins/unityshell/src/unity-launcher-accessible.cpp +plugins/unityshell/src/unity-quicklist-menu-accessible.cpp plugins/unityshell/src/unity-search-bar-accessible.cpp plugins/unityshell/src/unityshell.cpp +plugins/unityshell/src/unity-switcher-accessible.cpp plugins/unityshell/unityshell.xml.in + diff -Nru unity-5.6.0/po/POTFILES.skip unity-5.8.0/po/POTFILES.skip --- unity-5.6.0/po/POTFILES.skip 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/po/POTFILES.skip 2012-03-23 11:53:16.000000000 +0000 @@ -1 +1,5 @@ +standalone-clients/StandaloneHud.cpp +standalone-clients/TestShortcut.cpp +tests/test_glib_signals.cpp +tests/test_home_lens.cpp diff -Nru unity-5.6.0/services/CMakeLists.txt unity-5.8.0/services/CMakeLists.txt --- unity-5.6.0/services/CMakeLists.txt 2012-03-23 14:02:25.000000000 +0000 +++ unity-5.8.0/services/CMakeLists.txt 2012-03-23 14:02:25.000000000 +0000 @@ -2,7 +2,7 @@ # Panel Service # find_package(PkgConfig) -pkg_check_modules(SERVICE_DEPS REQUIRED gtk+-3.0>=3.3 gobject-2.0 gio-2.0 gthread-2.0 indicator3-0.4 x11 gconf-2.0) +pkg_check_modules(SERVICE_DEPS REQUIRED gtk+-3.0>=3.3 gobject-2.0 gio-2.0 gthread-2.0 indicator3-0.4>=0.4.90 x11 gconf-2.0) execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} indicator3-0.4 --variable indicatordir OUTPUT_VARIABLE _indicatordir OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} indicator3-0.4 --variable iconsdir OUTPUT_VARIABLE _iconsdir OUTPUT_STRIP_TRAILING_WHITESPACE) diff -Nru unity-5.6.0/services/panel-indicator-entry-accessible.c unity-5.8.0/services/panel-indicator-entry-accessible.c --- unity-5.6.0/services/panel-indicator-entry-accessible.c 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-indicator-entry-accessible.c 2012-03-23 11:53:16.000000000 +0000 @@ -46,7 +46,8 @@ #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, PanelIndicatorEntryAccessiblePrivate)) static void -on_entry_activated_cb (PanelService *service, const gchar *entry_id, gpointer user_data) +on_entry_activated_cb (PanelService *service, const gchar *entry_id, + gint x, gint y, guint w, guint h, gpointer user_data) { gchar *s; gboolean adding = FALSE; @@ -251,7 +252,8 @@ g_return_val_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (accessible), 0); piea = PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible); - if (GTK_IS_MENU (piea->priv->entry->menu)) + + if (piea->priv->entry->parent_object && GTK_IS_MENU (piea->priv->entry->menu)) n_children = 1; return n_children; @@ -266,7 +268,7 @@ g_return_val_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (accessible), NULL); piea = PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible); - if (GTK_IS_MENU (piea->priv->entry->menu)) + if (piea->priv->entry->parent_object && GTK_IS_MENU (piea->priv->entry->menu)) { child = gtk_widget_get_accessible (GTK_WIDGET (piea->priv->entry->menu)); atk_object_set_parent (child, accessible); diff -Nru unity-5.6.0/services/panel-main.c unity-5.8.0/services/panel-main.c --- unity-5.6.0/services/panel-main.c 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-main.c 2012-03-23 11:53:16.000000000 +0000 @@ -58,13 +58,21 @@ " " " " " " - "" + "" " " " " + " " + " " + " " + " " " " + " " + "" + " " + " " " " " " - " " + " " " " "" " " @@ -79,6 +87,7 @@ "" " " " " + " " " " "" " " @@ -174,18 +183,31 @@ } else if (g_strcmp0 (method_name, "ShowEntry") == 0) { + guint32 xid; gchar *entry_id; - guint32 timestamp; gint32 x; gint32 y; - gint32 button; - g_variant_get (parameters, "(suiii)", &entry_id, ×tamp, &x, &y, &button, NULL); + guint32 button; + guint32 timestamp; + g_variant_get (parameters, "(suiiuu)", &entry_id, &xid, &x, &y, &button, ×tamp, NULL); - panel_service_show_entry (service, entry_id, timestamp, x, y, button); + panel_service_show_entry (service, entry_id, xid, x, y, button, timestamp); g_dbus_method_invocation_return_value (invocation, NULL); g_free (entry_id); } + else if (g_strcmp0 (method_name, "ShowAppMenu") == 0) + { + guint32 xid; + gint32 x; + gint32 y; + guint32 timestamp; + g_variant_get (parameters, "(uiiu)", &xid, &x, &y, ×tamp, NULL); + + panel_service_show_app_menu (service, xid, x, y, timestamp); + + g_dbus_method_invocation_return_value (invocation, NULL); + } else if (g_strcmp0 (method_name, "SecondaryActivateEntry") == 0) { gchar *entry_id; @@ -229,6 +251,7 @@ static void on_service_entry_activated (PanelService *service, const gchar *entry_id, + gint x, gint y, guint w, guint h, GDBusConnection *connection) { GError *error = NULL; @@ -237,7 +260,7 @@ S_PATH, S_IFACE, "EntryActivated", - g_variant_new ("(s)", entry_id), + g_variant_new ("(s(iiuu))", entry_id, x, y, w, h), &error); if (error) diff -Nru unity-5.6.0/services/panel-marshal.list unity-5.8.0/services/panel-marshal.list --- unity-5.6.0/services/panel-marshal.list 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-marshal.list 2012-03-23 11:53:16.000000000 +0000 @@ -1,2 +1,3 @@ NONE:OBJECT,POINTER,INT,INT,INT,INT VOID:STRING,BOOLEAN +VOID:STRING,INT,INT,UINT,UINT diff -Nru unity-5.6.0/services/panel-root-accessible.c unity-5.8.0/services/panel-root-accessible.c --- unity-5.6.0/services/panel-root-accessible.c 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-root-accessible.c 2012-03-23 11:53:16.000000000 +0000 @@ -134,16 +134,16 @@ if (INDICATOR_IS_OBJECT (indicator)) { AtkObject *child; - gpointer *data; + gpointer *weak_data; child = panel_indicator_accessible_new (indicator); /* FIXME: use proper signals once we support dynamic adding/removing * of indicators */ - data = g_new0 (gpointer, 2); - data[0] = root; - data[1] = child; + weak_data = g_new0 (gpointer, 2); + weak_data[0] = root; + weak_data[1] = child; g_object_weak_ref (G_OBJECT (indicator), - (GWeakNotify) on_indicator_removed, data); + (GWeakNotify) on_indicator_removed, weak_data); atk_object_set_parent (child, accessible); root->priv->a11y_children = g_slist_append (root->priv->a11y_children, child); diff -Nru unity-5.6.0/services/panel-service.c unity-5.8.0/services/panel-service.c --- unity-5.6.0/services/panel-service.c 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-service.c 2012-03-23 11:53:16.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C; indent-tabs-mode: nil; tab-width: 2 -*- /* - * 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 @@ -27,8 +27,10 @@ #include "panel-service.h" #include +#include #include #include +#include #include #include @@ -44,12 +46,15 @@ #define N_TIMEOUT_SLOTS 50 #define MAX_INDICATOR_ENTRIES 50 +#define COMPIZ_OPTIONS_PATH "/apps/compiz-1/plugins/unityshell/screen0/options" +#define MENU_TOGGLE_KEYBINDING_PATH COMPIZ_OPTIONS_PATH"/panel_first_menu" + static PanelService *static_service = NULL; struct _PanelServicePrivate { GSList *indicators; - GHashTable *entry2indicator_hash; + GHashTable *id2entry_hash; GHashTable *panel2entries_hash; guint initial_sync_id; @@ -69,6 +74,10 @@ gint last_bottom; guint32 last_menu_button; + KeyCode toggle_key; + guint32 toggle_modifiers; + guint32 key_monitor_id; + IndicatorObjectEntry *pressed_entry; gboolean use_event; }; @@ -121,7 +130,6 @@ static void sort_indicators (PanelService *self); static void notify_object (IndicatorObject *object); -static IndicatorObjectEntry *get_entry_at (PanelService *self, gint x, gint y); static GdkFilterReturn event_filter (GdkXEvent *ev, GdkEvent *gev, @@ -137,24 +145,27 @@ PanelServicePrivate *priv = PANEL_SERVICE (object)->priv; gint i; - g_hash_table_destroy (priv->entry2indicator_hash); + g_hash_table_destroy (priv->id2entry_hash); g_hash_table_destroy (priv->panel2entries_hash); gdk_window_remove_filter (NULL, (GdkFilterFunc)event_filter, object); - if (G_IS_OBJECT (priv->menubar)) + if (GTK_IS_WIDGET (priv->menubar) && + gtk_widget_get_realized (GTK_WIDGET (priv->menubar))) { g_object_unref (priv->menubar); priv->menubar = NULL; } - if (G_IS_OBJECT (priv->offscreen_window)) + if (GTK_IS_WIDGET (priv->offscreen_window) && + gtk_widget_get_realized (GTK_WIDGET (priv->offscreen_window))) { g_object_unref (priv->offscreen_window); priv->offscreen_window = NULL; } - if (G_IS_OBJECT (priv->last_menu)) + if (GTK_IS_WIDGET (priv->last_menu) && + gtk_widget_get_realized (GTK_WIDGET (priv->last_menu))) { g_object_unref (priv->last_menu); priv->last_menu = NULL; @@ -175,15 +186,28 @@ } } + if (priv->key_monitor_id) + { + gconf_client_notify_remove (gconf_client_get_default(), priv->key_monitor_id); + priv->key_monitor_id = 0; + } + G_OBJECT_CLASS (panel_service_parent_class)->dispose (object); } static void +panel_service_class_finalize (GObject *object) +{ + static_service = NULL; +} + +static void panel_service_class_init (PanelServiceClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->dispose = panel_service_class_dispose; + obj_class->finalize = panel_service_class_finalize; /* Signals */ _service_signals[ENTRY_ACTIVATED] = @@ -192,8 +216,9 @@ G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + panel_marshal_VOID__STRING_INT_INT_UINT_UINT, + G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, + G_TYPE_UINT, G_TYPE_UINT); _service_signals[RE_SYNC] = g_signal_new ("re-sync", @@ -212,6 +237,7 @@ NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + _service_signals[GEOMETRIES_CHANGED] = g_signal_new ("geometries-changed", G_OBJECT_CLASS_TYPE (obj_class), @@ -245,6 +271,82 @@ g_type_class_add_private (obj_class, sizeof (PanelServicePrivate)); } +static IndicatorObjectEntry * +get_entry_at (PanelService *self, gint x, gint y) +{ + GHashTableIter panel_iter, entries_iter; + gpointer key, value, k, v; + + g_hash_table_iter_init (&panel_iter, self->priv->panel2entries_hash); + while (g_hash_table_iter_next (&panel_iter, &key, &value)) + { + GHashTable *entry2geometry_hash = value; + g_hash_table_iter_init (&entries_iter, entry2geometry_hash); + + while (g_hash_table_iter_next (&entries_iter, &k, &v)) + { + IndicatorObjectEntry *entry = k; + GdkRectangle *geo = v; + + if (x >= geo->x && x <= (geo->x + geo->width) && + y >= geo->y && y <= (geo->y + geo->height)) + { + return entry; + } + } + } + + return NULL; +} + +static IndicatorObject * +get_entry_parent_indicator (IndicatorObjectEntry *entry) +{ + if (!entry || !INDICATOR_IS_OBJECT (entry->parent_object)) + return NULL; + + return INDICATOR_OBJECT (entry->parent_object); +} + +static gchar * +get_indicator_entry_id_by_entry (IndicatorObjectEntry *entry) +{ + gchar *entry_id = NULL; + + if (entry) + entry_id = g_strdup_printf ("%p", entry); + + return entry_id; +} + +static IndicatorObjectEntry * +get_indicator_entry_by_id (PanelService *self, const gchar *entry_id) +{ + IndicatorObjectEntry *entry; + + entry = g_hash_table_lookup (self->priv->id2entry_hash, entry_id); + + if (entry) + { + if (g_slist_find (self->priv->indicators, entry->parent_object)) + { + if (!INDICATOR_IS_OBJECT (entry->parent_object)) + entry = NULL; + } + else + { + entry = NULL; + } + + if (!entry) + { + g_warning("The entry id '%s' you're trying to lookup is not a valid IndicatorObjectEntry!", entry_id); + } + } + + return entry; +} + static GdkFilterReturn event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self) { @@ -269,9 +371,9 @@ if (!event) return ret; - if (event->evtype == XI_KeyRelease) + if (event->evtype == XI_KeyPress) { - if (XkbKeycodeToKeysym(event->display, event->detail, 0, 0) == GDK_KEY_F10) + if (event->mods.base == priv->toggle_modifiers && event->detail == priv->toggle_key) { if (GTK_IS_MENU (priv->last_menu)) gtk_menu_popdown (GTK_MENU (priv->last_menu)); @@ -288,21 +390,21 @@ } if (event->evtype == XI_ButtonRelease) - { + { IndicatorObjectEntry *entry; gboolean event_is_a_click = FALSE; entry = get_entry_at (self, event->root_x, event->root_y); - if (XIMaskIsSet (event->buttons.mask, 1) || XIMaskIsSet (event->buttons.mask, 3)) + if (event->detail == 1 || event->detail == 3) { /* Consider only right and left clicks over the indicators entries */ event_is_a_click = TRUE; } - else if (XIMaskIsSet (event->buttons.mask, 2) && entry) + else if (entry && event->detail == 2) { /* Middle clicks over an appmenu entry are considered just like * all other clicks */ - IndicatorObject *obj = g_hash_table_lookup (priv->entry2indicator_hash, entry); + IndicatorObject *obj = get_entry_parent_indicator (entry); if (g_strcmp0 (g_object_get_data (G_OBJECT (obj), "id"), "libappmenu.so") == 0) { @@ -330,25 +432,23 @@ /* If we were navigating over indicators using the keyboard * and now we click over the indicator under the mouse, we * must force it to show back again, not make it close */ - gchar *entry_id = g_strdup_printf ("%p", entry); + gchar *entry_id = get_indicator_entry_id_by_entry (entry); g_signal_emit (self, _service_signals[ENTRY_ACTIVATE_REQUEST], 0, entry_id); g_free (entry_id); } } } } - else if ((XIMaskIsSet (event->buttons.mask, 2) || - XIMaskIsSet (event->buttons.mask, 4) || - XIMaskIsSet (event->buttons.mask, 5)) && entry) + else if (entry && (event->detail == 2 || event->detail == 4 || event->detail == 5)) { /* If we're scrolling or middle-clicking over an indicator * (which is not an appmenu entry) then we need to send the * event to the indicator itself, and avoid it to close */ - gchar *entry_id = g_strdup_printf ("%p", entry); + gchar *entry_id = get_indicator_entry_id_by_entry (entry); - if (XIMaskIsSet (event->buttons.mask, 4) || XIMaskIsSet (event->buttons.mask, 5)) + if (event->detail == 4 || event->detail == 5) { - gint32 delta = XIMaskIsSet (event->buttons.mask, 4) ? 120 : -120; + gint32 delta = (event->detail == 4) ? 120 : -120; panel_service_scroll_entry (self, entry_id, delta); } else if (entry == priv->pressed_entry) @@ -365,69 +465,83 @@ return ret; } -static IndicatorObjectEntry * -get_entry_at (PanelService *self, gint x, gint y) +static gboolean +initial_resync (PanelService *self) { - GHashTableIter panel_iter, entries_iter; - gpointer key, value, k, v; - - g_hash_table_iter_init (&panel_iter, self->priv->panel2entries_hash); - while (g_hash_table_iter_next (&panel_iter, &key, &value)) + if (PANEL_IS_SERVICE (self)) { - GHashTable *entry2geometry_hash = value; - g_hash_table_iter_init (&entries_iter, entry2geometry_hash); - - while (g_hash_table_iter_next (&entries_iter, &k, &v)) - { - IndicatorObjectEntry *entry = k; - GdkRectangle *geo = v; - - if (x >= geo->x && x <= (geo->x + geo->width) && - y >= geo->y && y <= (geo->y + geo->height)) - { - return entry; - } - } + g_signal_emit (self, _service_signals[RE_SYNC], 0, ""); + self->priv->initial_sync_id = 0; } - - return NULL; + return FALSE; } static void -panel_service_get_indicator_entry_by_id (PanelService *self, - const gchar *entry_id, - IndicatorObjectEntry **entry, - IndicatorObject **object) +panel_service_update_menu_keybinding (PanelService *self) { - IndicatorObject *indicator; - IndicatorObjectEntry *probably_entry; - PanelServicePrivate *priv = self->priv; + GConfClient *client = gconf_client_get_default (); + gchar *binding = gconf_client_get_string (client, MENU_TOGGLE_KEYBINDING_PATH, NULL); - /* FIXME: eeek, why do we even do this? */ - if (sscanf (entry_id, "%p", &probably_entry) == 1) - { - /* check that there really is such IndicatorObjectEntry */ - indicator = g_hash_table_lookup (priv->entry2indicator_hash, - probably_entry); - if (object) *object = indicator; - if (entry) *entry = indicator != NULL ? probably_entry : NULL; - } - else + KeyCode keycode = 0; + KeySym keysym = NoSymbol; + guint32 modifiers = 0; + + gchar *keystart = (binding) ? strrchr (binding, '>') : NULL; + + if (!keystart) + keystart = binding; + + while (keystart && !g_ascii_isalnum (*keystart)) + keystart++; + + gchar *keyend = keystart; + + while (keyend && g_ascii_isalnum (*keyend)) + keyend++; + + if (keystart != keyend) { - if (object) *object = NULL; - if (entry) *entry = NULL; + gchar *keystr = g_strndup (keystart, keyend-keystart); + keysym = XStringToKeysym (keystr); + g_free (keystr); } -} -static gboolean -initial_resync (PanelService *self) -{ - if (PANEL_IS_SERVICE (self)) + if (keysym != NoSymbol) { - g_signal_emit (self, _service_signals[RE_SYNC], 0, ""); - self->priv->initial_sync_id = 0; + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + keycode = XKeysymToKeycode(dpy, keysym); + + if (g_strrstr (binding, "")) + { + modifiers |= GDK_SHIFT_MASK; + } + if (g_strrstr (binding, "")) + { + modifiers |= GDK_CONTROL_MASK; + } + if (g_strrstr (binding, "") || g_strrstr (binding, "")) + { + modifiers |= GDK_MOD1_MASK; + } + if (g_strrstr (binding, "")) + { + modifiers |= GDK_SUPER_MASK; + } } - return FALSE; + + self->priv->toggle_key = keycode; + self->priv->toggle_modifiers = modifiers; + + g_free (binding); +} + +void +on_keybinding_changed (GConfClient* client, guint id, GConfEntry* entry, gpointer data) +{ + PanelService *self = data; + g_return_if_fail (PANEL_IS_SERVICE (data)); + + panel_service_update_menu_keybinding (self); } static void @@ -442,7 +556,7 @@ gdk_window_add_filter (NULL, (GdkFilterFunc)event_filter, self); - priv->entry2indicator_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->id2entry_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->panel2entries_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy); @@ -452,6 +566,14 @@ sort_indicators (self); suppress_signals = FALSE; + panel_service_update_menu_keybinding (self); + + GConfClient *client = gconf_client_get_default (); + gconf_client_add_dir (client, COMPIZ_OPTIONS_PATH, GCONF_CLIENT_PRELOAD_NONE, NULL); + priv->key_monitor_id = gconf_client_notify_add (client, MENU_TOGGLE_KEYBINDING_PATH, + on_keybinding_changed, self, + NULL, NULL); + priv->initial_sync_id = g_idle_add ((GSourceFunc)initial_resync, self); } @@ -481,17 +603,23 @@ { for (l = entries; l; l = l->next) { - g_hash_table_remove (self->priv->entry2indicator_hash, l->data); - + IndicatorObjectEntry *entry; + gchar *entry_id; GHashTableIter iter; gpointer key, value; + + entry = l->data; + entry_id = get_indicator_entry_id_by_entry (entry); + g_hash_table_remove (self->priv->id2entry_hash, entry_id); + g_free (entry_id); + g_hash_table_iter_init (&iter, self->priv->panel2entries_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { GHashTable *entry2geometry_hash = value; if (g_hash_table_size (entry2geometry_hash) > 1) - g_hash_table_remove (entry2geometry_hash, l->data); + g_hash_table_remove (entry2geometry_hash, entry); else g_hash_table_iter_remove (&iter); } @@ -586,7 +714,7 @@ gpointer timeout = g_object_get_data (G_OBJECT (indicator), "remove-timeout"); if (timeout) - g_source_remove (GPOINTER_TO_UINT (timeout)); + g_source_remove (GPOINTER_TO_UINT (timeout)); g_object_set_data (G_OBJECT (indicator), "remove", GINT_TO_POINTER (TRUE)); notify_object (indicator); @@ -695,13 +823,11 @@ IndicatorObjectEntry *entry, PanelService *self) { - PanelServicePrivate *priv; - g_return_if_fail (PANEL_IS_SERVICE (self)); g_return_if_fail (entry != NULL); - priv = self->priv; - g_hash_table_insert (priv->entry2indicator_hash, entry, object); + gchar *entry_id = get_indicator_entry_id_by_entry (entry); + g_hash_table_insert (self->priv->id2entry_hash, entry_id, entry); if (GTK_IS_LABEL (entry->label)) { @@ -748,18 +874,18 @@ IndicatorObjectEntry *entry, PanelService *self) { - PanelServicePrivate *priv; g_return_if_fail (PANEL_IS_SERVICE (self)); g_return_if_fail (entry != NULL); - priv = self->priv; - - g_hash_table_remove (priv->entry2indicator_hash, entry); - /* Don't remove here the value from priv->panel2entries_hash, this should - * be done in during the sync, to avoid false positive. + /* Don't remove here the value from panel2entries_hash, this should be + * done during the geometries sync, to avoid false positive. * FIXME this in libappmenu.so to avoid to send an "entry-removed" signal * when switching the focus from a window to one of its dialog children */ + gchar *entry_id = get_indicator_entry_id_by_entry (entry); + g_hash_table_remove (self->priv->id2entry_hash, entry_id); + g_free (entry_id); + notify_object (object); } @@ -786,10 +912,8 @@ return; } - entry_id = g_strdup_printf ("%p", entry); - + entry_id = get_indicator_entry_id_by_entry (entry); g_signal_emit (self, _service_signals[ENTRY_ACTIVATE_REQUEST], 0, entry_id); - g_free (entry_id); } @@ -808,10 +932,8 @@ return; } - entry_id = g_strdup_printf ("%p", entry); - + entry_id = get_indicator_entry_id_by_entry (entry); g_signal_emit (self, _service_signals[ENTRY_SHOW_NOW_CHANGED], 0, entry_id, show_now_changed); - g_free (entry_id); } @@ -829,7 +951,7 @@ gchar *name; GList *entries, *entry; - indicator_object_set_environment(object, (const GStrv)indicator_environment); + indicator_object_set_environment(object, (GStrv)indicator_environment); if (_name != NULL) name = g_strdup (_name); @@ -1079,7 +1201,7 @@ { gint prio = -1; IndicatorObjectEntry *entry = e->data; - gchar *id = g_strdup_printf ("%p", entry); + gchar *id = get_indicator_entry_id_by_entry (entry); if (entry->name_hint) { @@ -1095,13 +1217,14 @@ indicator_entry_to_variant (entry, id, indicator_id, b, prio); g_free (id); } + + g_list_free (entries); } else { /* Add a null entry to indicate that there is an indicator here, it's just empty */ indicator_entry_null_to_variant (indicator_id, b); } - g_list_free (entries); } static void @@ -1147,7 +1270,7 @@ priv->use_event = FALSE; priv->pressed_entry = NULL; - g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, ""); + g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, "", 0, 0, 0, 0); } /* @@ -1226,15 +1349,29 @@ { IndicatorObject *object; IndicatorObjectEntry *entry; + gboolean valid_entry = TRUE; PanelServicePrivate *priv = self->priv; - panel_service_get_indicator_entry_by_id (self, entry_id, &entry, &object); + entry = get_indicator_entry_by_id (self, entry_id); + + /* If the entry we read is not valid, maybe it has already been removed + * or unparented, so we need to make sure that the related key on the + * entry2geometry_hash is correctly removed and the value is free'd */ + if (!entry) + { + IndicatorObjectEntry *invalid_entry; + if (sscanf (entry_id, "%p", &invalid_entry) == 1) + { + entry = invalid_entry; + valid_entry = FALSE; + } + } if (entry) { GHashTable *entry2geometry_hash = g_hash_table_lookup (priv->panel2entries_hash, panel_id); - if (width < 0 || height < 0) + if (width < 0 || height < 0 || !valid_entry) { if (entry2geometry_hash) { @@ -1247,63 +1384,110 @@ g_hash_table_remove (priv->panel2entries_hash, panel_id); } } + + /* If the entry has been removed let's make sure that its menu is closed */ + if (valid_entry && GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu) + { + gtk_menu_popdown (entry->menu); + } } else { GdkRectangle *geo = NULL; if (entry2geometry_hash == NULL) - { - //FIXME - this leaks memory but i'm not 100% on the logic, - // using g_free as the keys destructor function causes all - // kinds of problems - entry2geometry_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); - g_hash_table_insert (priv->panel2entries_hash, g_strdup (panel_id), - entry2geometry_hash); - } + { + entry2geometry_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, g_free); + g_hash_table_insert (priv->panel2entries_hash, g_strdup (panel_id), + entry2geometry_hash); + } else - { - geo = g_hash_table_lookup (entry2geometry_hash, entry); - } + { + geo = g_hash_table_lookup (entry2geometry_hash, entry); + } if (geo == NULL) { - geo = g_new (GdkRectangle, 1); + geo = g_new0 (GdkRectangle, 1); g_hash_table_insert (entry2geometry_hash, entry, geo); } + /* If the current entry geometry has changed, we need to move the menu + * accordingly to the change we recorded! */ + if (GTK_IS_MENU (priv->last_menu) && priv->last_menu == entry->menu) + { + GtkWidget *top_widget = gtk_widget_get_toplevel (GTK_WIDGET (priv->last_menu)); + + if (GTK_IS_WINDOW (top_widget)) + { + GtkWindow *top_win = GTK_WINDOW (top_widget); + gint old_x, old_y; + + gtk_window_get_position (top_win, &old_x, &old_y); + gtk_window_move (top_win, old_x - (geo->x - x), old_y - (geo->y - y)); + } + } + geo->x = x; geo->y = y; geo->width = width; geo->height = height; } - g_signal_emit (self, _service_signals[GEOMETRIES_CHANGED], 0, object, entry, x, y, width, height); + if (valid_entry) + { + object = get_entry_parent_indicator (entry); + g_signal_emit (self, _service_signals[GEOMETRIES_CHANGED], 0, object, entry, x, y, width, height); + } } } static gboolean -should_skip_menu (IndicatorObjectEntry *entry) +panel_service_entry_is_visible (PanelService *self, IndicatorObjectEntry *entry) { - gboolean label_ok = FALSE; - gboolean image_ok = FALSE; + GHashTableIter panel_iter; + gpointer key, value; + gboolean found_geo; + + g_return_val_if_fail (PANEL_IS_SERVICE (self), FALSE); + g_return_val_if_fail (entry != NULL, FALSE); + + found_geo = FALSE; + g_hash_table_iter_init (&panel_iter, self->priv->panel2entries_hash); + + while (g_hash_table_iter_next (&panel_iter, &key, &value) && !found_geo) + { + GHashTable *entry2geometry_hash = value; + + if (g_hash_table_lookup (entry2geometry_hash, entry)) + { + found_geo = TRUE; + } + } - g_return_val_if_fail (entry != NULL, TRUE); + if (!found_geo) + return FALSE; if (GTK_IS_LABEL (entry->label)) { - label_ok = gtk_widget_get_visible (GTK_WIDGET (entry->label)) - && gtk_widget_is_sensitive (GTK_WIDGET (entry->label)); + if (gtk_widget_get_visible (GTK_WIDGET (entry->label)) && + gtk_widget_is_sensitive (GTK_WIDGET (entry->label))) + { + return TRUE; + } } if (GTK_IS_IMAGE (entry->image)) { - image_ok = gtk_widget_get_visible (GTK_WIDGET (entry->image)) - && gtk_widget_is_sensitive (GTK_WIDGET (entry->image)); + if (gtk_widget_get_visible (GTK_WIDGET (entry->image)) && + gtk_widget_is_sensitive (GTK_WIDGET (entry->image))) + { + return TRUE; + } } - return !label_ok && !image_ok; + return TRUE; } static int @@ -1341,7 +1525,7 @@ gint prio = -1; new_entry = ll->data; - if (should_skip_menu (new_entry)) + if (!panel_service_entry_is_visible (self, new_entry)) continue; if (new_entry->name_hint) @@ -1388,7 +1572,7 @@ if (new_entry) { - id = g_strdup_printf ("%p", new_entry); + id = get_indicator_entry_id_by_entry (new_entry); g_signal_emit (self, _service_signals[ENTRY_ACTIVATE_REQUEST], 0, id); g_free (id); } @@ -1433,7 +1617,7 @@ } /* Find the next/prev indicator */ - object = g_hash_table_lookup (priv->entry2indicator_hash, priv->last_entry); + object = get_entry_parent_indicator(priv->last_entry); if (object == NULL) { g_warning ("Unable to find IndicatorObject for entry"); @@ -1450,23 +1634,25 @@ gtk_widget_destroy (menu); } -void -panel_service_show_entry (PanelService *self, - const gchar *entry_id, - guint32 timestamp, - gint32 x, - gint32 y, - gint32 button) +static void +panel_service_show_entry_common (PanelService *self, + IndicatorObject *object, + IndicatorObjectEntry *entry, + guint32 xid, + gint32 x, + gint32 y, + guint32 button, + guint32 timestamp) { - IndicatorObject *object; - IndicatorObjectEntry *entry; - GtkWidget *last_menu; - PanelServicePrivate *priv = self->priv; - - panel_service_get_indicator_entry_by_id (self, entry_id, &entry, &object); + PanelServicePrivate *priv; + GtkWidget *last_menu; + g_return_if_fail (PANEL_IS_SERVICE (self)); + g_return_if_fail (INDICATOR_IS_OBJECT (object)); g_return_if_fail (entry); + priv = self->priv; + if (priv->last_entry == entry) return; @@ -1489,7 +1675,14 @@ if (entry != NULL) { - g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, entry_id); + if (xid > 0) + { + indicator_object_entry_activate_window (object, entry, xid, CurrentTime); + } + else + { + indicator_object_entry_activate (object, entry, CurrentTime); + } if (GTK_IS_MENU (entry->menu)) { @@ -1526,29 +1719,33 @@ priv->last_menu_move_id = g_signal_connect_after (priv->last_menu, "move-current", G_CALLBACK (on_active_menu_move_current), self); - indicator_object_entry_activate (object, entry, CurrentTime); - gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, 0, CurrentTime); GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu)); + if (gdkwin != NULL) - { - gint left=0, top=0, width=0, height=0; + { + gint left=0, top=0, width=0, height=0; - gdk_window_get_geometry (gdkwin, NULL, NULL, &width, &height); - gdk_window_get_origin (gdkwin, &left, &top); + gdk_window_get_geometry (gdkwin, NULL, NULL, &width, &height); + gdk_window_get_origin (gdkwin, &left, &top); - priv->last_left = left; - priv->last_right = left + width -1; - priv->last_top = top; - priv->last_bottom = top + height -1; - } + gchar *entry_id = get_indicator_entry_id_by_entry (entry); + g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, entry_id, + left, top, width, height); + g_free (entry_id); + + priv->last_left = left; + priv->last_right = left + width -1; + priv->last_top = top; + priv->last_bottom = top + height -1; + } else - { - priv->last_left = 0; - priv->last_right = 0; - priv->last_top = 0; - priv->last_bottom = 0; - } + { + priv->last_left = 0; + priv->last_right = 0; + priv->last_top = 0; + priv->last_bottom = 0; + } } /* We popdown the old one last so we don't accidently send key focus back to the @@ -1560,6 +1757,53 @@ } void +panel_service_show_entry (PanelService *self, + const gchar *entry_id, + guint32 xid, + gint32 x, + gint32 y, + guint32 button, + guint32 timestamp) +{ + IndicatorObject *object; + IndicatorObjectEntry *entry; + + g_return_if_fail (PANEL_IS_SERVICE (self)); + + entry = get_indicator_entry_by_id (self, entry_id); + object = get_entry_parent_indicator (entry); + + panel_service_show_entry_common (self, object, entry, xid, x, y, button, timestamp); +} + +void +panel_service_show_app_menu (PanelService *self, + guint32 xid, + gint32 x, + gint32 y, + guint32 timestamp) +{ + IndicatorObject *object; + IndicatorObjectEntry *entry; + GList *entries; + + g_return_if_fail (PANEL_IS_SERVICE (self)); + + object = panel_service_get_indicator (self, "libappmenu.so"); + g_return_if_fail (INDICATOR_IS_OBJECT (object)); + + entries = indicator_object_get_entries (object); + + if (entries) + { + entry = entries->data; + g_list_free (entries); + + panel_service_show_entry_common (self, object, entry, xid, x, y, 1, timestamp); + } +} + +void panel_service_secondary_activate_entry (PanelService *self, const gchar *entry_id, guint32 timestamp) @@ -1567,9 +1811,10 @@ IndicatorObject *object; IndicatorObjectEntry *entry; - panel_service_get_indicator_entry_by_id (self, entry_id, &entry, &object); + entry = get_indicator_entry_by_id (self, entry_id); g_return_if_fail (entry); + object = get_entry_parent_indicator (entry); g_signal_emit_by_name(object, INDICATOR_OBJECT_SIGNAL_SECONDARY_ACTIVATE, entry, timestamp); } @@ -1582,11 +1827,12 @@ IndicatorObject *object; IndicatorObjectEntry *entry; - panel_service_get_indicator_entry_by_id (self, entry_id, &entry, &object); + entry = get_indicator_entry_by_id (self, entry_id); g_return_if_fail (entry); GdkScrollDirection direction = delta < 0 ? GDK_SCROLL_DOWN : GDK_SCROLL_UP; + object = get_entry_parent_indicator (entry); g_signal_emit_by_name(object, INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED, entry, abs(delta/120), direction); } diff -Nru unity-5.6.0/services/panel-service.h unity-5.8.0/services/panel-service.h --- unity-5.6.0/services/panel-service.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/services/panel-service.h 2012-03-23 11:53:16.000000000 +0000 @@ -95,10 +95,17 @@ void panel_service_show_entry (PanelService *self, const gchar *entry_id, - guint32 timestamp, + guint32 xid, gint32 x, gint32 y, - gint32 button); + guint32 button, + guint32 timestamp); + +void panel_service_show_app_menu (PanelService *self, + guint32 xid, + gint32 x, + gint32 y, + guint32 timestamp); void panel_service_secondary_activate_entry (PanelService *self, const gchar *entry_id, diff -Nru unity-5.6.0/standalone-clients/CMakeLists.txt unity-5.8.0/standalone-clients/CMakeLists.txt --- unity-5.6.0/standalone-clients/CMakeLists.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/standalone-clients/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 @@ -43,6 +43,8 @@ # add_executable (dash standalone_dash.cpp + ${UNITY_SRC}/AbstractPlacesGroup.cpp + ${UNITY_SRC}/AbstractPlacesGroup.h ${UNITY_SRC}/BackgroundEffectHelper.cpp ${UNITY_SRC}/BackgroundEffectHelper.h ${UNITY_SRC}/BGHash.cpp @@ -101,6 +103,8 @@ ${UNITY_SRC}/LensBarIcon.h ${UNITY_SRC}/LensView.cpp ${UNITY_SRC}/LensView.h + ${UNITY_SRC}/LensViewPrivate.cpp + ${UNITY_SRC}/LensViewPrivate.h ${UNITY_SRC}/OverlayRenderer.cpp ${UNITY_SRC}/PreviewApplications.cpp ${UNITY_SRC}/PreviewBase.cpp diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/bamf.py unity-5.8.0/tests/autopilot/autopilot/emulators/bamf.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/bamf.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/bamf.py 2012-03-23 11:53:16.000000000 +0000 @@ -131,15 +131,21 @@ return found_app[0] - def launch_application(self, desktop_file, wait=True): + def launch_application(self, desktop_file, files=[], wait=True): """Launch an application by specifying a desktop file. + `files` is a list of files to pass to the application. Not all apps support this. + + If `wait` is True, this method will block until the application has launched. + Returns the Gobject process object. if wait is True (the default), this method will not return until an instance of this application appears in the BAMF application list. """ + if type(files) is not list: + raise TypeError("files must be a list.") proc = gio.unix.DesktopAppInfo(desktop_file) - proc.launch() + proc.launch_uris(files) if wait: self.wait_until_application_is_running(desktop_file, -1) return proc diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/unity/dash.py unity-5.8.0/tests/autopilot/autopilot/emulators/unity/dash.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/unity/dash.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/unity/dash.py 2012-03-23 11:53:16.000000000 +0000 @@ -30,24 +30,27 @@ def __init__(self): self.controller = DashController.get_all_instances()[0] - self.view = self.controller.get_dash_view() self._keyboard = Keyboard() super(Dash, self).__init__() + @property + def view(self): + return self.controller.get_dash_view() + def toggle_reveal(self): """ Reveals the dash if it's currently hidden, hides it otherwise. """ logger.debug("Toggling dash visibility with Super key.") - self.keybinding("dash/reveal") + self.keybinding("dash/reveal", 0.1) sleep(1) def ensure_visible(self, clear_search=True): """ Ensures the dash is visible. """ - if not self.get_is_visible(): + if not self.visible: self.toggle_reveal() self._wait_for_visibility(expect_visible=True) if clear_search: @@ -57,25 +60,30 @@ """ Ensures the dash is hidden. """ - if self.get_is_visible(): + 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.get_is_visible() != expect_visible: + 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")) - def get_is_visible(self): + @property + def visible(self): """ Is the dash visible? """ return self.controller.visible + @property + def search_string(self): + return self.get_searchbar().search_string + def get_searchbar(self): """Returns the searchbar attached to the dash.""" return self.view.get_searchbar() @@ -96,33 +104,34 @@ def reveal_application_lens(self, clear_search=True): """Reveal the application lense.""" logger.debug("Revealing application lens with Super+a.") - self._reveal_lens("lens_reveal/apps") - if clear_search: - self.clear_search() + self._reveal_lens("lens_reveal/apps", clear_search) def reveal_music_lens(self, clear_search=True): """Reveal the music lense.""" logger.debug("Revealing music lens with Super+m.") - self._reveal_lens("lens_reveal/music") + self._reveal_lens("lens_reveal/music", clear_search) def reveal_file_lens(self, clear_search=True): """Reveal the file lense.""" logger.debug("Revealing file lens with Super+f.") - self._reveal_lens("lens_reveal/files") - if clear_search: - self.clear_search() + self._reveal_lens("lens_reveal/files", clear_search) def reveal_command_lens(self, clear_search=True): """Reveal the 'run command' lens.""" logger.debug("Revealing command lens with Alt+F2.") - self._reveal_lens("lens_reveal/command") - if clear_search: - self.clear_search() + self._reveal_lens("lens_reveal/command", clear_search) - def _reveal_lens(self, binding_name): + def _reveal_lens(self, binding_name, clear_search): self.keybinding_hold(binding_name) self.keybinding_tap(binding_name) self.keybinding_release(binding_name) + self._wait_for_visibility(expect_visible=True) + if clear_search: + self.clear_search() + + @property + def active_lens(self): + return self.view.get_lensbar().active_lens def get_current_lens(self): """Get the currently-active LensView object.""" @@ -168,6 +177,11 @@ class LensView(UnityIntrospectionObject): """A Lens View.""" + def get_groups(self): + """Get a list of all groups within this lensview. May return an empty list.""" + groups = self.get_children_by_type(PlacesGroup) + return groups + def get_focused_category(self): """Return a PlacesGroup instance for the category whose header has keyboard focus. @@ -248,6 +262,7 @@ m = Mouse() m.move(tx, ty) m.click() + self._wait_for_expansion(True) def ensure_collapsed(self): """Collapse the filter bar, if it's not already.""" @@ -258,6 +273,16 @@ 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")) def _get_searchbar(self): """Get the searchbar. diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/unity/__init__.py unity-5.8.0/tests/autopilot/autopilot/emulators/unity/__init__.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/unity/__init__.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/unity/__init__.py 2012-03-23 11:53:16.000000000 +0000 @@ -80,6 +80,41 @@ return class_type(state) +def start_log_to_file(file_path): + """Instruct Unity to start logging to the given file.""" + _introspection_iface.StartLogToFile(file_path) + + +def reset_logging(): + """Instruct Unity to stop logging to a file.""" + _introspection_iface.ResetLogging() + + +def set_log_severity(component, severity): + """Instruct Unity to set a log component's severity. + + 'component' is the unity logging component name. + + 'severity' is the severity name (like 'DEBUG', 'INFO' etc.) + + """ + _introspection_iface.SetLogSeverity(component, severity) + + +def log_unity_message(severity, message): + """Instruct unity to log a message for us. + + severity: one of ('TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'). + + message: The message to log. + + For debugging purposes only! If you want to log a message during an autopilot + test, use the python logging framework instead. + + """ + _introspection_iface.LogMessage(severity, message) + + class UnityIntrospectionObject(object): """A class that can be created using a dictionary of state from Unity.""" __metaclass__ = IntrospectableObjectMetaclass diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/unity/launcher.py unity-5.8.0/tests/autopilot/autopilot/emulators/unity/launcher.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-23 11:53:16.000000000 +0000 @@ -47,10 +47,32 @@ self.show_timeout = 1 self.hide_timeout = 1 self.in_keynav_mode = False + self.in_switcher_mode = False self._mouse = Mouse() self._screen = ScreenGeometry() + def _perform_key_nav_binding(self, keybinding): + if not self.in_keynav_mode: + raise RuntimeError("Cannot perform key navigation when not in kaynav mode.") + self.keybinding(keybinding) + + def _perform_key_nav_exit_binding(self, keybinding): + self._perform_key_nav_binding(keybinding) + self.in_keynav_mode = False + + def _perform_switcher_binding(self, keybinding): + if not self.in_switcher_mode: + raise RuntimeError("Cannot interact with launcher switcher when not in switcher mode.") + self.keybinding(keybinding) + + def _perform_switcher_exit_binding(self, keybinding): + self._perform_switcher_binding(keybinding) + # if our exit binding was something besides just releasing, we need to release + if keybinding != "launcher/switcher": + self.keybinding_release("launcher/switcher") + self.in_switcher_mode = False + 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) @@ -72,7 +94,7 @@ logger.debug("Moving mouse to center of launcher.") self._mouse.move(target_x, target_y) - def reveal_launcher(self): + def mouse_reveal_launcher(self): """Reveal this launcher with the mouse.""" self._screen.move_mouse_to_monitor(self.monitor) (x, y, w, h) = self.geometry @@ -95,77 +117,85 @@ self.keybinding_release("launcher/reveal") sleep(1) - def grab_switcher(self): + 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.in_keynav_mode = True - def switcher_enter_quicklist(self): - if not self.in_keynav_mode: - raise RuntimeError("Cannot open switcher quicklist while not in keynav mode.") + def key_nav_cancel(self): + """End the key navigation.""" + logger.debug("Cancelling keyboard navigation mode.") + self._perform_key_nav_exit_binding("launcher/keynav/exit") + + 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") + + def key_nav_next(self): + """Moves the launcher keynav focus to the next launcher icon""" + logger.debug("Selecting next item in keyboard navigation mode.") + self._perform_key_nav_binding("launcher/keynav/next") + + def key_nav_prev(self): + """Moves the launcher keynav focus to the previous launcher icon""" + logger.debug("Selecting previous item in keyboard navigation mode.") + self._perform_key_nav_binding("launcher/keynav/prev") + + def key_nav_enter_quicklist(self): logger.debug("Opening quicklist for currently selected icon.") - self.keybinding("launcher/keynav/open-quicklist") + self._perform_key_nav_binding("launcher/keynav/open-quicklist") - def switcher_exit_quicklist(self): - if not self.in_keynav_mode: - raise RuntimeError("Cannot close switcher quicklist while not in keynav mode.") + def key_nav_exit_quicklist(self): logger.debug("Closing quicklist for currently selected icon.") - self.keybinding("launcher/keynav/close-quicklist") + self._perform_key_nav_binding("launcher/keynav/close-quicklist") - def start_switcher(self): + 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("launcher/switcher") - self.keybinding_tap("launcher/switcher") - sleep(1) - - def end_switcher(self, cancel): - """End either the keynav mode or the super+tab swithcer. + self.keybinding_hold_part_then_tap("launcher/switcher") + self.in_switcher_mode = True - If cancel is True, the currently selected icon will not be activated. - - """ - if cancel: - logger.debug("Cancelling keyboard navigation mode.") - self.keybinding("launcher/keynav/exit") - if not self.in_keynav_mode: - self.keybinding_release("launcher/switcher") - else: - logger.debug("Ending keyboard navigation mode.") - if self.in_keynav_mode: - self.keybinding("launcher/keynav/activate") - else: - self.keybinding_release("launcher/switcher") - self.in_keynav_mode = False + def switcher_cancel(self): + """End the super+tab swithcer.""" + logger.debug("Cancelling keyboard navigation mode.") + self._perform_switcher_exit_binding("launcher/switcher/exit") + + 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") def switcher_next(self): logger.debug("Selecting next item in keyboard navigation mode.") - if self.in_keynav_mode: - self.keybinding("launcher/keynav/next") - else: - self.keybinding("launcher/switcher/next") + self._perform_switcher_binding("launcher/switcher/next") def switcher_prev(self): logger.debug("Selecting previous item in keyboard navigation mode.") - if self.in_keynav_mode: - self.keybinding("launcher/keynav/prev") - else: - self.keybinding("launcher/switcher/prev") + self._perform_switcher_binding("launcher/switcher/prev") + + def switcher_up(self): + logger.debug("Selecting next item in keyboard navigation mode.") + self._perform_switcher_binding("launcher/switcher/up") + + def switcher_down(self): + logger.debug("Selecting previous item in keyboard navigation mode.") + self._perform_switcher_binding("launcher/switcher/down") def click_launcher_icon(self, icon, button=1): """Move the mouse over the launcher icon, and click it. - `icon` must be an instance of SimpleLauncherIcon or it's descendants. - """ if not isinstance(icon, SimpleLauncherIcon): raise TypeError("icon must be a LauncherIcon") logger.debug("Clicking launcher icon %r on monitor %d with mouse button %d", icon, self.monitor, button) - self.reveal_launcher() + self.mouse_reveal_launcher() target_x = icon.x + self.x target_y = icon.y + (self.icon_size / 2) self._mouse.move(target_x, target_y ) @@ -174,9 +204,7 @@ def lock_to_launcher(self, icon): """lock 'icon' to the launcher, if it's not already. - `icon` must be an instance of BamfLauncherIcon. - """ if not isinstance(icon, BamfLauncherIcon): raise TypeError("Can only lock instances of BamfLauncherIcon") @@ -243,7 +271,14 @@ 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) + return icons or None + def num_launcher_icons(self): """Get the number of icons in the launcher model.""" return len(self.get_launcher_icons()) - diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py unity-5.8.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,44 @@ +# -*- 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.keybindings import KeybindingsHelper +from autopilot.emulators.unity import UnityIntrospectionObject + + +logger = logging.getLogger(__name__) + + +class ShortcutController(UnityIntrospectionObject, KeybindingsHelper): + """ShortcutController proxy class.""" + + def show(self): + logger.debug("Revealing shortcut hint with keyboard.") + self.keybinding_hold("shortcuthint/reveal") + + def hide(self): + logger.debug("Un-revealing shortcut hint with keyboard.") + self.keybinding_release("shortcuthint/reveal") + + 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 -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/unity/switcher.py unity-5.8.0/tests/autopilot/autopilot/emulators/unity/switcher.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/unity/switcher.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/unity/switcher.py 2012-03-23 11:53:16.000000000 +0000 @@ -12,7 +12,7 @@ from autopilot.keybindings import KeybindingsHelper from autopilot.emulators.unity import get_state_by_path, make_introspection_object -from autopilot.emulators.X11 import Keyboard +from autopilot.emulators.X11 import Keyboard, Mouse # even though we don't use these directly, we need to make sure they've been # imported so the classes contained are registered with the introspection API. @@ -29,6 +29,7 @@ def __init__(self): super(Switcher, self).__init__() self._keyboard = Keyboard() + self._mouse = Mouse() def initiate(self): """Start the switcher with alt+tab.""" @@ -78,15 +79,27 @@ self.keybinding_release("switcher/reveal_normal") def next_icon(self): - """Move to the next application.""" + """Move to the next icon.""" logger.debug("Selecting next item in switcher.") self.keybinding("switcher/next") def previous_icon(self): - """Move to the previous application.""" + """Move to the previous icon.""" logger.debug("Selecting previous item in switcher.") self.keybinding("switcher/prev") + def next_icon_mouse(self): + """Move to the next icon using the mouse scroll wheel""" + logger.debug("Selecting next item in switcher with mouse scroll wheel.") + self._mouse.press(6) + self._mouse.release(6) + + def previous_icon_mouse(self): + """Move to the previous icon using the mouse scroll wheel""" + logger.debug("Selecting previous item in switcher with mouse scroll wheel.") + self._mouse.press(7) + self._mouse.release(7) + def show_details(self): """Show detail mode.""" logger.debug("Showing details view.") diff -Nru unity-5.6.0/tests/autopilot/autopilot/emulators/X11.py unity-5.8.0/tests/autopilot/autopilot/emulators/X11.py --- unity-5.6.0/tests/autopilot/autopilot/emulators/X11.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/emulators/X11.py 2012-03-23 11:53:16.000000000 +0000 @@ -78,6 +78,7 @@ 'Control' : 'Control_L', 'Ctrl' : 'Control_L', 'Alt' : 'Alt_L', + 'AltR': 'Alt_R', 'Super' : 'Super_L', 'Shift' : 'Shift_L', 'Enter' : 'Return', @@ -323,6 +324,9 @@ """Get the number of monitors attached to the PC.""" return self._default_screen.get_n_monitors() + def get_primary_monitor(self): + return self._default_screen.get_primary_monitor() + def get_screen_width(self): return self._default_screen.get_width() diff -Nru unity-5.6.0/tests/autopilot/autopilot/keybindings.py unity-5.8.0/tests/autopilot/autopilot/keybindings.py --- unity-5.6.0/tests/autopilot/autopilot/keybindings.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/keybindings.py 2012-03-23 11:53:16.000000000 +0000 @@ -48,11 +48,14 @@ "launcher/keynav/prev": "Up", "launcher/keynav/activate": "Enter", "launcher/keynav/exit": "Escape", + "launcher/keynav/open-quicklist": "Right", + "launcher/keynav/close-quicklist": "Left", "launcher/switcher": ('unityshell', 'launcher_switcher_forward'), + "launcher/switcher/exit": "Escape", "launcher/switcher/next": "Tab", "launcher/switcher/prev": "Shift+Tab", - "launcher/keynav/open-quicklist": "Right", - "launcher/keynav/close-quicklist": "Left", + "launcher/switcher/down": "Down", + "launcher/switcher/up": "Up", # Dash: "dash/reveal": "Super", # Lenses @@ -68,6 +71,9 @@ "switcher/reveal_details": "Alt+`", "switcher/reveal_all": ("unityshell", "alt_tab_forward_all"), "switcher/cancel": "Escape", + # Shortcut Hint: + "shortcuthint/reveal": ('unityshell', 'show_launcher'), + "shortcuthint/cancel": "Escape", # These are in compiz as 'Alt+Right' and 'Alt+Left', but the fact that it # lists the Alt key won't work for us, so I'm defining them manually. "switcher/next": "Tab", @@ -85,12 +91,15 @@ "workspace/move_down": ("wall", "down_key"), # Window management "window/minimize": ("core", "minimize_window_key"), + # expo plugin: + "expo/start": ("expo", "expo_key"), + "expo/cancel": "Escape", } def get(binding_name): - """Get a keyubinding, given it's well-known name. + """Get a keybinding, given its well-known name. binding_name must be a string, or a TypeError will be raised. @@ -224,3 +233,6 @@ """Tap the tap-part of a keybinding.""" self._keyboard.press_and_release(get_tap_part(binding_name)) + def keybinding_hold_part_then_tap(self, binding_name): + self.keybinding_hold(binding_name) + self.keybinding_tap(binding_name) \ No newline at end of file diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/__init__.py unity-5.8.0/tests/autopilot/autopilot/tests/__init__.py --- unity-5.6.0/tests/autopilot/autopilot/tests/__init__.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/__init__.py 2012-03-23 11:53:16.000000000 +0000 @@ -8,6 +8,7 @@ import os from StringIO import StringIO from subprocess import call, Popen, PIPE, STDOUT +from tempfile import mktemp from testscenarios import TestWithScenarios from testtools import TestCase from testtools.content import text_content @@ -15,6 +16,12 @@ import time from autopilot.emulators.bamf import Bamf +from autopilot.emulators.unity import ( + set_log_severity, + start_log_to_file, + reset_logging, + ) +from autopilot.emulators.unity.dash import Dash from autopilot.emulators.unity.launcher import LauncherController from autopilot.emulators.unity.switcher import Switcher from autopilot.emulators.unity.workspace import WorkspaceManager @@ -30,11 +37,42 @@ logger = logging.getLogger(__name__) +try: + from testscenarios.scenarios import multiple_scenarios +except ImportError: + from itertools import product + def multiply_scenarios(*scenarios): + """Multiply two or more iterables of scenarios. + + It is safe to pass scenario generators or iterators. + + :returns: A list of compound scenarios: the cross-product of all + scenarios, with the names concatenated and the parameters + merged together. + """ + result = [] + scenario_lists = map(list, scenarios) + for combination in product(*scenario_lists): + names, parameters = zip(*combination) + scenario_name = ','.join(names) + scenario_parameters = {} + for parameter in parameters: + scenario_parameters.update(parameter) + result.append((scenario_name, scenario_parameters)) + return result + + class LoggedTestCase(TestWithScenarios, TestCase): """Initialize the logging for the test case.""" def setUp(self): + self._setUpTestLogging() + self._setUpUnityLogging() + # The reason that the super setup is done here is due to making sure + # that the logging is properly set up prior to calling it. + super(LoggedTestCase, self).setUp() + def _setUpTestLogging(self): class MyFormatter(logging.Formatter): def formatTime(self, record, datefmt=None): @@ -50,17 +88,14 @@ root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG) handler = logging.StreamHandler(stream=self._log_buffer) - log_format = "%(asctime)s %(levelname)s %(pathname)s:%(lineno)d - %(message)s" + log_format = "%(asctime)s %(levelname)s %(module)s:%(lineno)d - %(message)s" handler.setFormatter(MyFormatter(log_format)) root_logger.addHandler(handler) #Tear down logging in a cleanUp handler, so it's done after all other # tearDown() calls and cleanup handlers. - self.addCleanup(self.tearDownLogging) - # The reason that the super setup is done here is due to making sure - # that the logging is properly set up prior to calling it. - super(LoggedTestCase, self).setUp() + self.addCleanup(self._tearDownLogging) - def tearDownLogging(self): + def _tearDownLogging(self): logger = logging.getLogger() for handler in logger.handlers: handler.flush() @@ -71,6 +106,28 @@ # abusing the log handlers here a little. del self._log_buffer + def _setUpUnityLogging(self): + self._unity_log_file_name = mktemp(prefix=self.shortDescription()) + start_log_to_file(self._unity_log_file_name) + self.addCleanup(self._tearDownUnityLogging) + + def _tearDownUnityLogging(self): + reset_logging() + with open(self._unity_log_file_name) as unity_log: + self.addDetail('unity-log', text_content(unity_log.read())) + os.remove(self._unity_log_file_name) + self._unity_log_file_name = "" + + def set_unity_log_level(self, component, level): + """Set the unity log level for 'component' to 'level'. + + Valid levels are: TRACE, DEBUG, INFO, WARNING and ERROR. + + Components are dotted unity component names. The empty string specifies + the root logging component. + """ + set_log_severity(component, level) + class VideoCapturedTestCase(LoggedTestCase): """Video capture autopilot tests, saving the results if the test failed.""" @@ -169,6 +226,7 @@ self.bamf = Bamf() self.keyboard = Keyboard() self.mouse = Mouse() + self.dash = Dash() self.switcher = Switcher() self.workspace = WorkspaceManager() self.launcher = self._get_launcher_controller() @@ -176,11 +234,14 @@ self.addCleanup(Keyboard.cleanup) self.addCleanup(Mouse.cleanup) - def start_app(self, app_name): - """Start one of the known apps, and kill it on tear down.""" + def start_app(self, app_name, files=[]): + """Start one of the known apps, and kill it on tear down. + + if files is specified, start the application with the specified files. + """ logger.info("Starting application '%s'", app_name) app = self.KNOWN_APPS[app_name] - self.bamf.launch_application(app['desktop-file']) + self.bamf.launch_application(app['desktop-file'], files) self.addCleanup(call, ["killall", app['process-name']]) def close_all_app(self, app_name): diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_dash.py unity-5.8.0/tests/autopilot/autopilot/tests/test_dash.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_dash.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_dash.py 2012-03-23 11:53:16.000000000 +0000 @@ -6,140 +6,171 @@ # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -from gtk import Clipboard from time import sleep -from autopilot.emulators.unity.dash import Dash +from gtk import Clipboard +from testtools.matchers import Equals + from autopilot.emulators.X11 import Keyboard, Mouse from autopilot.tests import AutopilotTestCase -class DashRevealTests(AutopilotTestCase): - """Test the unity Dash Reveal.""" - +class DashTestCase(AutopilotTestCase): def setUp(self): - super(DashRevealTests, self).setUp() - self.dash = Dash() - - def tearDown(self): - super(DashRevealTests, self).tearDown() + super(DashTestCase, self).setUp() + self.set_unity_log_level("unity.shell", "DEBUG") + self.set_unity_log_level("unity.launcher", "DEBUG") self.dash.ensure_hidden() + # On shutdown, ensure hidden too. Also add a delay. Cleanup is LIFO. + self.addCleanup(self.dash.ensure_hidden) + self.addCleanup(sleep, 1) - def test_dash_reveal(self): - """Ensure we can show and hide the dash.""" - self.dash.ensure_hidden() - self.assertFalse(self.dash.get_is_visible()) - self.dash.toggle_reveal() - self.assertTrue(self.dash.get_is_visible()) - self.dash.toggle_reveal() - self.assertFalse(self.dash.get_is_visible()) +class DashRevealTests(DashTestCase): + """Test the Unity dash Reveal.""" - def test_dash_keyboard_focus(self): - """Dash must put keyboard focus on the search bar at all times.""" + def test_dash_reveal(self): + """Ensure we can show and hide the dash.""" self.dash.ensure_visible() - kb = Keyboard() - kb.type("Hello") - sleep(1) - searchbar = self.dash.get_searchbar() - self.assertEqual(searchbar.search_string, u'Hello') + self.dash.ensure_hidden() def test_application_lens_shortcut(self): """Application lense must reveal when Super+a is pressed.""" - self.dash.ensure_hidden() self.dash.reveal_application_lens() - lensbar = self.dash.view.get_lensbar() - self.assertEqual(lensbar.active_lens, u'applications.lens') + self.assertThat(self.dash.active_lens, Equals('applications.lens')) def test_music_lens_shortcut(self): """Music lense must reveal when Super+w is pressed.""" - self.dash.ensure_hidden() self.dash.reveal_music_lens() - lensbar = self.dash.view.get_lensbar() - self.assertEqual(lensbar.active_lens, u'music.lens') + self.assertThat(self.dash.active_lens, Equals('music.lens')) def test_file_lens_shortcut(self): """File lense must reveal when Super+f is pressed.""" - self.dash.ensure_hidden() self.dash.reveal_file_lens() - lensbar = self.dash.view.get_lensbar() - self.assertEqual(lensbar.active_lens, u'files.lens') + self.assertThat(self.dash.active_lens, Equals('files.lens')) def test_command_lens_shortcut(self): """Run Command lens must reveat on alt+F2.""" - self.dash.ensure_hidden() self.dash.reveal_command_lens() - lensbar = self.dash.view.get_lensbar() - self.assertEqual(lensbar.active_lens, u'commands.lens') + self.assertThat(self.dash.active_lens, 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) -class DashKeyNavTests(AutopilotTestCase): - """Test the unity Dash keyboard navigation.""" +class DashSearchInputTests(DashTestCase): + """Test features involving input to the dash search""" - def setUp(self): - super(DashKeyNavTests, self).setUp() - self.dash = Dash() + def assertSearchText(self, text): + sleep(0.5) + self.assertThat(self.dash.search_string, Equals(text)) - def tearDown(self): - super(DashKeyNavTests, self).tearDown() - self.dash.ensure_hidden() + def test_search_keyboard_focus(self): + """Dash must put keyboard focus on the search bar at all times.""" + self.dash.ensure_visible() + self.keyboard.type("Hello") + self.assertSearchText("Hello") + + def test_multi_key(self): + """Pressing 'Multi_key' must not add any characters to the search.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("o") + self.assertSearchText("") + + def test_multi_key_o(self): + """Pressing the sequences 'Multi_key' + '^' + 'o' must produce 'ô'.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("^o") + self.assertSearchText("ô") + + def test_multi_key_copyright(self): + """Pressing the sequences 'Multi_key' + 'c' + 'o' must produce '©'.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("oc") + self.assertSearchText("©") + + def test_multi_key_delete(self): + """Pressing 'Multi_key' must not get stuck looking for a sequence.""" + self.dash.reveal_application_lens() + self.keyboard.type("dd") + self.keyboard.press_and_release('Multi_key') + self.keyboard.press_and_release('BackSpace') + self.keyboard.press_and_release('BackSpace') + self.assertSearchText("d") + + +class DashKeyNavTests(DashTestCase): + """Test the unity Dash keyboard navigation.""" def test_lensbar_gets_keyfocus(self): """Test that the lensbar gets key focus after using Down keypresses.""" self.dash.ensure_visible() - kb = Keyboard() + # Make sure that the lens bar can get the focus for i in range(self.dash.get_num_rows()): - kb.press_and_release("Down") + self.keyboard.press_and_release("Down") lensbar = self.dash.view.get_lensbar() self.assertIsNot(lensbar.focused_lens_icon, '') def test_lensbar_focus_changes(self): """Lensbar focused icon should change with Left and Right keypresses.""" self.dash.ensure_visible() - kb = Keyboard() - #put KB focus on lensbar again: - for i in range(self.dash.get_num_rows()): - kb.press_and_release("Down") + 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 - kb.press_and_release("Right"); + self.keyboard.press_and_release("Right"); lensbar.refresh_state() self.assertNotEqual(lensbar.focused_lens_icon, current_focused_icon) - kb.press_and_release("Left") + self.keyboard.press_and_release("Left") lensbar.refresh_state() self.assertEqual(lensbar.focused_lens_icon, current_focused_icon) def test_lensbar_enter_activation(self): """Must be able to activate LensBar icons that have focus with an Enter keypress.""" self.dash.ensure_visible() - kb = Keyboard() - #put KB focus on lensbar again: + for i in range(self.dash.get_num_rows()): - kb.press_and_release("Down") - kb.press_and_release("Right"); + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Right"); lensbar = self.dash.view.get_lensbar() focused_icon = lensbar.focused_lens_icon - kb.press_and_release("Enter"); + self.keyboard.press_and_release("Enter"); lensbar.refresh_state() self.assertEqual(lensbar.active_lens, 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): - """Test that the dash autoscroll when a category header gets - the focus. + """Tests that the dash scrolls a category header into view when scrolling via + the keyboard. + + Test for lp:919563 """ - self.dash.ensure_hidden() - self.dash.reveal_application_lens() - app_lens = self.dash.get_current_lens() - kb = Keyboard() - mouse = Mouse() + 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 - kb.press_and_release("Down") - kb.press_and_release("Enter") + 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. @@ -164,8 +195,8 @@ sleep(2) # Then focus again the first category header - kb.press_and_release("Down") - kb.press_and_release("Enter") + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Enter") category = app_lens.get_focused_category() y = category.header_y @@ -173,27 +204,27 @@ self.assertTrue(abs(y - cached_y) < 30) def test_category_header_keynav(self): - """ This test makes sure that: - 1. A category header can get the focus. - 2. A category header stays highlight when it loses the focus - and mouse is close to it (but not inside). - """ - self.dash.ensure_hidden() - self.dash.reveal_application_lens() - - kb = Keyboard() - mouse = Mouse() + """ Tests that a category header gets focus when 'down' is pressed after the + dash is opened + OK important to note that this test only tests that A category is + focused, not the first and from doing this it seems that it's common + for a header other than the first to get focus. + """ + self.dash.ensure_visible() # Make sure that a category have the focus. - kb.press_and_release("Down") - app_lens = self.dash.get_current_lens() - category = app_lens.get_focused_category() + self.keyboard.press_and_release("Down") + lens = self.dash.get_current_lens() + category = lens.get_focused_category() self.assertIsNot(category, None) - # 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 @@ -204,104 +235,97 @@ y + h / 2, True) sleep(1) - kb.press_and_release("Down") - sleep(1) - category = app_lens.get_focused_category() + self.keyboard.press_and_release("Down") + lens = self.dash.get_current_lens() + category = lens.get_focused_category() self.assertEqual(category, None) - def test_cltr_tab(self): - """ This test makes sure that Ctlr + Tab works well.""" - self.dash.ensure_hidden() - self.dash.toggle_reveal() + def test_control_tab_lens_cycle(self): + """ This test makes sure that Ctlr + Tab cycles lenses.""" + self.dash.ensure_visible() - kb = Keyboard() - lensbar = self.dash.view.get_lensbar() + self.keyboard.press('Control') + self.keyboard.press_and_release('Tab') + self.keyboard.release('Control') - kb.press('Control') - kb.press_and_release('Tab') - kb.release('Control') - lensbar.refresh_state() + lensbar = self.dash.view.get_lensbar() self.assertEqual(lensbar.active_lens, u'applications.lens') - kb.press('Control') - kb.press('Shift') - kb.press_and_release('Tab') - kb.release('Control') - kb.release('Shift') + self.keyboard.press('Control') + self.keyboard.press('Shift') + self.keyboard.press_and_release('Tab') + self.keyboard.release('Control') + self.keyboard.release('Shift') lensbar.refresh_state() self.assertEqual(lensbar.active_lens, u'home.lens') - def test_tab(self): - """ This test makes sure that Tab works well.""" - self.dash.ensure_hidden() - self.dash.reveal_application_lens() - app_lens = self.dash.get_current_lens() - - kb = Keyboard() + def test_tab_cycle_category_headers(self): + """ Makes sure that pressing tab cycles through the category headers""" + self.dash.ensure_visible() + lens = self.dash.get_current_lens() - for i in range(app_lens.get_num_visible_categories()): - kb.press_and_release('Tab') - category = app_lens.get_focused_category() + # Test that tab cycles through the categories. + # + 1 is to cycle back to first header + for i in range(lens.get_num_visible_categories() + 1): + self.keyboard.press_and_release('Tab') + category = lens.get_focused_category() self.assertIsNot(category, None) - kb.press_and_release('Tab') + def test_tab_with_filter_bar(self): + """ This test makes sure that Tab works well with the filter bara.""" + self.dash.reveal_application_lens() + lens = self.dash.get_current_lens() + + # 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) + filter_bar = lens.get_filterbar() if not searchbar.showing_filters: - kb.press_and_release('Enter') - searchbar.refresh_state() + self.keyboard.press_and_release('Enter') self.assertTrue(searchbar.showing_filters) + self.addCleanup(filter_bar.ensure_collapsed) - filter_bar = app_lens.get_filterbar() for i in range(filter_bar.get_num_filters()): - kb.press_and_release('Tab') + self.keyboard.press_and_release('Tab') new_focused_filter = filter_bar.get_focused_filter() self.assertIsNotNone(new_focused_filter) - kb.press_and_release('Tab') - category = app_lens.get_focused_category() + # Ensure that tab cycles back to a category header + self.keyboard.press_and_release('Tab') + category = lens.get_focused_category() self.assertIsNot(category, None) -class DashClipboardTests(AutopilotTestCase): +class DashClipboardTests(DashTestCase): """Test the Unity clipboard""" - def setUp(self): - super(DashClipboardTests, self).setUp() - self.dash = Dash() - - def tearDown(self): - super(DashClipboardTests, self).tearDown() - self.dash.ensure_hidden() - def test_ctrl_a(self): """ This test if ctrl+a selects all text """ - self.dash.ensure_hidden() - self.dash.toggle_reveal() + self.dash.ensure_visible() - kb = Keyboard(); - kb.type("SelectAll") + self.keyboard.type("SelectAll") sleep(1) + self.assertThat(self.dash.search_string, Equals('SelectAll')) - kb.press_and_release("Ctrl+a") - kb.press_and_release("Delete") - - searchbar = self.dash.get_searchbar() - self.assertEqual(searchbar.search_string, u'') + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Delete") + self.assertThat(self.dash.search_string, Equals('')) def test_ctrl_c(self): """ This test if ctrl+c copies text into the clipboard """ - self.dash.ensure_hidden() - self.dash.toggle_reveal() + self.dash.ensure_visible() - kb = Keyboard(); - kb.type("Copy") + self.keyboard.type("Copy") sleep(1) - kb.press_and_release("Ctrl+a") - kb.press_and_release("Ctrl+c") + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+c") cb = Clipboard(selection="CLIPBOARD") @@ -310,15 +334,13 @@ def test_ctrl_x(self): """ This test if ctrl+x deletes all text and copys it """ - self.dash.ensure_hidden() - self.dash.toggle_reveal() + self.dash.ensure_visible() - kb = Keyboard(); - kb.type("Cut") + self.keyboard.type("Cut") sleep(1) - kb.press_and_release("Ctrl+a") - kb.press_and_release("Ctrl+x") + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+x") sleep(1) searchbar = self.dash.get_searchbar() @@ -329,50 +351,38 @@ def test_ctrl_c_v(self): """ This test if ctrl+c and ctrl+v copies and pastes text""" - self.dash.ensure_hidden() - self.dash.toggle_reveal() + self.dash.ensure_visible() - kb = Keyboard(); - kb.type("CopyPaste") + self.keyboard.type("CopyPaste") sleep(1) - kb.press_and_release("Ctrl+a") - kb.press_and_release("Ctrl+c") - kb.press_and_release("Ctrl+v") - kb.press_and_release("Ctrl+v") + 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') def test_ctrl_x_v(self): """ This test if ctrl+x and ctrl+v cuts and pastes text""" - self.dash.ensure_hidden() - self.dash.toggle_reveal() + self.dash.ensure_visible() - kb = Keyboard(); - kb.type("CutPaste") + self.keyboard.type("CutPaste") sleep(1) - kb.press_and_release("Ctrl+a") - kb.press_and_release("Ctrl+x") - kb.press_and_release("Ctrl+v") - kb.press_and_release("Ctrl+v") + 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') -class DashKeyboardFocusTests(AutopilotTestCase): +class DashKeyboardFocusTests(DashTestCase): """Tests that keyboard focus works.""" - def setUp(self): - super(DashKeyboardFocusTests, self).setUp() - self.dash = Dash() - - def tearDown(self): - super(DashKeyboardFocusTests, self).tearDown() - self.dash.ensure_hidden() - def test_filterbar_expansion_leaves_kb_focus(self): """Expanding or collapsing the filterbar must keave keyboard focus in the search bar. @@ -381,11 +391,100 @@ filter_bar = self.dash.get_current_lens().get_filterbar() filter_bar.ensure_collapsed() - kb = Keyboard() - kb.type("hello") + self.keyboard.type("hello") filter_bar.ensure_expanded() - kb.type(" world") + self.addCleanup(filter_bar.ensure_collapsed) + self.keyboard.type(" world") + self.assertThat(self.dash.search_string, Equals("hello world")) - searchbar = self.dash.get_searchbar() - self.assertEqual("hello world", searchbar.search_string) +class DashLensResultsTests(DashTestCase): + """Tests results from the lens view.""" + + def test_results_message_empty_search(self): + """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) + + 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) + lens = self.dash.get_current_lens() + self.assertFalse(lens.no_results_active) + + 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) + lens = self.dash.get_current_lens() + self.assertTrue(lens.no_results_active) + + 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) + results_category = lens.get_category_by_name("Installed") + old_results = results_category.get_results() + + + 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) + + filter_bar = lens.get_filterbar() + if not searchbar.showing_filters: + self.keyboard.press_and_release('Enter') + self.assertTrue(searchbar.showing_filters) + if add_cleanup: self.addCleanup(filter_bar.ensure_collapsed) + + # Tab to the "Type" filter in apps lens + self.keyboard.press_and_release('Tab') + new_focused_filter = filter_bar.get_focused_filter() + self.assertIsNotNone(new_focused_filter) + + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Down") + # We should be on the Education category + self.keyboard.press_and_release('Enter') + + 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) + + # so we can clean up properly + self.keyboard.press_and_release('BackSpace') + + +class DashVisualTests(DashTestCase): + """Tests that the dash visual is correct.""" + + def test_see_more_result_alignment(self): + """The see more results label should be baseline aligned + with the category name label. + """ + self.dash.reveal_application_lens() + + lens = self.dash.get_current_lens() + groups = lens.get_groups() + + for group in groups: + if (group.is_visible and group.expand_label_is_visible): + expand_label_y = group.expand_label_y + group.expand_label_baseline + name_label_y = group.name_label_y + group.name_label_baseline + self.assertThat(expand_label_y, Equals(name_label_y)) diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_hud.py unity-5.8.0/tests/autopilot/autopilot/tests/test_hud.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_hud.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_hud.py 2012-03-23 11:53:16.000000000 +0000 @@ -11,12 +11,19 @@ from autopilot.emulators.unity.hud import HudController from autopilot.tests import AutopilotTestCase - +from os import remove class HudTests(AutopilotTestCase): + scenarios = [ + ('Launcher never hide', {'launcher_hide_mode': 0}), + ('Launcher autohide', {'launcher_hide_mode': 1}), + ] + def setUp(self): super(HudTests, self).setUp() + self.set_unity_option('launcher_hide_mode', self.launcher_hide_mode) + sleep(0.5) self.hud = self.get_hud_controller() def tearDown(self): @@ -36,26 +43,34 @@ return num_active def test_initially_hidden(self): - self.assertFalse(self.hud.is_visible()) + self.assertFalse(self.hud.visible) - def test_reveal_hud(self): + def reveal_hud(self): self.hud.toggle_reveal() - self.assertTrue(self.hud.is_visible()) + for counter in range(10): + sleep(1) + if self.hud.visible: + break + self.assertTrue(self.hud.visible, "HUD did not appear.") def test_no_initial_values(self): - self.hud.toggle_reveal() + self.reveal_hud() self.assertThat(self.hud.num_buttons, Equals(0)) self.assertThat(self.hud.selected_button, Equals(0)) def test_check_a_values(self): - self.hud.toggle_reveal() + self.reveal_hud() 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)) def test_up_down_arrows(self): - self.hud.toggle_reveal() + self.reveal_hud() self.keyboard.type('a') + # Give the HUD a second to get values. + sleep(1) self.keyboard.press_and_release('Down') self.assertThat(self.hud.selected_button, Equals(2)) self.keyboard.press_and_release('Down') @@ -81,14 +96,16 @@ def test_slow_tap_not_reveal_hud(self): self.hud.toggle_reveal(tap_delay=0.3) - self.assertFalse(self.hud.is_visible()) + sleep(1) + self.assertFalse(self.hud.visible) def test_alt_f4_doesnt_show_hud(self): self.start_app('Calculator') sleep(1) # Do a very fast Alt+F4 self.keyboard.press_and_release("Alt+F4", 0.05) - self.assertFalse(self.hud.is_visible()) + sleep(1) + self.assertFalse(self.hud.visible) def test_reveal_hud_with_no_apps(self): """Hud must show even with no visible applications.""" @@ -98,11 +115,11 @@ self.hud.toggle_reveal() sleep(1) - self.assertTrue(self.hud.is_visible()) + self.assertTrue(self.hud.visible) self.hud.toggle_reveal() sleep(1) - self.assertFalse(self.hud.is_visible()) + self.assertFalse(self.hud.visible) def test_multiple_hud_reveal_does_not_break_launcher(self): """Multiple Hud reveals must not cause the launcher to set multiple @@ -166,3 +183,31 @@ 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 ".""" + + 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']) + + sleep(1) + self.keyboard.type("0") + self.keyboard.type(" ") + self.keyboard.type("1") + + self.hud.toggle_reveal() + sleep(1) + + self.keyboard.type("undo") + self.keyboard.press_and_release('Return') + sleep(1) + + self.keyboard.press_and_release("Ctrl+s") + sleep(1) + + contents = open("/tmp/autopilot_gedit_undo_test_temp_file.txt").read().strip('\n') + self.assertEqual("0 ", contents) + diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_ibus.py unity-5.8.0/tests/autopilot/autopilot/tests/test_ibus.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_ibus.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_ibus.py 2012-03-23 11:53:16.000000000 +0000 @@ -14,7 +14,7 @@ ) from autopilot.emulators.unity.dash import Dash from autopilot.emulators.X11 import Keyboard -from autopilot.tests import AutopilotTestCase +from autopilot.tests import AutopilotTestCase, multiply_scenarios from time import sleep @@ -99,11 +99,17 @@ class IBusTestsAnthy(IBusTests): """Tests for the Anthy(Japanese) input engine.""" - scenarios = [ - ('system', {'input': 'shisutemu ', 'result': u'\u30b7\u30b9\u30c6\u30e0'}), - ('game', {'input': 'ge-mu ', 'result': u'\u30b2\u30fc\u30e0'}), - ('user', {'input': 'yu-za- ', 'result': u'\u30e6\u30fc\u30b6\u30fc'}), + scenarios = multiply_scenarios( + [ + ('system', {'input': 'shisutemu ', 'result': u'\u30b7\u30b9\u30c6\u30e0'}), + ('game', {'input': 'ge-mu ', 'result': u'\u30b2\u30fc\u30e0'}), + ('user', {'input': 'yu-za- ', 'result': u'\u30e6\u30fc\u30b6\u30fc'}), + ], + [ + ('commit_j', {'commit_key': 'Ctrl+j'}), + ('commit_enter', {'commit_key': 'Enter'}), ] + ) def test_simple_input(self): self.activate_input_engine_or_skip("anthy") @@ -112,7 +118,7 @@ self.activate_ibus() sleep(0.5) self.kb.type(self.input) - self.kb.press_and_release("Ctrl+j") + self.kb.press_and_release(self.commit_key) dash_search_string = self.dash.get_searchbar().search_string self.deactivate_ibus() self.dash.ensure_hidden() diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_launcher.py unity-5.8.0/tests/autopilot/autopilot/tests/test_launcher.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_launcher.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_launcher.py 2012-03-23 11:53:16.000000000 +0000 @@ -8,7 +8,7 @@ # by the Free Software Foundation. import logging -from testtools.matchers import Equals, LessThan, GreaterThan +from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan from time import sleep from autopilot.tests import AutopilotTestCase @@ -39,6 +39,12 @@ """Get the launcher for the current scenario.""" return self.launcher.get_launcher_for_monitor(self.launcher_num) + def setUp(self): + super(ScenariodLauncherTests, self).setUp() + # 0 means launchers on all monitors. + self.set_unity_option('num_launchers', 0) + self.set_unity_log_level("unity.launcher", "DEBUG") + class LauncherTests(ScenariodLauncherTests): """Test the launcher.""" @@ -51,55 +57,108 @@ """Test that starting the Launcher switcher puts the keyboard focus on item 0.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) 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)) - def test_launcher_switcher_end_works(self): + def test_launcher_switcher_cancel_works(self): """Test that ending the launcher switcher actually works.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() + launcher_instance.switcher_start() sleep(.5) - launcher_instance.end_switcher(cancel=True) + launcher_instance.switcher_cancel() sleep(.5) self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + def test_launcher_switcher_escape_works(self): + """Test that ending the launcher switcher actually works.""" + sleep(.5) + launcher_instance = self.get_launcher() + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) + sleep(.25) + self.assertThat(self.launcher.key_nav_is_active, Equals(True)) + sleep(.25) + self.keyboard.press_and_release("Escape") + sleep(.25) + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + def test_launcher_switcher_next_works(self): """Moving to the next launcher item while switcher is activated must work.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) + logger.info("After starting, keynav selection is %d", self.launcher.key_nav_selection) launcher_instance.switcher_next() sleep(.5) - self.assertThat(self.launcher.key_nav_selection, Equals(1)) + 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)) def test_launcher_switcher_prev_works(self): """Moving to the previous launcher item while switcher is activated must work.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) + sleep(.25) + self.assertThat(self.launcher.key_nav_selection, Equals(0)) + + launcher_instance.switcher_prev() + sleep(.25) + self.assertThat(self.launcher.key_nav_selection, NotEquals(0)) + + def test_launcher_switcher_down_works(self): + """Pressing the down arrow key while switcher is activated must work.""" sleep(.5) + launcher_instance = self.get_launcher() + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) + sleep(.25) + self.assertThat(self.launcher.key_nav_selection, Equals(0)) - launcher_instance.switcher_next() + 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)) + + def test_launcher_switcher_up_works(self): + """Pressing the up arrow key while switcher is activated must work.""" sleep(.5) - launcher_instance.switcher_prev() + launcher_instance = self.get_launcher() + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) + sleep(.25) self.assertThat(self.launcher.key_nav_selection, Equals(0)) + launcher_instance.switcher_up() + sleep(.25) + self.assertThat(self.launcher.key_nav_selection, NotEquals(0)) + def test_launcher_switcher_next_doesnt_show_shortcuts(self): """Moving forward in launcher switcher must not show launcher shortcuts.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) launcher_instance.switcher_next() sleep(2) @@ -109,8 +168,8 @@ """Moving backward in launcher switcher must not show launcher shortcuts.""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) launcher_instance.switcher_next() sleep(2) @@ -123,8 +182,8 @@ """Launcher Switcher must loop through icons when cycling forwards""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) prev_icon = 0 @@ -147,8 +206,8 @@ """Launcher Switcher must loop through icons when cycling backwards""" sleep(.5) launcher_instance = self.get_launcher() - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) launcher_instance.switcher_prev() @@ -182,8 +241,8 @@ self.addCleanup(launcher_instance.keyboard_unreveal_launcher) sleep(1) - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) self.assertThat(self.launcher.key_nav_is_active, Equals(True)) @@ -198,8 +257,8 @@ self.addCleanup(launcher_instance.keyboard_unreveal_launcher) sleep(1) - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) launcher_instance.switcher_next() @@ -210,7 +269,7 @@ sleep(.5) self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(True)) - def test_launcher_switcher_ungrabbed_using_shorcuts(self): + def test_launcher_switcher_using_shorcuts(self): """Using some other shortcut while switcher is active must cancel switcher.""" sleep(.5) @@ -219,8 +278,8 @@ launcher_instance.keyboard_reveal_launcher() self.addCleanup(launcher_instance.keyboard_unreveal_launcher) sleep(1) - launcher_instance.start_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.switcher_start() + self.addCleanup(launcher_instance.switcher_cancel) sleep(.5) self.keyboard.press_and_release("s") @@ -234,8 +293,8 @@ """Tests we can initiate keyboard navigation on the launcher.""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) self.assertThat(self.launcher.key_nav_is_active, Equals(True)) @@ -245,9 +304,9 @@ """Test that we can exit keynav mode.""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() + launcher_instance.key_nav_start() sleep(.5) - launcher_instance.end_switcher(cancel=True) + 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)) @@ -255,8 +314,8 @@ """Test keynav mode starts at index 0.""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) self.assertThat(self.launcher.key_nav_selection, Equals(0)) @@ -265,23 +324,29 @@ """Must be able to move forwards while in keynav mode.""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) - launcher_instance.switcher_next() + launcher_instance.key_nav_next() sleep(.5) - self.assertThat(self.launcher.key_nav_selection, Equals(1)) + # 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)) def test_launcher_keynav_prev_works(self): """Must be able to move backwards while in keynav mode.""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) - launcher_instance.switcher_next() + launcher_instance.key_nav_next() sleep(.5) - launcher_instance.switcher_prev() + launcher_instance.key_nav_prev() sleep(.5) self.assertThat(self.launcher.key_nav_selection, Equals(0)) @@ -289,13 +354,13 @@ """Launcher keynav must loop through icons when cycling forwards""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.25) prev_icon = 0 for icon in range(1, self.launcher.model.num_launcher_icons()): - launcher_instance.switcher_next() + 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 @@ -304,18 +369,18 @@ prev_icon = self.launcher.key_nav_selection sleep(.5) - launcher_instance.switcher_next() + launcher_instance.key_nav_next() self.assertThat(self.launcher.key_nav_selection, Equals(0)) def test_launcher_keynav_cycling_backward(self): """Launcher keynav must loop through icons when cycling backwards""" launcher_instance = self.get_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.25) - launcher_instance.switcher_prev() + 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)) @@ -324,13 +389,13 @@ launcher_instance = self.get_launcher() launcher_instance.move_mouse_to_right_of_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) - launcher_instance.switcher_next() + launcher_instance.key_nav_next() sleep(.5) - launcher_instance.switcher_enter_quicklist() - self.addCleanup(launcher_instance.switcher_exit_quicklist) + launcher_instance.key_nav_enter_quicklist() + self.addCleanup(launcher_instance.key_nav_exit_quicklist) sleep(.5) self.assertThat(launcher_instance.is_quicklist_open(), Equals(True)) @@ -339,32 +404,71 @@ launcher_instance = self.get_launcher() launcher_instance.move_mouse_to_right_of_launcher() sleep(.5) - launcher_instance.grab_switcher() - self.addCleanup(launcher_instance.end_switcher, True) + launcher_instance.key_nav_start() + self.addCleanup(launcher_instance.key_nav_cancel) sleep(.5) - launcher_instance.switcher_next() + launcher_instance.key_nav_next() sleep(.5) - launcher_instance.switcher_enter_quicklist() + launcher_instance.key_nav_enter_quicklist() sleep(.5) - launcher_instance.switcher_exit_quicklist() + launcher_instance.key_nav_exit_quicklist() self.assertThat(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)) + def test_launcher_keynav_mode_toggles(self): + """Tests that keynav mode toggles with Alt+F1.""" + launcher_instance = self.get_launcher() + + launcher_instance.key_nav_start() + launcher_instance.key_nav_start() + + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + + def test_launcher_keynav_alt_tab_quits(self): + """Tests that alt+tab exits keynav mode.""" + launcher_instance = self.get_launcher() + launcher_instance.key_nav_start() + + self.switcher.initiate() + sleep(1) + self.switcher.stop() + + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + + def test_launcher_keynav_alt_grave_quits(self): + """Tests that alt+` exits keynav mode.""" + launcher_instance = self.get_launcher() + launcher_instance.key_nav_start() + + self.switcher.initiate_detail_mode() + sleep(1) + self.switcher.stop() + + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + + class LauncherRevealTests(ScenariodLauncherTests): """Test the launcher reveal bahavior when in autohide mode.""" def setUp(self): super(LauncherRevealTests, self).setUp() - self.set_unity_option('launcher_hide_mode', True) - sleep(1) + 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.") def test_reveal_on_mouse_to_edge(self): """Tests reveal of launchers by mouse pressure.""" launcher_instance = self.get_launcher() launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.reveal_launcher() + launcher_instance.mouse_reveal_launcher() self.assertThat(launcher_instance.is_showing(), Equals(True)) def test_reveal_with_mouse_under_launcher(self): @@ -375,9 +479,12 @@ launcher_instance = self.get_launcher() launcher_instance.move_mouse_over_launcher() - launcher_instance.keyboard_reveal_launcher() - launcher_instance.keyboard_unreveal_launcher() + # we can't use "launcher_instance.keyboard_reveal_launcher()" + # since it moves the mouse out of the way, invalidating the test. + self.keybinding_hold("launcher/reveal") sleep(1) + self.keybinding_release("launcher/reveal") + sleep(2) self.assertThat(launcher_instance.is_showing(), Equals(False)) def test_reveal_does_not_hide_again(self): @@ -388,7 +495,7 @@ launcher_instance = self.get_launcher() launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.reveal_launcher() + launcher_instance.mouse_reveal_launcher() sleep(2) self.assertThat(launcher_instance.is_showing(), Equals(True)) @@ -399,6 +506,6 @@ screens.move_mouse_to_monitor(launcher_instance.monitor) self.mouse.press(1) - launcher_instance.reveal_launcher() + launcher_instance.mouse_reveal_launcher() self.assertThat(launcher_instance.is_showing(), Equals(False)) self.mouse.release(1) diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py unity-5.8.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,322 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: 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. + +from testtools.matchers import Equals +from time import sleep + +from autopilot.tests import AutopilotTestCase +from autopilot.emulators.unity.shortcut_hint import ShortcutController +from autopilot.emulators.X11 import ScreenGeometry + + +class BaseShortcutHintTests(AutopilotTestCase): + """Base class for the shortcut hint tests""" + + def setUp(self): + super(BaseShortcutHintTests, self).setUp() + + self.DEFAULT_WIDTH = 970; + self.DEFAULT_HEIGHT = 680; + + self.shortcut_hint = self.get_shortcut_controller() + self.set_unity_option('shortcut_overlay', True) + self.skip_if_monitor_too_small() + sleep(1) + + def skip_if_monitor_too_small(self): + screen = ScreenGeometry(); + monitor = screen.get_primary_monitor() + monitor_geo = screen.get_monitor_geometry(monitor); + monitor_w = monitor_geo[2]; + monitor_h = monitor_geo[3]; + launcher_width = self.launcher.get_launcher_for_monitor(monitor).geometry[2]; + panel_height = 24 # TODO get it from panel + + if ((monitor_w - launcher_width) <= self.DEFAULT_WIDTH or + (monitor_h - panel_height) <= self.DEFAULT_HEIGHT): + self.skipTest("This test requires a bigger screen, to show the ShortcutHint") + + def get_shortcut_controller(self): + controllers = ShortcutController.get_all_instances() + self.assertThat(len(controllers), Equals(1)) + return controllers[0] + + def get_launcher(self): + # We could parameterise this so all tests run on both monitors (if MM is + # set up), but I think it's fine to just always use monitor primary monitor: + screen = ScreenGeometry(); + monitor = screen.get_primary_monitor() + return self.launcher.get_launcher_for_monitor(monitor) + + +class ShortcutHintTests(BaseShortcutHintTests): + """Test the shortcuthint.""" + + 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)) + + def test_shortcut_hint_reveal_timeout(self): + """Test that the shortcut hint is shown when it should.""" + sleep(.5) + timeout = self.shortcut_hint.get_show_timeout() + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.hide) + + 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)) + + 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) + + self.shortcut_hint.hide() + sleep(.25) + self.assertThat(self.shortcut_hint.is_visible(), 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) + + 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)) + + def test_shortcut_hint_geometries(self): + """Test that the shortcut hint has the wanted geometries.""" + sleep(.5) + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.hide) + sleep(self.shortcut_hint.get_show_timeout()) + + (x, y, w, h) = self.shortcut_hint.get_geometry() + self.assertThat(w, Equals(self.DEFAULT_WIDTH)) + self.assertThat(h, Equals(self.DEFAULT_HEIGHT)) + + +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()) + + 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)) + + def test_launcher_switcher_next_doesnt_show_shortcut_hint(self): + """Moving forward in launcher switcher must not show the shortcut hint.""" + sleep(.5) + 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.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)) + + def test_launcher_switcher_prev_doesnt_show_shortcut_hint(self): + """Moving backward in launcher switcher must not show the shortcut hint.""" + sleep(.5) + 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.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) + + self.assertThat(self.shortcut_hint.is_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. + + """ + 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)) + + 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)) + + 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. + + """ + 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)) + + 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_prev() + sleep(.25) + launcher.switcher_prev() + sleep(show_timeout) + + self.assertThat(self.shortcut_hint.is_visible(), Equals(True)) + + def test_launcher_switcher_cancel_doesnt_hide_shortcut_hint(self): + """Cancelling the launcher switcher (by Escape) should 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) + + sleep(show_timeout) + self.assertThat(self.shortcut_hint.is_visible(), Equals(True)) + + 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)) + + 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)) + + 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) + + sleep(show_timeout) + self.assertThat(self.shortcut_hint.is_visible(), Equals(True)) + + 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)) + + 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.shortcut_hint.cancel() + sleep(.25) + self.assertThat(self.shortcut_hint.is_visible(), 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 + be shown. + + """ + launcher = self.get_launcher() + 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)) + self.assertThat(launcher.are_shortcuts_showing(), Equals(True)) + + def test_shortcut_hint_shows_with_launcher_icons_hints(self): + """When the launcher icons hints are shown also the shortcut hint should + be shown. + + """ + 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)) diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_switcher.py unity-5.8.0/tests/autopilot/autopilot/tests/test_switcher.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_switcher.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_switcher.py 2012-03-23 11:53:16.000000000 +0000 @@ -65,7 +65,79 @@ self.assertThat(start, NotEquals(0)) self.assertThat(end, Equals(start - 1)) - self.set_timeout_setting(True) + + def test_switcher_scroll_next(self): + self.set_timeout_setting(False) + sleep(1) + + self.switcher.initiate() + sleep(.2) + + start = self.switcher.get_selection_index() + self.switcher.next_icon_mouse() + sleep(.2) + + end = self.switcher.get_selection_index() + self.assertThat(start, NotEquals(0)) + self.assertThat(end, Equals(start + 1)) + + self.switcher.terminate() + + def test_switcher_scroll_prev(self): + self.set_timeout_setting(False) + sleep(1) + + self.switcher.initiate() + sleep(.2) + + start = self.switcher.get_selection_index() + self.switcher.previous_icon_mouse() + sleep(.2) + + end = self.switcher.get_selection_index() + self.assertThat(start, NotEquals(0)) + self.assertThat(end, Equals(start - 1)) + + self.switcher.terminate() + + def test_switcher_scroll_next_ignores_fast_events(self): + self.set_timeout_setting(False) + sleep(1) + + self.switcher.initiate() + sleep(.2) + + # Quickly repeatead events should be ignored (except the first) + start = self.switcher.get_selection_index() + self.switcher.next_icon_mouse() + self.switcher.next_icon_mouse() + self.switcher.next_icon_mouse() + sleep(.2) + + end = self.switcher.get_selection_index() + self.assertThat(start, NotEquals(0)) + self.assertThat(end, Equals(start + 1)) + + self.switcher.terminate() + + def test_switcher_scroll_prev_ignores_fast_events(self): + self.set_timeout_setting(False) + sleep(1) + + self.switcher.initiate() + sleep(.2) + + # Quickly repeatead events should be ignored (except the first) + start = self.switcher.get_selection_index() + self.switcher.previous_icon_mouse() + self.switcher.previous_icon_mouse() + self.switcher.previous_icon_mouse() + sleep(.2) + + end = self.switcher.get_selection_index() + self.assertThat(end, Equals(start - 1)) + + self.switcher.terminate() def test_switcher_arrow_key_does_not_init(self): self.set_timeout_setting(False) diff -Nru unity-5.6.0/tests/autopilot/autopilot/tests/test_unity_logging.py unity-5.8.0/tests/autopilot/autopilot/tests/test_unity_logging.py --- unity-5.6.0/tests/autopilot/autopilot/tests/test_unity_logging.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/autopilot/autopilot/tests/test_unity_logging.py 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,67 @@ +# -*- 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. + +from os import remove +from os.path import exists +from tempfile import mktemp +from testtools.matchers import Contains, Not +from time import sleep + + +from autopilot.tests import AutopilotTestCase +from autopilot.emulators.unity import ( + start_log_to_file, + reset_logging, + set_log_severity, + log_unity_message, + ) + + +class UnityLoggingTests(AutopilotTestCase): + """Tests for Unity's debug logging framework.""" + + def start_new_log_file(self): + fpath = mktemp() + start_log_to_file(fpath) + return fpath + + def test_new_file_created(self): + """Unity must create log file when we call start_log_to_file. + """ + fpath = self.start_new_log_file() + self.addCleanup(remove, fpath) + self.addCleanup(reset_logging) + sleep(1) + self.assertTrue(exists(fpath)) + + def test_messages_arrive_in_file(self): + fpath = self.start_new_log_file() + log_unity_message("WARNING", "This is a warning of things to come") + sleep(1) + reset_logging() + + with open(fpath, 'r') as f: + self.assertThat(f.read(), Contains("This is a warning of things to come")) + + def test_default_log_level_unchanged(self): + fpath = self.start_new_log_file() + log_unity_message("DEBUG", "This is some INFORMATION") + sleep(1) + reset_logging() + with open(fpath, 'r') as f: + self.assertThat(f.read(), Not(Contains("This is some INFORMATION"))) + + def test_can_change_log_level(self): + fpath = self.start_new_log_file() + set_log_severity("", "DEBUG") + self.addCleanup(set_log_severity, "", "INFO") + log_unity_message("DEBUG", "This is some more INFORMATION") + sleep(1) + reset_logging() + with open(fpath, 'r') as f: + self.assertThat(f.read(), Contains("This is some more INFORMATION")) diff -Nru unity-5.6.0/tests/CMakeLists.txt unity-5.8.0/tests/CMakeLists.txt --- unity-5.6.0/tests/CMakeLists.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 @@ -45,9 +45,18 @@ # We can't have convenience libs so we need to rebuild with what we need # Please keep actual test files alphabetically at top and then files # from ../${UNITY_SRC} or ../../services in alphabetically after that +find_program(GLIB_GENMARSHAL glib-genmarshal) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c + COMMAND ${GLIB_GENMARSHAL} ARGS ../services/panel-marshal.list --body --prefix=panel_marshal > ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c + COMMAND ${GLIB_GENMARSHAL} ARGS ../services/panel-marshal.list --header --prefix=panel_marshal > ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ../services/panel-marshal.list + COMMENT "Generating marshallers for panel-service") + add_executable (test-unit - unit/TestQuicklistMenuitems.cpp unit/TestMain.cpp + unit/TestQuicklistMenuitems.cpp + unit/TestPanelService.cpp unit/TestUBus.cpp unit/TestStaticCairoText.cpp ${UNITY_SRC}/CairoBaseWindow.cpp @@ -59,6 +68,8 @@ ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp ${UNITY_SRC}/QuicklistView.cpp ${UNITY_SRC}/StaticCairoText.cpp + ../services/panel-service.c + ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c ${UNITY_SRC}/ubus-server.cpp ) add_dependencies (test-unit unity-core-${UNITY_API_VERSION}) @@ -114,6 +125,10 @@ test_glib_signals_utils.h test_glib_variant.cpp ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp + test_indicator.cpp + test_indicator_appmenu.cpp + test_indicator_entry.cpp + test_indicators.cpp test_favorite_store_gsettings.cpp test_favorite_store_private.cpp test_home_lens.cpp @@ -123,43 +138,29 @@ test_main_xless.cpp test_grabhandle.cpp test_unityshell_private.cpp - ${UNITY_SRC}/AbstractLauncherIcon.h + test_lensview_impl.cpp ${UNITY_SRC}/AbstractLauncherIcon.cpp + ${UNITY_SRC}/AbstractPlacesGroup.cpp + ${UNITY_SRC}/AbstractPlacesGroup.h ${UNITY_SRC}/AbstractShortcutHint.h ${UNITY_SRC}/Animator.cpp - ${UNITY_SRC}/Animator.h - ${UNITY_SRC}/DebugDBusInterface.h ${UNITY_SRC}/DebugDBusInterface.cpp - ${UNITY_SRC}/XPathQueryPart.h ${UNITY_SRC}/XPathQueryPart.cpp ${UNITY_SRC}/FavoriteStore.cpp - ${UNITY_SRC}/FavoriteStore.h ${UNITY_SRC}/FavoriteStoreGSettings.cpp - ${UNITY_SRC}/FavoriteStoreGSettings.h - ${UNITY_SRC}/IconTextureSource.h ${UNITY_SRC}/IconTextureSource.cpp ${UNITY_SRC}/LauncherModel.cpp - ${UNITY_SRC}/LauncherModel.h + ${UNITY_SRC}/LensViewPrivate.cpp ${UNITY_SRC}/FavoriteStorePrivate.cpp - ${UNITY_SRC}/FavoriteStorePrivate.h ${UNITY_SRC}/MockLauncherIcon.h ${UNITY_SRC}/MockShortcutHint.h ${UNITY_SRC}/ShortcutModel.cpp - ${UNITY_SRC}/ShortcutModel.h ${UNITY_SRC}/ShortcutHintPrivate.cpp - ${UNITY_SRC}/ShortcutHintPrivate.h - ${UNITY_SRC}/SwitcherModel.cpp - ${UNITY_SRC}/SwitcherModel.h ${UNITY_SRC}/Introspectable.cpp - ${UNITY_SRC}/Introspectable.h ${UNITY_SRC}/TextureCache.cpp - ${UNITY_SRC}/TextureCache.h ${UNITY_SRC}/Timer.cpp - ${UNITY_SRC}/Timer.h ${UNITY_SRC}/UnityshellPrivate.cpp - ${UNITY_SRC}/UnityshellPrivate.h ${UNITY_SRC}/WindowManager.cpp - ${UNITY_SRC}/WindowManager.h ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp @@ -177,7 +178,6 @@ test_filter.cpp test_gdbus_proxy.cpp test_hud.cpp - test_indicator_entry.cpp test_lens.cpp test_main_dbus.cpp test_model.cpp @@ -195,14 +195,27 @@ test_texture_cache.cpp test_main.cpp test_icon_loader.cpp + test_switcher_controller.cpp + test_switcher_model.cpp + ${UNITY_SRC}/AbstractLauncherIcon.cpp + ${UNITY_SRC}/BackgroundEffectHelper.cpp ${UNITY_SRC}/DashViewPrivate.cpp - ${UNITY_SRC}/DashViewPrivate.h ${UNITY_SRC}/TextureCache.cpp - ${UNITY_SRC}/TextureCache.h ${UNITY_SRC}/IconLoader.cpp - ${UNITY_SRC}/IconLoader.h + ${UNITY_SRC}/IconRenderer.cpp + ${UNITY_SRC}/IconTextureSource.cpp + ${UNITY_SRC}/Introspectable.cpp + ${UNITY_SRC}/LayoutSystem.cpp + ${UNITY_SRC}/StaticCairoText.cpp + ${UNITY_SRC}/SwitcherController.cpp + ${UNITY_SRC}/SwitcherModel.cpp + ${UNITY_SRC}/SwitcherView.cpp ${UNITY_SRC}/Timer.cpp - ${UNITY_SRC}/Timer.h + ${UNITY_SRC}/UBusWrapper.cpp + ${UNITY_SRC}/UnityWindowStyle.cpp + ${UNITY_SRC}/UnityWindowView.cpp + ${UNITY_SRC}/ubus-server.cpp + ${UNITY_SRC}/WindowManager.cpp ) target_link_libraries(test-gtest gtest) add_test(UnityGTest test-gtest) diff -Nru unity-5.6.0/tests/test_filesystem_lenses.cpp unity-5.8.0/tests/test_filesystem_lenses.cpp --- unity-5.6.0/tests/test_filesystem_lenses.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_filesystem_lenses.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -18,7 +18,7 @@ return FALSE; }; - guint32 timeout_id = g_timeout_add_seconds(10, timeout_cb, &timeout_reached); + guint32 timeout_id = g_timeout_add(10000, timeout_cb, &timeout_reached); while (!result && !timeout_reached) { diff -Nru unity-5.6.0/tests/test_gdbus_proxy.cpp unity-5.8.0/tests/test_gdbus_proxy.cpp --- unity-5.6.0/tests/test_gdbus_proxy.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_gdbus_proxy.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -60,8 +60,8 @@ return FALSE; }; - guint timeout_source = g_timeout_add_seconds(1, timeout_check, this); // check once a second - guint bailout_source = g_timeout_add_seconds(10, timeout_bailout, this); // bail out after ten + guint timeout_source = g_timeout_add(1000, timeout_check, this); // check once a second + guint bailout_source = g_timeout_add(10000, timeout_bailout, this); // bail out after ten g_main_loop_run(loop_); g_source_remove(timeout_source); @@ -114,7 +114,7 @@ return FALSE; }; - guint bailout_source = g_timeout_add_seconds(10, timeout_bailout, this); + guint bailout_source = g_timeout_add(10000, timeout_bailout, this); EXPECT_EQ(proxy->IsConnected(), true); // fail if we are not connected proxy->Connect("TestSignal", signal_connection); diff -Nru unity-5.6.0/tests/test_hud.cpp unity-5.8.0/tests/test_hud.cpp --- unity-5.6.0/tests/test_hud.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_hud.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -2,6 +2,7 @@ #include #include #include +#include using namespace std; @@ -22,6 +23,7 @@ unity::hud::Hud::Queries queries; bool query_return_result; bool connected_result; + int number_signals_found; }; TEST_F(TestHud, TestConstruction) @@ -57,8 +59,8 @@ return FALSE; }; - g_timeout_add_seconds(1, timeout_check, this); - g_timeout_add_seconds(10, timeout_bailout, this); + g_timeout_add(1000, timeout_check, this); + g_timeout_add(10000, timeout_bailout, this); g_main_loop_run(loop_); @@ -85,9 +87,9 @@ return FALSE; }; - hud->queries_updated.connect(query_connection); + sigc::connection connection = hud->queries_updated.connect(query_connection); - guint source_id = g_timeout_add_seconds(10, timeout_bailout, this); + guint source_id = g_timeout_add(10000, timeout_bailout, this); // next check we get 30 entries from this specific known callback hud->RequestQuery("Request30Queries"); @@ -98,7 +100,43 @@ // finally close the connection - Nothing to check for here hud->CloseQuery(); + connection.disconnect(); } +TEST_F(TestHud, TestSigEmission) +{ + // checks that the signal emission from Hud is working correctly + // the service is setup to emit the same signal every 1000ms + // using the same query key as its StarQuery method + // so calling StartQuery and listening we expect > 1 + // signal emission + number_signals_found = 0; + + // make sure we receive the queries + auto query_connection = [this](unity::hud::Hud::Queries queries_) + { + number_signals_found += 1; + }; + + auto timeout_bailout = [] (gpointer data) -> gboolean + { + g_main_loop_quit(loop_); + return FALSE; + }; + + sigc::connection connection = hud->queries_updated.connect(query_connection); + + hud->RequestQuery("Request30Queries"); + guint source_id = g_timeout_add(10000, timeout_bailout, this); + + g_main_loop_run(loop_); + EXPECT_GT(number_signals_found, 1); + g_source_remove(source_id); + + // finally close the connection - Nothing to check for here + hud->CloseQuery(); + connection.disconnect(); + +} } diff -Nru unity-5.6.0/tests/test_indicator_appmenu.cpp unity-5.8.0/tests/test_indicator_appmenu.cpp --- unity-5.6.0/tests/test_indicator_appmenu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_indicator_appmenu.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,66 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + */ + +#include + +#include + +using namespace std; +using namespace unity; +using namespace indicator; + +namespace +{ + +TEST(TestAppmenuIndicator, Construction) +{ + AppmenuIndicator indicator("indicator-appmenu"); + + EXPECT_EQ(indicator.name(), "indicator-appmenu"); + EXPECT_TRUE(indicator.IsAppmenu()); +} + +TEST(TestAppmenuIndicator, ShowAppmenu) +{ + AppmenuIndicator indicator("indicator-appmenu"); + + bool signal_emitted = false; + int show_x, show_y; + unsigned int show_xid, show_timestamp; + + // Connecting to signals + indicator.on_show_appmenu.connect([&] (unsigned int xid, int x, int y, + unsigned int timestamp) { + signal_emitted = true; + show_xid = xid; + show_x = x; + show_y = y; + show_timestamp = timestamp; + }); + + indicator.ShowAppmenu(123456789, 50, 100, 1328308554); + EXPECT_TRUE(signal_emitted); + + EXPECT_EQ(show_xid, 123456789); + EXPECT_EQ(show_x, 50); + EXPECT_EQ(show_y, 100); + EXPECT_EQ(show_timestamp, 1328308554); +} + +} diff -Nru unity-5.6.0/tests/test_indicator.cpp unity-5.8.0/tests/test_indicator.cpp --- unity-5.6.0/tests/test_indicator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_indicator.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,207 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + */ + +#include + +#include + +using namespace std; +using namespace unity; +using namespace indicator; + +namespace +{ + +TEST(TestIndicator, Construction) +{ + Indicator indicator("indicator-test"); + + EXPECT_EQ(indicator.name(), "indicator-test"); + EXPECT_FALSE(indicator.IsAppmenu()); + EXPECT_EQ(indicator.GetEntry("test-entry"), nullptr); + EXPECT_TRUE(indicator.GetEntries().empty()); +} + +TEST(TestIndicator, Syncing) +{ + Indicator::Entries sync_data; + Entry* entry; + + Indicator indicator("indicator-test"); + + // Connecting to signals + Indicator::Entries added; + indicator.on_entry_added.connect([&added] (Entry::Ptr const& e) { + added.push_back(e); + }); + + std::vector removed; + sigc::connection removed_connection = indicator.on_entry_removed.connect([&removed] + (std::string const& en_id) { + removed.push_back(en_id); + }); + + entry = new Entry("test-entry-1", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + Entry::Ptr entry1(entry); + sync_data.push_back(entry1); + + entry = new Entry("test-entry-2", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + Entry::Ptr entry2(entry); + sync_data.push_back(entry2); + + entry = new Entry("test-entry-3", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + Entry::Ptr entry3(entry); + sync_data.push_back(entry3); + + // Sync the indicator, adding 3 entries + indicator.Sync(sync_data); + EXPECT_EQ(indicator.GetEntries().size(), 3); + EXPECT_EQ(indicator.GetEntry("test-entry-2"), entry2); + EXPECT_EQ(added.size(), 3); + EXPECT_EQ(added.front()->id(), "test-entry-1"); + EXPECT_EQ(added.back()->id(), "test-entry-3"); + EXPECT_EQ(removed.size(), 0); + + added.clear(); + removed.clear(); + + // Sync the indicator removing an entry + sync_data.remove(entry2); + EXPECT_EQ(sync_data.size(), 2); + + indicator.Sync(sync_data); + EXPECT_EQ(indicator.GetEntries().size(), 2); + EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr); + EXPECT_EQ(added.size(), 0); + EXPECT_EQ(removed.size(), 1); + EXPECT_EQ(removed.front(), entry2->id()); + + // Sync the indicator removing an entry and adding a new one + entry = new Entry("test-entry-4", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + Entry::Ptr entry4(entry); + sync_data.push_back(entry4); + sync_data.remove(entry3); + EXPECT_EQ(sync_data.size(), 2); + + added.clear(); + removed.clear(); + + indicator.Sync(sync_data); + EXPECT_EQ(indicator.GetEntries().size(), 2); + EXPECT_EQ(added.size(), 1); + EXPECT_EQ(added.front(), entry4); + EXPECT_EQ(removed.size(), 1); + EXPECT_EQ(removed.front(), entry3->id()); + + // Remove all the indicators + added.clear(); + removed.clear(); + + sync_data.clear(); + indicator.Sync(sync_data); + EXPECT_EQ(indicator.GetEntries().size(), 0); + EXPECT_EQ(added.size(), 0); + EXPECT_EQ(removed.size(), 2); + + removed_connection.disconnect(); +} + +TEST(TestIndicator, ChildrenSignals) +{ + Indicator::Entries sync_data; + Entry* entry; + + Indicator indicator("indicator-test"); + + entry = new Entry("test-entry-1", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + Entry::Ptr entry1(entry); + sync_data.push_back(entry1); + + indicator.Sync(sync_data); + + std::string show_entry; + int show_x, show_y; + unsigned int show_xid, show_button, show_timestamp; + + // Connecting to signals + indicator.on_show_menu.connect([&] (std::string const& eid, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp) { + show_entry = eid; + show_xid = xid; + show_x = x; + show_y = y; + show_button = button; + show_timestamp = timestamp; + }); + + entry1->ShowMenu(123456789, 50, 100, 2, 1328058770); + EXPECT_EQ(show_entry, "test-entry-1"); + EXPECT_EQ(show_xid, 123456789); + EXPECT_EQ(show_x, 50); + EXPECT_EQ(show_y, 100); + EXPECT_EQ(show_button, 2); + EXPECT_EQ(show_timestamp, 1328058770); + + // Check if a removed entry still emits a signal to the old indicator + show_entry = "invalid-entry"; + sync_data.remove(entry1); + indicator.Sync(sync_data); + + entry1->ShowMenu(123456789, 50, 100, 2, 1328058770); + EXPECT_EQ(show_entry, "invalid-entry"); + + // Checking secondary activate signal + entry = new Entry("test-entry-2", "name-hint", "label", true, true, 0, "icon", + true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + indicator.Sync(sync_data); + + std::string secondary_activated; + unsigned int secondary_timestamp; + indicator.on_secondary_activate.connect([&] (std::string const& eid, + unsigned int timestamp) { + secondary_activated = eid; + secondary_timestamp = timestamp; + }); + + entry->SecondaryActivate(1328060717); + EXPECT_EQ(secondary_activated, "test-entry-2"); + EXPECT_EQ(secondary_timestamp, 1328060717); + + // Checking scroll signal + std::string scrolled_entry; + int scrolled_delta; + + indicator.on_scroll.connect([&] (std::string const& eid, int delta) { + scrolled_entry = eid; + scrolled_delta = delta; + }); + + entry->Scroll(-5); + EXPECT_EQ(scrolled_entry, "test-entry-2"); + EXPECT_EQ(scrolled_delta, -5); +} + +} diff -Nru unity-5.6.0/tests/test_indicator_entry.cpp unity-5.8.0/tests/test_indicator_entry.cpp --- unity-5.6.0/tests/test_indicator_entry.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_indicator_entry.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -24,7 +24,7 @@ EXPECT_TRUE(entry.image_visible()); EXPECT_FALSE(entry.active()); EXPECT_FALSE(entry.show_now()); - EXPECT_FALSE(entry.IsUnused()); + EXPECT_TRUE(entry.visible()); EXPECT_EQ(entry.image_type(), 1); EXPECT_EQ(entry.image_data(), "some icon"); EXPECT_EQ(entry.priority(), -1); @@ -77,21 +77,6 @@ EXPECT_EQ(entry.priority(), 5); } -TEST(TestIndicatorEntry, TestUnused) -{ - - indicator::Entry entry("id", "name_hint", "label", true, true, - 0, "some icon", false, true, -1); - - Counter counter; - entry.updated.connect(sigc::mem_fun(counter, &Counter::increment)); - - entry.MarkUnused(); - EXPECT_TRUE(entry.IsUnused()); - // Setting unused emits updated. - EXPECT_EQ(counter.count, 1); -} - TEST(TestIndicatorEntry, TestShowNowEvents) { @@ -174,16 +159,18 @@ struct ShowMenuRecorder { - void OnShowMenu(std::string const& a, int b, int c, int d, int e) + void OnShowMenu(std::string const& a, unsigned int b, int c, int d, unsigned int e, unsigned int f) { name = a; - x = b; - y = c; - timestamp = d; + xid = b; + x = c; + y = d; button = e; + timestamp = f; } std::string name; - int x, y, timestamp, button; + unsigned int xid, timestamp, button; + int x, y; }; TEST(TestIndicatorEntry, TestOnShowMenu) @@ -195,13 +182,103 @@ ShowMenuRecorder recorder; entry.on_show_menu.connect(sigc::mem_fun(recorder, &ShowMenuRecorder::OnShowMenu)); - entry.ShowMenu(10, 20, 12345, 1); + entry.ShowMenu(10, 20, 1, 12345); EXPECT_EQ(recorder.name, "id"); + EXPECT_EQ(recorder.xid, 0); EXPECT_EQ(recorder.x, 10); EXPECT_EQ(recorder.y, 20); EXPECT_EQ(recorder.timestamp, 12345); EXPECT_EQ(recorder.button, 1); } +TEST(TestIndicatorEntry, TestOnShowMenuXid) +{ + + indicator::Entry entry("xid", "name_hint", "label", true, true, + 0, "some icon", false, true, -1); + + ShowMenuRecorder recorder; + entry.on_show_menu.connect(sigc::mem_fun(recorder, &ShowMenuRecorder::OnShowMenu)); + + entry.ShowMenu(88492615, 15, 25, 2, 123456); + EXPECT_EQ(recorder.name, "xid"); + EXPECT_EQ(recorder.xid, 88492615); + EXPECT_EQ(recorder.x, 15); + EXPECT_EQ(recorder.y, 25); + EXPECT_EQ(recorder.timestamp, 123456); + EXPECT_EQ(recorder.button, 2); +} + +TEST(TestIndicatorEntry, TestVisibility) +{ + + indicator::Entry entry("id", "name_hint", "label", true, true, + 0, "some icon", false, false, -1); + + EXPECT_TRUE(entry.visible()); + + entry.setLabel("", true, true); + EXPECT_FALSE(entry.visible()); + + entry.setLabel("valid-label", true, true); + EXPECT_TRUE(entry.visible()); + + entry.setLabel("invalid-label", true, false); + EXPECT_FALSE(entry.visible()); + + entry.setImage(1, "valid-image", true, true); + EXPECT_TRUE(entry.visible()); + + entry.setImage(1, "", true, true); + EXPECT_FALSE(entry.visible()); + + entry.setImage(1, "valid-image", true, true); + EXPECT_TRUE(entry.visible()); + + entry.setImage(0, "invalid-image-type", true, true); + EXPECT_FALSE(entry.visible()); + + entry.setLabel("valid-label", true, true); + EXPECT_TRUE(entry.visible()); + + entry.setLabel("invalid-label", true, false); + EXPECT_FALSE(entry.visible()); + + entry.setImage(1, "invalid-image", true, false); + EXPECT_FALSE(entry.visible()); + + entry.setLabel("valid-label", true, true); + entry.setImage(1, "valid-image", true, true); + EXPECT_TRUE(entry.visible()); +} + +TEST(TestIndicatorEntry, TestGeometry) +{ + + indicator::Entry entry("id", "name_hint", "label", true, true, + 0, "some icon", false, true, -1); + + Counter counter; + entry.updated.connect(sigc::mem_fun(counter, &Counter::increment)); + bool geo_changed = false; + nux::Rect new_geo; + + entry.geometry_changed.connect([&] (nux::Rect const& geo) { + geo_changed = true; + new_geo = geo; + }); + + // Setting to the same value doesn't emit any events. + entry.set_geometry(nux::Rect()); + EXPECT_EQ(entry.geometry(), nux::Rect()); + EXPECT_EQ(counter.count, 0); + + // Setting to a different value does emit the events. + entry.set_geometry(nux::Rect(1, 2, 3, 4)); + EXPECT_EQ(entry.geometry(), nux::Rect(1, 2, 3, 4)); + EXPECT_TRUE(geo_changed); + EXPECT_EQ(new_geo, nux::Rect(1, 2, 3, 4)); + EXPECT_EQ(counter.count, 1); +} } diff -Nru unity-5.6.0/tests/test_indicators.cpp unity-5.8.0/tests/test_indicators.cpp --- unity-5.6.0/tests/test_indicators.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_indicators.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,586 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + */ + +#include +#include +#include + +using namespace std; +using namespace unity; +using namespace indicator; +using namespace testing; + +namespace +{ + +struct TargetData +{ + TargetData() + { + Reset(); + } + + void Reset() + { + entry = ""; + geo = nux::Rect(); + delta = 0; + x = 0; + y = 0; + xid = 0; + button = 0; + timestamp = 0; + } + + std::string entry; + nux::Rect geo; + int delta; + int x; + int y; + unsigned int xid; + unsigned int button; + unsigned int timestamp; +}; + +class MockIndicators : public Indicators +{ +public: + MockIndicators() + {} + + // Implementing Indicators virtual functions + virtual void OnEntryScroll(std::string const& entry_id, int delta) + { + target.entry = entry_id; + target.delta = delta; + } + + virtual void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp) + { + on_entry_show_menu.emit(entry_id, xid, x, y, button, timestamp); + + target.entry = entry_id; + target.xid = xid; + target.x = x; + target.y = y; + target.button = button; + target.timestamp = timestamp; + } + + virtual void OnEntrySecondaryActivate(std::string const& entry_id, + unsigned int timestamp) + { + target.entry = entry_id; + target.timestamp = timestamp; + } + + virtual void OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp) + { + on_show_appmenu.emit(xid, x, y, timestamp); + + target.xid = xid; + target.x = x; + target.y = y; + target.timestamp = timestamp; + } + + // Redirecting protected methods + Indicator::Ptr GetIndicator(std::string const& name) + { + return Indicators::GetIndicator(name); + } + + Indicator::Ptr AddIndicator(std::string const& name) + { + return Indicators::AddIndicator(name); + } + + void RemoveIndicator(std::string const& name) + { + Indicators::RemoveIndicator(name); + } + + // Utility function used to fill the class with test indicators with entries + void SetupTestChildren() + { + // Adding an indicator filled with entries into the MockIndicators + Indicator::Entries sync_data; + Entry* entry; + + Indicator::Ptr test_indicator_1 = AddIndicator("indicator-test-1"); + + entry = new Entry("indicator-test-1|entry-1", "name-hint-1", "label", true, true, + 0, "icon", true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + + entry = new Entry("indicator-test-1|entry-2", "name-hint-2", "label", true, true, + 0, "icon", true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + + entry = new Entry("indicator-test-1|entry-3", "name-hint-3", "label", true, true, + 0, "icon", true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + + // Sync the indicator, adding 3 entries + test_indicator_1->Sync(sync_data); + EXPECT_EQ(test_indicator_1->GetEntries().size(), 3); + + + // Adding another indicator filled with entries into the MockIndicators + Indicator::Ptr test_indicator_2 = AddIndicator("indicator-test-2"); + sync_data.clear(); + + entry = new Entry("indicator-test-2|entry-1", "name-hint-1", "label", true, true, + 0, "icon", true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + + entry = new Entry("indicator-test-2|entry-2", "name-hint-2", "label", true, true, + 0, "icon", true, true, -1); + sync_data.push_back(Entry::Ptr(entry)); + + // Sync the indicator, adding 2 entries + test_indicator_2->Sync(sync_data); + EXPECT_EQ(test_indicator_2->GetEntries().size(), 2); + + ASSERT_THAT(GetIndicators().size(), 2); + } + + TargetData target; +}; + +TEST(TestIndicators, Construction) +{ + { + MockIndicators indicators; + + EXPECT_TRUE(indicators.GetIndicators().empty()); + } +} + +TEST(TestIndicators, GetInvalidIndicator) +{ + MockIndicators indicators; + + ASSERT_THAT(indicators.GetIndicator("no-available-indicator"), IsNull()); +} + +TEST(TestIndicators, IndicatorsFactory) +{ + MockIndicators indicators; + + Indicator::Ptr standard_indicator = indicators.AddIndicator("libapplication.so"); + EXPECT_EQ(standard_indicator->name(), "libapplication.so"); + EXPECT_FALSE(standard_indicator->IsAppmenu()); + + Indicator::Ptr appmenu_indicator = indicators.AddIndicator("libappmenu.so"); + EXPECT_EQ(appmenu_indicator->name(), "libappmenu.so"); + EXPECT_TRUE(appmenu_indicator->IsAppmenu()); +} + +TEST(TestIndicators, IndicatorsHandling) +{ + MockIndicators indicators; + Indicators::IndicatorsList indicators_list; + + // Connecting to signals + Indicators::IndicatorsList added_list; + indicators.on_object_added.connect([&added_list] (Indicator::Ptr const& i) { + added_list.push_back(i); + }); + + Indicators::IndicatorsList removed_list; + indicators.on_object_removed.connect([&removed_list] (Indicator::Ptr const& i) { + removed_list.push_back(i); + }); + + // Adding some indicators... + Indicator::Ptr test_indicator_1(indicators.AddIndicator("indicator-test-1")); + EXPECT_EQ(indicators.GetIndicator("indicator-test-1"), test_indicator_1); + + EXPECT_EQ(added_list.size(), 1); + EXPECT_NE(std::find(added_list.begin(), added_list.end(), test_indicator_1), added_list.end()); + EXPECT_TRUE(removed_list.empty()); + + indicators_list = indicators.GetIndicators(); + EXPECT_EQ(indicators_list.size(), 1); + EXPECT_NE(std::find(indicators_list.begin(), indicators_list.end(), test_indicator_1), indicators_list.end()); + + + Indicator::Ptr test_indicator_2(indicators.AddIndicator("indicator-test-2")); + EXPECT_EQ(indicators.GetIndicator("indicator-test-2"), test_indicator_2); + + EXPECT_EQ(added_list.size(), 2); + EXPECT_NE(std::find(added_list.begin(), added_list.end(), test_indicator_2), added_list.end()); + EXPECT_TRUE(removed_list.empty()); + + indicators_list = indicators.GetIndicators(); + EXPECT_EQ(indicators_list.size(), 2); + EXPECT_NE(std::find(indicators_list.begin(), indicators_list.end(), test_indicator_2), indicators_list.end()); + + + Indicator::Ptr test_indicator_3(indicators.AddIndicator("indicator-test-3")); + EXPECT_EQ(indicators.GetIndicator("indicator-test-3"), test_indicator_3); + + EXPECT_EQ(added_list.size(), 3); + EXPECT_NE(std::find(added_list.begin(), added_list.end(), test_indicator_3), added_list.end()); + EXPECT_TRUE(removed_list.empty()); + + indicators_list = indicators.GetIndicators(); + EXPECT_EQ(indicators_list.size(), 3); + EXPECT_NE(std::find(indicators_list.begin(), indicators_list.end(), test_indicator_3), indicators_list.end()); + + + ASSERT_THAT(indicators.GetIndicator("invalid-indicator-test-4"), IsNull()); + EXPECT_EQ(added_list.size(), 3); + EXPECT_TRUE(removed_list.empty()); + EXPECT_EQ(indicators.GetIndicators().size(), 3); + + // Readding an indicator already there should do nothing + Indicator::Ptr test_indicator_3_duplicate(indicators.AddIndicator("indicator-test-3")); + EXPECT_EQ(added_list.size(), 3); + EXPECT_EQ(indicators.GetIndicator("indicator-test-3"), test_indicator_3); + EXPECT_EQ(indicators.GetIndicators().size(), 3); + EXPECT_EQ(test_indicator_3, test_indicator_3_duplicate); + + // Removing the indicators... + added_list.clear(); + + indicators.RemoveIndicator("indicator-test-2"); + ASSERT_THAT(indicators.GetIndicator("indicator-test-2"), IsNull()); + + EXPECT_TRUE(added_list.empty()); + EXPECT_NE(std::find(removed_list.begin(), removed_list.end(), test_indicator_2), removed_list.end()); + EXPECT_EQ(removed_list.size(), 1); + + indicators_list = indicators.GetIndicators(); + EXPECT_EQ(indicators_list.size(), 2); + EXPECT_EQ(std::find(indicators_list.begin(), indicators_list.end(), test_indicator_2), indicators_list.end()); + + + indicators.RemoveIndicator("indicator-test-1"); + ASSERT_THAT(indicators.GetIndicator("indicator-test-1"), IsNull()); + + EXPECT_TRUE(added_list.empty()); + EXPECT_NE(std::find(removed_list.begin(), removed_list.end(), test_indicator_1), removed_list.end()); + EXPECT_EQ(removed_list.size(), 2); + + indicators_list = indicators.GetIndicators(); + EXPECT_EQ(indicators_list.size(), 1); + EXPECT_EQ(std::find(indicators_list.begin(), indicators_list.end(), test_indicator_1), indicators_list.end()); + + + indicators.RemoveIndicator("indicator-test-3"); + ASSERT_THAT(indicators.GetIndicator("indicator-test-3"), IsNull()); + + EXPECT_TRUE(added_list.empty()); + EXPECT_NE(std::find(removed_list.begin(), removed_list.end(), test_indicator_3), removed_list.end()); + EXPECT_EQ(removed_list.size(), 3); + + indicators_list = indicators.GetIndicators(); + EXPECT_TRUE(indicators_list.empty()); + + + indicators.RemoveIndicator("invalid-indicator-test-4"); + EXPECT_EQ(removed_list.size(), 3); +} + +TEST(TestIndicators, ActivateEntry) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + // Activating Entries from the Indicators class to see if they get updated + TargetData target; + + sigc::connection activated_conn = + indicators.on_entry_activated.connect([&] (std::string const& e, nux::Rect const& g) { + target.entry = e; + target.geo = g; + }); + + ASSERT_THAT(indicators.GetIndicator("indicator-test-1"), NotNull()); + + Entry::Ptr entry12(indicators.GetIndicator("indicator-test-1")->GetEntry("indicator-test-1|entry-2")); + ASSERT_THAT(entry12, NotNull()); + + ASSERT_THAT(entry12->active(), false); + ASSERT_THAT(entry12->geometry(), nux::Rect()); + + target.Reset(); + indicators.ActivateEntry("indicator-test-1|entry-2", nux::Rect(1, 2, 3, 4)); + + EXPECT_EQ(entry12->active(), true); + EXPECT_EQ(entry12->geometry(), nux::Rect(1, 2, 3, 4)); + EXPECT_EQ(target.entry, entry12->id()); + EXPECT_EQ(target.geo, entry12->geometry()); + + activated_conn.disconnect(); +} + +TEST(TestIndicators, ActivateEntryShouldDisactivatePrevious) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + // Activating Entries from the Indicators class to see if they get updated + TargetData target; + + sigc::connection activated_conn = + indicators.on_entry_activated.connect([&] (std::string const& e, nux::Rect const& g) { + target.entry = e; + target.geo = g; + }); + + ASSERT_THAT(indicators.GetIndicator("indicator-test-2"), NotNull()); + + Entry::Ptr entry22(indicators.GetIndicator("indicator-test-2")->GetEntry("indicator-test-2|entry-2")); + ASSERT_THAT(entry22, NotNull()); + + ASSERT_THAT(entry22->active(), false); + ASSERT_THAT(entry22->geometry(), nux::Rect()); + + indicators.ActivateEntry("indicator-test-2|entry-2", nux::Rect(1, 2, 3, 4)); + + ASSERT_THAT(entry22->active(), true); + ASSERT_THAT(entry22->geometry(), nux::Rect(1, 2, 3, 4)); + + + // Activating another entry, the previously selected one should be disactivate + Entry::Ptr entry21(indicators.GetIndicator("indicator-test-2")->GetEntry("indicator-test-2|entry-1")); + ASSERT_THAT(entry21, NotNull()); + + ASSERT_THAT(entry21->active(), false); + ASSERT_THAT(entry21->geometry(), nux::Rect()); + + target.Reset(); + indicators.ActivateEntry("indicator-test-2|entry-1", nux::Rect(4, 3, 2, 1)); + + EXPECT_EQ(entry22->active(), false); + EXPECT_EQ(entry22->geometry(), nux::Rect()); + + EXPECT_EQ(entry21->active(), true); + EXPECT_EQ(entry21->geometry(), nux::Rect(4, 3, 2, 1)); + EXPECT_EQ(target.entry, entry21->id()); + EXPECT_EQ(target.geo, entry21->geometry()); + + activated_conn.disconnect(); +} + +TEST(TestIndicators, ActivateEntryInvalidEmitsNullSignal) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + TargetData target; + bool signal_received = false; + + sigc::connection activated_conn = + indicators.on_entry_activated.connect([&] (std::string const& e, nux::Rect const& g) { + signal_received = true; + target.entry = e; + target.geo = g; + }); + + ASSERT_THAT(indicators.GetIndicator("indicator-test-1"), NotNull()); + + Entry::Ptr entry13(indicators.GetIndicator("indicator-test-1")->GetEntry("indicator-test-1|entry-3")); + ASSERT_THAT(entry13, NotNull()); + + ASSERT_THAT(entry13->active(), false); + ASSERT_THAT(entry13->geometry(), nux::Rect()); + + indicators.ActivateEntry("indicator-test-1|entry-3", nux::Rect(4, 2, 3, 4)); + + ASSERT_THAT(entry13->active(), true); + ASSERT_THAT(entry13->geometry(), nux::Rect(4, 2, 3, 4)); + ASSERT_TRUE(signal_received); + + + // Activating invalid entry, the previously selected one should be disactivate + target.Reset(); + signal_received = false; + indicators.ActivateEntry("indicator-entry-invalid", nux::Rect(5, 5, 5, 5)); + EXPECT_TRUE(target.entry.empty()); + EXPECT_EQ(target.geo, nux::Rect()); + EXPECT_TRUE(signal_received); + + EXPECT_EQ(entry13->active(), false); + EXPECT_EQ(entry13->geometry(), nux::Rect()); + + activated_conn.disconnect(); +} + +TEST(TestIndicators, SetEntryShowNow) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + TargetData target; + + sigc::connection activated_conn = + indicators.on_entry_activated.connect([&] (std::string const& e, nux::Rect const& g) { + target.entry = e; + target.geo = g; + }); + + ASSERT_THAT(indicators.GetIndicator("indicator-test-2"), NotNull()); + + Entry::Ptr entry22(indicators.GetIndicator("indicator-test-2")->GetEntry("indicator-test-2|entry-2")); + + ASSERT_THAT(entry22, NotNull()); + ASSERT_THAT(entry22->show_now(), false); + + indicators.SetEntryShowNow("indicator-test-2|entry-2", true); + EXPECT_EQ(entry22->show_now(), true); + + indicators.SetEntryShowNow("indicator-test-2|entry-2", false); + EXPECT_EQ(entry22->show_now(), false); +} + +TEST(TestIndicators, EntryShowMenu) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + // See if the indicators class get notified on entries actions + ASSERT_THAT(indicators.GetIndicator("indicator-test-1"), NotNull()); + + Entry::Ptr entry13(indicators.GetIndicator("indicator-test-1")->GetEntry("indicator-test-1|entry-3")); + ASSERT_THAT(entry13, NotNull()); + + TargetData show_menu_data; + sigc::connection on_entry_show_menu_conn = + indicators.on_entry_show_menu.connect([&] (std::string const& e, unsigned int w, + int x, int y, unsigned int b, unsigned int t) { + show_menu_data.entry = e; + show_menu_data.xid = w; + show_menu_data.x = x; + show_menu_data.y = y; + show_menu_data.button = b; + show_menu_data.timestamp = t; + }); + + entry13->ShowMenu(465789, 35, 53, 2, 1331773412); + + EXPECT_EQ(indicators.target.entry, entry13->id()); + EXPECT_EQ(indicators.target.xid, 465789); + EXPECT_EQ(indicators.target.x, 35); + EXPECT_EQ(indicators.target.y, 53); + EXPECT_EQ(indicators.target.button, 2); + EXPECT_EQ(indicators.target.timestamp, 1331773412); + + EXPECT_EQ(show_menu_data.entry, entry13->id()); + EXPECT_EQ(show_menu_data.xid, 465789); + EXPECT_EQ(show_menu_data.x, 35); + EXPECT_EQ(show_menu_data.y, 53); + EXPECT_EQ(show_menu_data.button, 2); + EXPECT_EQ(show_menu_data.timestamp, 1331773412); + + show_menu_data.Reset(); + indicators.target.Reset(); + + entry13->ShowMenu(55, 68, 3, 1331773883); + + EXPECT_EQ(indicators.target.entry, entry13->id()); + EXPECT_EQ(indicators.target.xid, 0); + EXPECT_EQ(indicators.target.x, 55); + EXPECT_EQ(indicators.target.y, 68); + EXPECT_EQ(indicators.target.button, 3); + EXPECT_EQ(indicators.target.timestamp, 1331773883); + + EXPECT_EQ(show_menu_data.entry, entry13->id()); + EXPECT_EQ(show_menu_data.xid, 0); + EXPECT_EQ(show_menu_data.x, 55); + EXPECT_EQ(show_menu_data.y, 68); + EXPECT_EQ(show_menu_data.button, 3); + EXPECT_EQ(show_menu_data.timestamp, 1331773883); + + on_entry_show_menu_conn.disconnect(); +} + +TEST(TestIndicators, EntryScroll) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + // See if the indicators class get notified on entries actions + ASSERT_THAT(indicators.GetIndicator("indicator-test-1"), NotNull()); + + Entry::Ptr entry11(indicators.GetIndicator("indicator-test-1")->GetEntry("indicator-test-1|entry-1")); + ASSERT_THAT(entry11, NotNull()); + + entry11->Scroll(80); + EXPECT_EQ(indicators.target.entry, entry11->id()); + EXPECT_EQ(indicators.target.delta, 80); + + entry11->SecondaryActivate(1331774167); + EXPECT_EQ(indicators.target.entry, entry11->id()); + EXPECT_EQ(indicators.target.timestamp, 1331774167); +} + +TEST(TestIndicators, EntrySecondaryActivate) +{ + MockIndicators indicators; + indicators.SetupTestChildren(); + + // See if the indicators class get notified on entries actions + ASSERT_THAT(indicators.GetIndicator("indicator-test-2"), NotNull()); + + Entry::Ptr entry22(indicators.GetIndicator("indicator-test-2")->GetEntry("indicator-test-2|entry-1")); + ASSERT_THAT(entry22, NotNull()); + + entry22->SecondaryActivate(1331774167); + EXPECT_EQ(indicators.target.entry, entry22->id()); + EXPECT_EQ(indicators.target.timestamp, 1331774167); +} + +TEST(TestIndicators, ShowAppMenu) +{ + MockIndicators indicators; + + { + Indicator::Ptr appmenu_indicator = indicators.AddIndicator("libappmenu.so"); + ASSERT_TRUE(appmenu_indicator->IsAppmenu()); + } + + ASSERT_EQ(indicators.GetIndicators().size(), 1); + + { + Indicator::Ptr indicator = indicators.GetIndicator("libappmenu.so"); + ASSERT_THAT(indicator, NotNull()); + auto appmenu_indicator = dynamic_cast(indicator.get()); + ASSERT_THAT(appmenu_indicator, NotNull()); + + indicators.target.Reset(); + + appmenu_indicator->ShowAppmenu(4356789, 54, 13, 1331774961); + + EXPECT_TRUE(indicators.target.entry.empty()); + EXPECT_EQ(indicators.target.xid, 4356789); + EXPECT_EQ(indicators.target.x, 54); + EXPECT_EQ(indicators.target.y, 13); + EXPECT_EQ(indicators.target.button, 0); + EXPECT_EQ(indicators.target.timestamp, 1331774961); + } +} + +} diff -Nru unity-5.6.0/tests/test_lensview_impl.cpp unity-5.8.0/tests/test_lensview_impl.cpp --- unity-5.6.0/tests/test_lensview_impl.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_lensview_impl.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Andrea Azzarone + */ + +#include +#include + +#include + +#include "LensViewPrivate.h" +#include "AbstractPlacesGroup.h" + +using namespace unity; +using namespace testing; + +namespace +{ + +const int NUM_GROUPS = 4; + +class TestPlacesGroupImpl : public Test +{ +public: + TestPlacesGroupImpl() + { + for (int i=0; i GetList() + { + std::list ret; + std::copy(groups_vector.begin(), groups_vector.end(), std::back_inserter(ret)); + return ret; + } + + std::vector groups_vector; +}; + + +TEST_F(TestPlacesGroupImpl, TestUpdateDrawSeparatorsEmpty) +{ + std::list groups; + + // Just to make sure it doesn't crash. + dash::impl::UpdateDrawSeparators(groups); +} + +TEST_F(TestPlacesGroupImpl, TestUpdateDrawSeparatorsAllVisible) +{ + groups_vector[0]->SetVisible(true); + groups_vector[1]->SetVisible(true); + groups_vector[2]->SetVisible(true); + groups_vector[3]->SetVisible(true); + + dash::impl::UpdateDrawSeparators(GetList()); + + EXPECT_TRUE(groups_vector[0]->draw_separator); + EXPECT_TRUE(groups_vector[1]->draw_separator); + EXPECT_TRUE(groups_vector[2]->draw_separator); + EXPECT_FALSE(groups_vector[3]->draw_separator); +} + +TEST_F(TestPlacesGroupImpl, TestUpdateDrawSeparatorsLastInvisible) +{ + groups_vector[0]->SetVisible(true); + groups_vector[1]->SetVisible(true); + groups_vector[2]->SetVisible(true); + groups_vector[3]->SetVisible(false); + + dash::impl::UpdateDrawSeparators(GetList()); + + EXPECT_TRUE(groups_vector[0]->draw_separator); + EXPECT_TRUE(groups_vector[1]->draw_separator); + EXPECT_FALSE(groups_vector[2]->draw_separator); +} + +TEST_F(TestPlacesGroupImpl, TestUpdateDrawSeparatorsLastTwoInvisible) +{ + groups_vector[0]->SetVisible(true); + groups_vector[1]->SetVisible(true); + groups_vector[2]->SetVisible(false); + groups_vector[3]->SetVisible(false); + + dash::impl::UpdateDrawSeparators(GetList()); + + EXPECT_TRUE(groups_vector[0]->draw_separator); + EXPECT_FALSE(groups_vector[1]->draw_separator); +} + +TEST_F(TestPlacesGroupImpl, TestUpdateDrawSeparators) +{ + groups_vector[0]->SetVisible(true); + groups_vector[1]->SetVisible(false); + groups_vector[2]->SetVisible(false); + groups_vector[3]->SetVisible(true); + + dash::impl::UpdateDrawSeparators(GetList()); + + EXPECT_TRUE(groups_vector[0]->draw_separator); + EXPECT_FALSE(groups_vector[3]->draw_separator); +} + +} + diff -Nru unity-5.6.0/tests/test_main_dbus.cpp unity-5.8.0/tests/test_main_dbus.cpp --- unity-5.6.0/tests/test_main_dbus.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_main_dbus.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -59,7 +59,7 @@ NULL, &have_name, NULL); - g_timeout_add_seconds(10, timeout_cb, &timeout_reached); + g_timeout_add(10000, timeout_cb, &timeout_reached); while (!have_name && !timeout_reached) g_main_context_iteration(g_main_context_get_thread_default(), TRUE); diff -Nru unity-5.6.0/tests/TestPlacesResults.cpp unity-5.8.0/tests/TestPlacesResults.cpp --- unity-5.6.0/tests/TestPlacesResults.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/TestPlacesResults.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -119,7 +119,7 @@ nux::GetGraphicsThread()->SetLayout(layout); #endif - g_timeout_add_seconds(2, (GSourceFunc)remove_timeout, NULL); + g_timeout_add(2000, (GSourceFunc)remove_timeout, NULL); } void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) diff -Nru unity-5.6.0/tests/test_service_hud.c unity-5.8.0/tests/test_service_hud.c --- unity-5.6.0/tests/test_service_hud.c 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_service_hud.c 2012-03-23 11:53:16.000000000 +0000 @@ -51,6 +51,10 @@ GDBusMethodInvocation *invocation, gpointer user_data); +static gboolean do_emit_signal(gpointer data); +static void emit_signal(GDBusConnection *connection); + + G_DEFINE_TYPE(ServiceHud, service_hud, G_TYPE_OBJECT); static GDBusNodeInfo * node_info = NULL; static GDBusInterfaceInfo * iface_info = NULL; @@ -60,12 +64,12 @@ set_property: NULL, }; - struct _ServiceHudPrivate { GDBusConnection * bus; GCancellable * bus_lookup; guint bus_registration; + guint sig_emission_handle; }; static void @@ -88,6 +92,11 @@ self->priv->bus = NULL; } + if (self->priv->sig_emission_handle) { + g_source_remove(self->priv->sig_emission_handle); + self->priv->sig_emission_handle = 0; + } + } static void @@ -129,7 +138,6 @@ self->priv->bus_lookup = g_cancellable_new(); g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self); - } ServiceHud* @@ -168,10 +176,94 @@ g_error_free(error); return; } + else + { + self->priv->sig_emission_handle = g_timeout_add(1000, do_emit_signal, bus); + } return; } +static gboolean +do_emit_signal(gpointer data) +{ + emit_signal(G_DBUS_CONNECTION(data)); + return TRUE; +} + +static void +emit_signal(GDBusConnection *connection) +{ + GVariant *query; + int num_entries = 5; + + /* Build into into a variant */ + GVariantBuilder ret_builder; + g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&ret_builder, g_variant_new_string("target")); + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + + int i = 0; + for (i = 0; i < num_entries; i++) + { + gchar* target = g_strdup_printf("test-%i", i); + gchar* icon = g_strdup_printf("icon-%i", i); + gchar* future_icon = g_strdup(icon); + gchar* completion_text = g_strdup_printf("completion-%i", i); + gchar* accelerator = g_strdup_printf("+whatever"); + + GVariantBuilder tuple; + g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&tuple, g_variant_new_string(target)); + g_variant_builder_add_value(&tuple, g_variant_new_string(icon)); + g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon)); + g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text)); + g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator)); + // build a fake key + GVariant* key; + { + GVariantBuilder keybuilder; + g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986)); + + key = g_variant_new_variant(g_variant_builder_end(&keybuilder)); + } + g_variant_ref_sink(key); + g_variant_builder_add_value(&tuple, key); + g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple)); + g_free(target); + g_free(icon); + g_free(future_icon); + g_free(completion_text); + } + g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder)); + + GVariant* query_key; + { + GVariantBuilder keybuilder; + g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986)); + + query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder)); + } + g_variant_ref_sink(query_key); + g_variant_builder_add_value(&ret_builder, query_key); + + query = g_variant_builder_end(&ret_builder); + + g_dbus_connection_emit_signal (connection, NULL, "/com/canonical/hud", + "com.canonical.hud", "UpdatedQuery", + query, NULL); +} + static void bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { diff -Nru unity-5.6.0/tests/test_shortcut_private.cpp unity-5.8.0/tests/test_shortcut_private.cpp --- unity-5.6.0/tests/test_shortcut_private.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_shortcut_private.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -68,7 +68,15 @@ EXPECT_EQ(FixMouseShortcut("Super"), "Super"); EXPECT_EQ(FixMouseShortcut("Super"), "Super"); EXPECT_EQ(FixMouseShortcut("Super"), "Super"); +} +TEST(TestShortcutHintPrivate, TestGetMetaKey) +{ + EXPECT_EQ(GetMetaKey(""), ""); + EXPECT_EQ(GetMetaKey(""), ""); + EXPECT_EQ(GetMetaKey("A"), ""); + EXPECT_EQ(GetMetaKey("A"), ""); + EXPECT_EQ(GetMetaKey("ABC"), ""); } } // anonymouse namespace diff -Nru unity-5.6.0/tests/test_switcher_controller.cpp unity-5.8.0/tests/test_switcher_controller.cpp --- unity-5.6.0/tests/test_switcher_controller.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_switcher_controller.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright 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 published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with this program. If not, see + * + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + * + */ + +#include + +#include "SwitcherController.h" +#include "test_utils.h" + + +using namespace unity::switcher; + +namespace +{ + +unsigned int DEFAULT_LAZY_CONSTRUCT_TIMEOUT = 20; + +class MockSwitcherController : public Controller +{ +public: + MockSwitcherController() + : Controller() + , window_constructed_(false) + , view_constructed_(false) + , view_shown_(false) + {}; + + MockSwitcherController(unsigned int load_timeout) + : Controller(load_timeout) + , window_constructed_(false) + , view_constructed_(false) + , view_shown_(false) + {}; + + virtual void ConstructWindow() + { + window_constructed_ = true; + } + + virtual void ConstructView() + { + view_constructed_ = true; + } + + virtual void ShowView() + { + view_shown_ = true; + } + + unsigned int GetConstructTimeout() const + { + return construct_timeout_; + } + + bool window_constructed_; + bool view_constructed_; + bool view_shown_; +}; + +TEST(TestSwitcherController, Construction) +{ + Controller controller; + EXPECT_FALSE(controller.Visible()); +} + +TEST(TestSwitcherController, LazyConstructionTimeoutLength) +{ + MockSwitcherController controller; + EXPECT_EQ(controller.GetConstructTimeout(), DEFAULT_LAZY_CONSTRUCT_TIMEOUT); +} + +TEST(TestSwitcherController, LazyWindowConstruction) +{ + // Setting the timeout to a lower value to speed-up the test + MockSwitcherController controller(2); + + EXPECT_EQ(controller.GetConstructTimeout(), 2); + + g_timeout_add_seconds(controller.GetConstructTimeout()/2, [] (gpointer data) -> gboolean { + auto controller = static_cast(data); + EXPECT_FALSE(controller->window_constructed_); + + return FALSE; + }, &controller); + + Utils::WaitUntil(controller.window_constructed_, controller.GetConstructTimeout() + 1); + EXPECT_TRUE(controller.window_constructed_); +} + +} diff -Nru unity-5.6.0/tests/test_switcher_model.cpp unity-5.8.0/tests/test_switcher_model.cpp --- unity-5.6.0/tests/test_switcher_model.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/tests/test_switcher_model.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright 2011 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 published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with this program. If not, see + * + * + * Authored by: Jason Smith + * + */ + +#include + +#include "SwitcherModel.h" +#include "MockLauncherIcon.h" +#include "AbstractLauncherIcon.h" + +#include + + +using namespace unity::switcher; +using unity::launcher::AbstractLauncherIcon; +using unity::launcher::MockLauncherIcon; + +namespace +{ + +TEST(TestSwitcherModel, TestConstructor) +{ + AbstractLauncherIcon::Ptr first(new MockLauncherIcon()); + AbstractLauncherIcon::Ptr second(new MockLauncherIcon()); + std::vector icons; + icons.push_back(first); + icons.push_back(second); + + SwitcherModel::Ptr model(new SwitcherModel(icons)); + + EXPECT_EQ(model->Size(), 2); + EXPECT_EQ(model->Selection(), first); + EXPECT_EQ(model->LastSelection(), first); + EXPECT_EQ(model->SelectionIndex(), 0); + EXPECT_EQ(model->LastSelectionIndex(), 0); +} + +TEST(TestSwitcherModel, TestSelection) +{ + std::vector icons; + AbstractLauncherIcon::Ptr first(new MockLauncherIcon()); + AbstractLauncherIcon::Ptr second(new MockLauncherIcon()); + AbstractLauncherIcon::Ptr third(new MockLauncherIcon()); + AbstractLauncherIcon::Ptr fourth(new MockLauncherIcon()); + + icons.push_back(first); + icons.push_back(second); + icons.push_back(third); + icons.push_back(fourth); + + SwitcherModel::Ptr model(new SwitcherModel(icons)); + + EXPECT_EQ(model->Size(), 4); + EXPECT_EQ(model->Selection(), first); + + model->Next(); + EXPECT_EQ(model->Selection(), second); + EXPECT_EQ(model->LastSelection(), first); + model->Next(); + EXPECT_EQ(model->Selection(), third); + EXPECT_EQ(model->LastSelection(), second); + model->Next(); + EXPECT_EQ(model->Selection(), fourth); + EXPECT_EQ(model->LastSelection(), third); + model->Next(); + EXPECT_EQ(model->Selection(), first); + EXPECT_EQ(model->LastSelection(), fourth); + model->Next(); + EXPECT_EQ(model->Selection(), second); + EXPECT_EQ(model->LastSelection(), first); + model->Prev(); + EXPECT_EQ(model->Selection(), first); + EXPECT_EQ(model->LastSelection(), second); + model->Prev(); + EXPECT_EQ(model->Selection(), fourth); + EXPECT_EQ(model->LastSelection(), first); + + model->Select(2); + EXPECT_EQ(model->Selection(), third); + EXPECT_EQ(model->LastSelection(), fourth); + + model->Select(first); + EXPECT_EQ(model->Selection(), first); + EXPECT_EQ(model->LastSelection(), third); +} + +} diff -Nru unity-5.6.0/tests/test_utils.h unity-5.8.0/tests/test_utils.h --- unity-5.6.0/tests/test_utils.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/test_utils.h 2012-03-23 11:53:16.000000000 +0000 @@ -22,7 +22,7 @@ return FALSE; }; - guint32 timeout_id = g_timeout_add_seconds(10, timeout_cb, &timeout_reached); + guint32 timeout_id = g_timeout_add(10000, timeout_cb, &timeout_reached); while (model.count != n_rows && !timeout_reached) { @@ -48,7 +48,7 @@ static guint32 ScheduleTimeout(bool* timeout_reached, unsigned int timeout_duration = 10) { - return g_timeout_add_seconds(timeout_duration, TimeoutCallback, timeout_reached); + return g_timeout_add(timeout_duration*1000, TimeoutCallback, timeout_reached); } static guint32 ScheduleTimeoutMSec(bool* timeout_reached, unsigned int timeout_duration = 10) diff -Nru unity-5.6.0/tests/unit/TestMain.cpp unity-5.8.0/tests/unit/TestMain.cpp --- unity-5.6.0/tests/unit/TestMain.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/unit/TestMain.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -25,9 +25,9 @@ #include "Nux/Nux.h" #include "Nux/WindowThread.h" -//void TestPanelServiceCreateSuite (void); -void TestUBusCreateSuite(void); -void TestQuicklistMenuitemsCreateSuite(void); +void TestPanelServiceCreateSuite(); +void TestUBusCreateSuite(); +void TestQuicklistMenuitemsCreateSuite(); void TestStaticCairoTextCreateSuite(); nux::WindowThread* @@ -70,7 +70,7 @@ g_test_init(&argc, &argv, NULL); //Keep alphabetical please - //TestPanelServiceCreateSuite (); + TestPanelServiceCreateSuite(); TestQuicklistMenuitemsCreateSuite(); TestStaticCairoTextCreateSuite(); TestUBusCreateSuite(); diff -Nru unity-5.6.0/tests/unit/TestPanelService.cpp unity-5.8.0/tests/unit/TestPanelService.cpp --- unity-5.6.0/tests/unit/TestPanelService.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/unit/TestPanelService.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -177,6 +177,7 @@ GVariantIter* iter; gchar* indicator_id; gchar* entry_id; + gchar* entry_name_hint; gchar* label; gboolean label_sensitive; gboolean label_visible; @@ -185,10 +186,11 @@ gboolean image_sensitive; gboolean image_visible; - g_variant_get(result, "(a(sssbbusbb))", &iter); - while (g_variant_iter_loop(iter, "(sssbbusbb)", + g_variant_get(result, "(a(ssssbbusbbi))", &iter); + while (g_variant_iter_loop(iter, "(ssssbbusbbi)", &indicator_id, &entry_id, + &entry_name_hint, &label, &label_sensitive, &label_visible, @@ -215,8 +217,8 @@ guint ret = 0; GVariantIter* iter; gchar* indicator_id; - gchar* name_hint; gchar* entry_id; + gchar* entry_name_hint; gchar* label; gboolean label_sensitive; gboolean label_visible; @@ -229,8 +231,8 @@ g_variant_get(result, "(a(ssssbbusbbi))", &iter); while (g_variant_iter_loop(iter, "(ssssbbusbbi)", &indicator_id, - &name_hint, &entry_id, + &entry_name_hint, &label, &label_sensitive, &label_visible, diff -Nru unity-5.6.0/tests/unit/TestSwitcherModel.cpp unity-5.8.0/tests/unit/TestSwitcherModel.cpp --- unity-5.6.0/tests/unit/TestSwitcherModel.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tests/unit/TestSwitcherModel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright 2011 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 published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 3 along with this program. If not, see - * - * - * Authored by: Jason Smith - * - */ - -#include - -#include "SwitcherModel.h" -#include "MockLauncherIcon.h" - -#include - - -using namespace unity::switcher; - -namespace -{ - -TEST(TestSwitcher, TestConstructor) -{ - AbstractLauncherIcon* first = new MockLauncherIcon(); - AbstractLauncherIcon* second = new MockLauncherIcon(); - std::vector icons; - icons.push_back(first); - icons.push_back(second); - - SwitcherModel::Ptr model(new SwitcherModel(icons)); - - EXPECT_EQ(model->Size(), 2); - EXPECT_EQ(model->Selection(), first); - EXPECT_EQ(model->LastSelection(), first); - EXPECT_EQ(model->SelectionIndex(), 0); - EXPECT_EQ(model->LastSelectionIndex(), 0); - - delete first; - delete second; -} - -TEST(TestSwitcher, TestSelection) -{ - std::vector icons; - AbstractLauncherIcon* first = new MockLauncherIcon(); - AbstractLauncherIcon* second = new MockLauncherIcon(); - AbstractLauncherIcon* third = new MockLauncherIcon(); - AbstractLauncherIcon* fourth = new MockLauncherIcon(); - - icons.push_back(first); - icons.push_back(second); - icons.push_back(third); - icons.push_back(fourth); - - SwitcherModel::Ptr model(new SwitcherModel(icons)); - - EXPECT_EQ(model->Size(), 4); - EXPECT_EQ(model->Selection(), first); - - model->Next(); - EXPECT_EQ(model->Selection(), second); - EXPECT_EQ(model->LastSelection(), first); - model->Next(); - EXPECT_EQ(model->Selection(), third); - EXPECT_EQ(model->LastSelection(), second); - model->Next(); - EXPECT_EQ(model->Selection(), fourth); - EXPECT_EQ(model->LastSelection(), third); - model->Next(); - EXPECT_EQ(model->Selection(), first); - EXPECT_EQ(model->LastSelection(), fourth); - model->Next(); - EXPECT_EQ(model->Selection(), second); - EXPECT_EQ(model->LastSelection(), first); - model->Prev(); - EXPECT_EQ(model->Selection(), first); - EXPECT_EQ(model->LastSelection(), second); - model->Prev(); - EXPECT_EQ(model->Selection(), fourth); - EXPECT_EQ(model->LastSelection(), first); - - model->Select(2); - EXPECT_EQ(model->Selection(), third); - EXPECT_EQ(model->LastSelection(), fourth); - - model->Select(first); - EXPECT_EQ(model->Selection(), first); - EXPECT_EQ(model->LastSelection(), third); - - delete first; - delete second; - delete third; - delete fourth; -} - -} diff -Nru unity-5.6.0/tools/unity-introspection-visualiser.py unity-5.8.0/tools/unity-introspection-visualiser.py --- unity-5.6.0/tools/unity-introspection-visualiser.py 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/tools/unity-introspection-visualiser.py 2012-03-23 11:53:16.000000000 +0000 @@ -50,7 +50,7 @@ global NEXT_NODE_ID lbl = parent.get_comment() + "|" # first, set labels for this node: - bits = ["%s=%s" % (k, string_rep(state[k])) for k in state.keys() if k != 'Children'] + bits = ["%s=%s" % (k, string_rep(state[k])) for k in sorted(state.keys()) if k != 'Children'] lbl += "\l".join(bits) parent.set_label(escape('"{' + lbl + '}"')) if state.has_key('Children'): diff -Nru unity-5.6.0/UnityCore/AppmenuIndicator.cpp unity-5.8.0/UnityCore/AppmenuIndicator.cpp --- unity-5.6.0/UnityCore/AppmenuIndicator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/UnityCore/AppmenuIndicator.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,37 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + */ + +#include "AppmenuIndicator.h" + +namespace unity +{ +namespace indicator +{ + +AppmenuIndicator::AppmenuIndicator(std::string const& name) + : Indicator(name) +{} + +void AppmenuIndicator::ShowAppmenu(unsigned int xid, int x, int y, unsigned int timestamp) const +{ + on_show_appmenu.emit(xid, x, y, timestamp); +} + +} // namespace indicator +} // namespace unity diff -Nru unity-5.6.0/UnityCore/AppmenuIndicator.h unity-5.8.0/UnityCore/AppmenuIndicator.h --- unity-5.6.0/UnityCore/AppmenuIndicator.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.8.0/UnityCore/AppmenuIndicator.h 2012-03-23 11:53:16.000000000 +0000 @@ -0,0 +1,45 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> + */ + +#ifndef UNITY_APPMENU_INDICATOR_H +#define UNITY_APPMENU_INDICATOR_H + +#include "Indicator.h" + +namespace unity +{ +namespace indicator +{ + +class AppmenuIndicator : public Indicator +{ +public: + AppmenuIndicator(std::string const& name); + + virtual bool IsAppmenu() const { return true; } + + void ShowAppmenu(unsigned int xid, int x, int y, unsigned int timestamp) const; + + sigc::signal on_show_appmenu; +}; + +} +} + +#endif // UNITY_APPMENU_INDICATOR_H diff -Nru unity-5.6.0/UnityCore/CMakeLists.txt unity-5.8.0/UnityCore/CMakeLists.txt --- unity-5.6.0/UnityCore/CMakeLists.txt 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 @@ -8,6 +8,7 @@ # set (CORE_HEADERS ApplicationPreview.h + AppmenuIndicator.h Categories.h Category.h CheckOptionFilter.h @@ -44,6 +45,7 @@ set (CORE_SOURCES ApplicationPreview.cpp + AppmenuIndicator.cpp Categories.cpp Category.cpp CheckOptionFilter.cpp diff -Nru unity-5.6.0/UnityCore/DBusIndicators.cpp unity-5.8.0/UnityCore/DBusIndicators.cpp --- unity-5.6.0/UnityCore/DBusIndicators.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/DBusIndicators.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2010, 2011 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 @@ -18,18 +18,11 @@ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ +#include "config.h" #include "DBusIndicators.h" -#include -#include - -#include - -#include - -#include "config.h" -#include "GLibSignal.h" #include "GLibWrapper.h" +#include "GLibDBusProxy.h" #include "Variant.h" namespace unity @@ -39,103 +32,54 @@ namespace { -// This anonymous namespace holds the DBus callback methods. - -struct SyncData -{ - SyncData(DBusIndicators::Impl* self_) - : self(self_) - , cancel(g_cancellable_new()) - { - } - - ~SyncData() - { - if (cancel) - { - g_cancellable_cancel(cancel); - g_object_unref(cancel); - } - } - - void SyncComplete() - { - if (cancel) - { - g_object_unref(cancel); - } - cancel = NULL; - } - - DBusIndicators::Impl* self; - GCancellable* cancel; -}; - -typedef boost::shared_ptr SyncDataPtr; - -const char* const S_NAME = "com.canonical.Unity.Panel.Service"; -const char* const S_PATH = "/com/canonical/Unity/Panel/Service"; -const char* const S_IFACE = "com.canonical.Unity.Panel.Service"; - -struct ShowEntryData -{ - GDBusProxy* proxy; - std::string entry_id; - int x; - int y; - guint timestamp; - guint32 button; -}; - -bool run_local_panel_service(); -gboolean reconnect_to_service(gpointer data); -void on_proxy_ready_cb(GObject* source, GAsyncResult* res, gpointer data); -void request_sync(GDBusProxy* proxy, const char* method, GVariant* name, - SyncData* data); -void on_sync_ready_cb(GObject* source, GAsyncResult* res, gpointer data); - -bool send_show_entry(ShowEntryData* data); - +const std::string SERVICE_NAME("com.canonical.Unity.Panel.Service"); +const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service"); +const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service"); } // anonymous namespace -// Connects to the remote panel service (unity-panel-service) and translates -// that into something that the panel can show +/* Connects to the remote panel service (unity-panel-service) and translates + * that into something that the panel can show */ class DBusIndicators::Impl { public: Impl(DBusIndicators* owner); ~Impl(); - void OnRemoteProxyReady(GDBusProxy* proxy); - void Reconnect(); + void CheckLocalService(); void RequestSyncAll(); void RequestSyncIndicator(std::string const& name); - void Sync(GVariant* args, SyncData* data); - void SyncGeometries(std::string const& name, - EntryLocationMap const& locations); - void OnProxyNameOwnerChanged(GDBusProxy* proxy, GParamSpec* pspec); - void OnProxySignalReceived(GDBusProxy* proxy, - char* sender_name, - char* signal_name_, - GVariant* parameters); + void Sync(GVariant* args); + void SyncGeometries(std::string const& name, EntryLocationMap const& locations); + + void OnConnected(); + void OnDisconnected(); + + void OnReSync(GVariant* parameters); + void OnEntryActivated(GVariant* parameters); + void OnEntryActivatedRequest(GVariant* parameters); + void OnEntryShowNowChanged(GVariant* parameters); virtual void OnEntryScroll(std::string const& entry_id, int delta); - virtual void OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button); + virtual void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp); virtual void OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp); + virtual void OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp); - std::string name() const; - std::string owner_name() const; - bool using_local_service() const; + struct CallData + { + Impl* self; + glib::Variant parameters; + }; DBusIndicators* owner_; - GDBusProxy* proxy_; - typedef std::vector PendingSyncs; - PendingSyncs pending_syncs_; - - glib::SignalManager signal_manager_; + guint reconnect_timeout_id_; + guint show_entry_idle_id_; + guint show_appmenu_idle_id_; + glib::DBusProxy gproxy_; std::map cached_locations_; }; @@ -143,120 +87,223 @@ // Public Methods DBusIndicators::Impl::Impl(DBusIndicators* owner) : owner_(owner) - , proxy_(NULL) -{ - Reconnect(); + , reconnect_timeout_id_(0) + , show_entry_idle_id_(0) + , show_appmenu_idle_id_(0) + , gproxy_(SERVICE_NAME, SERVICE_PATH, SERVICE_IFACE, + G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) +{ + gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync)); + gproxy_.Connect("EntryActivated", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryActivated)); + gproxy_.Connect("EntryActivateRequest", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryActivatedRequest)); + gproxy_.Connect("EntryShowNowChanged", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryShowNowChanged)); + + gproxy_.connected.connect(sigc::mem_fun(this, &DBusIndicators::Impl::OnConnected)); + gproxy_.disconnected.connect(sigc::mem_fun(this, &DBusIndicators::Impl::OnDisconnected)); + + CheckLocalService(); } DBusIndicators::Impl::~Impl() { - if (G_IS_OBJECT(proxy_)) - { - g_object_unref(proxy_); - } + if (reconnect_timeout_id_) + g_source_remove(reconnect_timeout_id_); + + if (show_entry_idle_id_) + g_source_remove(show_entry_idle_id_); + + if (show_appmenu_idle_id_) + g_source_remove(show_appmenu_idle_id_); } -void DBusIndicators::Impl::Reconnect() +void DBusIndicators::Impl::CheckLocalService() { - g_spawn_command_line_sync("killall -9 unity-panel-service", - NULL, NULL, NULL, NULL); - if (g_getenv("PANEL_USE_LOCAL_SERVICE")) { - run_local_panel_service(); - g_timeout_add_seconds(1, reconnect_to_service, this); + glib::Error error; + + g_spawn_command_line_sync("killall -9 unity-panel-service", + nullptr, nullptr, nullptr, nullptr); + + // This is obviously hackish, but this part of the code is mostly hackish... + // Let's attempt to run it from where we expect it to be + std::string cmd = PREFIXDIR + std::string("/lib/unity/unity-panel-service"); + std::cerr << "\nWARNING: Couldn't load panel from installed services, " + << "so trying to load panel from known location: " + << cmd << "\n"; + + g_spawn_command_line_async(cmd.c_str(), &error); + + if (error) + { + std::cerr << "\nWARNING: Unable to launch remote service manually: " + << error.Message() << "\n"; + } } - else +} + +void DBusIndicators::Impl::OnConnected() +{ + RequestSyncAll(); +} + +void DBusIndicators::Impl::OnDisconnected() +{ + for (auto indicator : owner_->GetIndicators()) { - // We want to grab the Panel Service object. This is async, which is fine - reconnect_to_service(this); + owner_->RemoveIndicator(indicator->name()); } + + cached_locations_.clear(); + + CheckLocalService(); + RequestSyncAll(); + + if (reconnect_timeout_id_) + g_source_remove(reconnect_timeout_id_); + + reconnect_timeout_id_ = g_timeout_add_seconds(1, [](gpointer data) -> gboolean { + auto self = static_cast(data); + + if (!self->gproxy_.IsConnected()) + { + self->RequestSyncAll(); + return TRUE; + } + + self->reconnect_timeout_id_ = 0; + return FALSE; + }, this); } -void DBusIndicators::Impl::OnRemoteProxyReady(GDBusProxy* proxy) +void DBusIndicators::Impl::OnReSync(GVariant* parameters) { - if (proxy_) + glib::String indicator_name; + g_variant_get(parameters, "(s)", &indicator_name); + + if (indicator_name && !indicator_name.Str().empty()) { - // We've been connected before; We don't need new proxy, just continue - // rocking with the old one. - g_object_unref(proxy); + RequestSyncIndicator(indicator_name); } else { - proxy_ = proxy; - // Connect to interesting signals - signal_manager_.Add(new glib::Signal - (proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignalReceived))); - - signal_manager_.Add(new glib::Signal - (proxy_, "notify::g-name-owner", sigc::mem_fun(this, &Impl::OnProxyNameOwnerChanged))); + RequestSyncAll(); } - RequestSyncAll(); +} + +void DBusIndicators::Impl::OnEntryActivated(GVariant* parameters) +{ + glib::String entry_name; + nux::Rect geo; + g_variant_get(parameters, "(s(iiuu))", &entry_name, &geo.x, &geo.y, &geo.width, &geo.height); + + if (entry_name) + owner_->ActivateEntry(entry_name, geo); +} + +void DBusIndicators::Impl::OnEntryActivatedRequest(GVariant* parameters) +{ + glib::String entry_name; + g_variant_get(parameters, "(s)", &entry_name); + + if (entry_name) + owner_->on_entry_activate_request.emit(entry_name); +} + +void DBusIndicators::Impl::OnEntryShowNowChanged(GVariant* parameters) +{ + glib::String entry_name; + gboolean show_now; + g_variant_get(parameters, "(sb)", &entry_name, &show_now); + + if (entry_name) + owner_->SetEntryShowNow(entry_name, show_now); } void DBusIndicators::Impl::RequestSyncAll() { - SyncDataPtr data(new SyncData(this)); - pending_syncs_.push_back(data); - request_sync(proxy_, "Sync", NULL, data.get()); + gproxy_.Call("Sync", nullptr, sigc::mem_fun(this, &DBusIndicators::Impl::Sync)); } void DBusIndicators::Impl::RequestSyncIndicator(std::string const& name) { - SyncDataPtr data(new SyncData(this)); - pending_syncs_.push_back(data); - // The ownership of this variant is taken by the g_dbus_proxy_call. - GVariant* v_name = g_variant_new("(s)", name.c_str()); - request_sync(proxy_, "SyncOne", v_name, data.get()); + GVariant* parameter = g_variant_new("(s)", name.c_str()); + + gproxy_.Call("SyncOne", parameter, sigc::mem_fun(this, &DBusIndicators::Impl::Sync)); } void DBusIndicators::Impl::OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button) + unsigned int xid, int x, int y, + unsigned int button, + unsigned int timestamp) { - owner_->on_entry_show_menu.emit(entry_id, x, y, timestamp, button); + owner_->on_entry_show_menu.emit(entry_id, xid, x, y, button, timestamp); // We have to do this because on certain systems X won't have time to // respond to our request for XUngrabPointer and this will cause the // menu not to show - ShowEntryData* data = new ShowEntryData(); - data->proxy = proxy_; - data->entry_id = entry_id; - data->x = x; - data->y = y; - data->timestamp = timestamp; - data->button = button; + auto data = new CallData(); + data->self = this; + data->parameters = g_variant_new("(suiiuu)", entry_id.c_str(), xid, x, y, + button, timestamp); - g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc)send_show_entry, data, NULL); + if (show_entry_idle_id_) + g_source_remove(show_entry_idle_id_); + + show_entry_idle_id_ = g_idle_add_full (G_PRIORITY_DEFAULT, [] (gpointer data) -> gboolean { + auto call_data = static_cast(data); + call_data->self->gproxy_.Call("ShowEntry", call_data->parameters); + + return FALSE; + }, data, [] (gpointer data) { delete static_cast(data); }); +} + +void DBusIndicators::Impl::OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp) +{ + owner_->on_show_appmenu.emit(xid, x, y, timestamp); + + // We have to do this because on certain systems X won't have time to + // respond to our request for XUngrabPointer and this will cause the + // menu not to show + auto data = new CallData(); + data->self = this; + data->parameters = g_variant_new("(uiiu)", xid, x, y, timestamp); + + if (show_appmenu_idle_id_) + g_source_remove(show_appmenu_idle_id_); + + show_appmenu_idle_id_ = g_idle_add_full (G_PRIORITY_DEFAULT, [] (gpointer data) -> gboolean { + auto call_data = static_cast(data); + call_data->self->gproxy_.Call("ShowAppMenu", call_data->parameters); + + return FALSE; + }, data, [] (gpointer data) { delete static_cast(data); }); } void DBusIndicators::Impl::OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp) { - g_dbus_proxy_call(proxy_, "SecondaryActivateEntry", - g_variant_new("(su)", entry_id.c_str(), timestamp), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + gproxy_.Call("SecondaryActivateEntry", g_variant_new("(su)", entry_id.c_str(), timestamp)); } void DBusIndicators::Impl::OnEntryScroll(std::string const& entry_id, int delta) { - g_dbus_proxy_call(proxy_, "ScrollEntry", - g_variant_new("(si)", entry_id.c_str(), delta), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, NULL, NULL); + gproxy_.Call("ScrollEntry", g_variant_new("(si)", entry_id.c_str(), delta)); } -void DBusIndicators::Impl::Sync(GVariant* args, SyncData* data) -{ - GVariantIter* iter = NULL; - gchar* name_hint = NULL; - gchar* indicator_id = NULL; - gchar* entry_id = NULL; - gchar* label = NULL; +void DBusIndicators::Impl::Sync(GVariant* args) +{ + GVariantIter* iter = nullptr; + gchar* name_hint = nullptr; + gchar* indicator_id = nullptr; + gchar* entry_id = nullptr; + gchar* label = nullptr; gboolean label_sensitive = false; gboolean label_visible = false; guint32 image_type = 0; - gchar* image_data = NULL; + gchar* image_data = nullptr; gboolean image_sensitive = false; gboolean image_visible = false; gint32 priority = -1; @@ -292,7 +339,7 @@ Indicator::Entries& entries = indicators[indicator]; - // NULL entries (entry_id == "") are empty indicators. + // Null entries (entry_id == "") are empty indicators. if (entry != "") { Entry::Ptr e = indicator->GetEntry(entry_id); @@ -327,20 +374,6 @@ i->first->Sync(indicators[i->first]); } - // Clean up the SyncData. NOTE: don't use find when passing in a raw - // pointer due to explicit construction of the shared pointer. Could write - // a predicate, but often a for loop is easier to understand. - data->SyncComplete(); - for (PendingSyncs::iterator i = pending_syncs_.begin(), end = pending_syncs_.end(); - i != end; ++i) - { - if (i->get() == data) - { - pending_syncs_.erase(i); - break; - } - } - // Notify listeners we have new data owner_->on_synced.emit(); } @@ -348,7 +381,7 @@ void DBusIndicators::Impl::SyncGeometries(std::string const& name, EntryLocationMap const& locations) { - if (!proxy_) + if (!gproxy_.IsConnected()) return; GVariantBuilder b; @@ -398,114 +431,17 @@ } g_variant_builder_close(&b); - g_dbus_proxy_call(proxy_, "SyncGeometries", - g_variant_builder_end(&b), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); + gproxy_.Call("SyncGeometries", g_variant_builder_end(&b)); cached_loc = locations; } -std::string DBusIndicators::Impl::name() const -{ - glib::String name; - g_object_get(proxy_, "g-name", &name, NULL); - return name.Str(); -} - -std::string DBusIndicators::Impl::owner_name() const -{ - glib::String owner_name; - g_object_get(proxy_, "g-name-owner", &owner_name, NULL); - return owner_name.Str(); -} - -bool DBusIndicators::Impl::using_local_service() const -{ - return g_getenv("PANEL_USE_LOCAL_SERVICE") != NULL; -} - -void DBusIndicators::Impl::OnProxyNameOwnerChanged(GDBusProxy* proxy, - GParamSpec* pspec) -{ - char* name_owner = g_dbus_proxy_get_name_owner(proxy); - - if (name_owner == NULL) - { - for (auto indicator : owner_->GetIndicators()) - { - owner_->RemoveIndicator(indicator->name()); - } - - // The panel service has stopped for some reason. Restart it if not in - // dev mode - if (!g_getenv("UNITY_DEV_MODE")) - Reconnect(); - } - - g_free(name_owner); -} - -void DBusIndicators::Impl::OnProxySignalReceived(GDBusProxy* proxy, - char* sender_name, - char* signal_name_, - GVariant* parameters) -{ - std::string signal_name(signal_name_); - if (signal_name == "EntryActivated") - { - const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); - if (entry_name) - { - owner_->ActivateEntry(entry_name); - } - } - else if (signal_name == "EntryActivateRequest") - { - const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); - if (entry_name) - { - owner_->on_entry_activate_request.emit(entry_name); - } - } - else if (signal_name == "ReSync") - { - const char* id = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); - bool sync_one = !g_strcmp0(id, "") == 0; - - if (sync_one) - { - RequestSyncIndicator(id); - } - else - { - RequestSyncAll(); - } - } - else if (signal_name == "EntryShowNowChanged") - { - gchar* id = NULL; - gboolean show_now; - - g_variant_get(parameters, "(sb)", &id, &show_now); - owner_->SetEntryShowNow(id, show_now); - - g_free(id); - } -} - DBusIndicators::DBusIndicators() : pimpl(new Impl(this)) -{ -} +{} DBusIndicators::~DBusIndicators() -{ - delete pimpl; -} +{} void DBusIndicators::SyncGeometries(std::string const& name, EntryLocationMap const& locations) @@ -519,9 +455,10 @@ } void DBusIndicators::OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button) + unsigned int xid, int x, int y, + unsigned int button, unsigned int timestamp) { - pimpl->OnEntryShowMenu(entry_id, x, y, timestamp, button); + pimpl->OnEntryShowMenu(entry_id, xid, x, y, button, timestamp); } void DBusIndicators::OnEntrySecondaryActivate(std::string const& entry_id, @@ -530,147 +467,11 @@ pimpl->OnEntrySecondaryActivate(entry_id, timestamp); } -std::string DBusIndicators::name() const -{ - return pimpl->name(); -} - -std::string DBusIndicators::owner_name() const +void DBusIndicators::OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp) { - return pimpl->owner_name(); + pimpl->OnShowAppMenu(xid, x, y, timestamp); } -bool DBusIndicators::using_local_service() const -{ - return pimpl->using_local_service(); -} - - -namespace -{ - -// Initialise DBus for the panel service, and let us know when it is -// ready. The unused bool return is to fit with the GSourceFunc. -gboolean reconnect_to_service(gpointer data) -{ - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - S_NAME, - S_PATH, - S_IFACE, - NULL, - on_proxy_ready_cb, - data); - return false; -} - -// Make sure the proxy object exists and has a name, and if so, pass -// that on to the DBusIndicators. -void on_proxy_ready_cb(GObject* source, GAsyncResult* res, gpointer data) -{ - DBusIndicators::Impl* remote = reinterpret_cast(data); - GError* error = NULL; - GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - static bool force_tried = false; - - char* name_owner; - if (G_IS_DBUS_PROXY(proxy) && (name_owner = g_dbus_proxy_get_name_owner(proxy))) - { - remote->OnRemoteProxyReady(G_DBUS_PROXY(proxy)); - g_free(name_owner); - return; - } - else - { - if (force_tried) - { - g_warning("WARNING: Unable to connect to the unity-panel-service %s", - error ? error->message : "Unknown"); - if (error) - g_error_free(error); - } - else - { - force_tried = true; - run_local_panel_service(); - g_timeout_add_seconds(2, reconnect_to_service, remote); - } - } - - g_object_unref(proxy); -} - - -bool run_local_panel_service() -{ - GError* error = NULL; - - // This is obviously hackish, but this part of the code is mostly hackish... - // Let's attempt to run it from where we expect it to be - std::string cmd = PREFIXDIR + std::string("/lib/unity/unity-panel-service"); - std::cerr << "\nWARNING: Couldn't load panel from installed services, " - << "so trying to load panel from known location: " - << cmd << "\n"; - - g_spawn_command_line_async(cmd.c_str(), &error); - if (error) - { - std::cerr << "\nWARNING: Unable to launch remote service manually: " - << error->message << "\n"; - g_error_free(error); - return false; - } - return true; -} - -void request_sync(GDBusProxy* proxy, const char* method, GVariant* name, SyncData* data) -{ - g_dbus_proxy_call(proxy, method, name, G_DBUS_CALL_FLAGS_NONE, - -1, data->cancel, on_sync_ready_cb, data); -} - -void on_sync_ready_cb(GObject* source, GAsyncResult* res, gpointer data) -{ - SyncData* sync_data = reinterpret_cast(data); - GError* error = NULL; - GVariant* args = g_dbus_proxy_call_finish((GDBusProxy*)source, res, &error); - - if (args == NULL) - { - g_warning("Unable to perform Sync() on panel service: %s", error->message); - g_error_free(error); - return; - } - - sync_data->self->Sync(args, sync_data); - g_variant_unref(args); -} - -bool send_show_entry(ShowEntryData* data) -{ - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(G_IS_DBUS_PROXY(data->proxy), FALSE); - - g_dbus_proxy_call(data->proxy, - "ShowEntry", - g_variant_new("(suiii)", - data->entry_id.c_str(), - 0, - data->x, - data->y, - data->button), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); - delete data; - return FALSE; -} - -} // anonymous namespace - } // namespace indicator } // namespace unity diff -Nru unity-5.6.0/UnityCore/DBusIndicators.h unity-5.8.0/UnityCore/DBusIndicators.h --- unity-5.6.0/UnityCore/DBusIndicators.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/DBusIndicators.h 2012-03-23 11:53:16.000000000 +0000 @@ -42,20 +42,17 @@ EntryLocationMap const& locations); virtual void OnEntryScroll(std::string const& entry_id, int delta); - virtual void OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button); + virtual void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp); virtual void OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp); + virtual void OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp); - std::string name() const; - std::string owner_name() const; - bool using_local_service() const; - - // Due to the callback nature, the Impl class must be declared public, but - // it is not available to anyone except the internal implementation. - class Impl; private: - Impl* pimpl; + class Impl; + std::unique_ptr pimpl; }; } diff -Nru unity-5.6.0/UnityCore/FilesystemLenses.cpp unity-5.8.0/UnityCore/FilesystemLenses.cpp --- unity-5.6.0/UnityCore/FilesystemLenses.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/FilesystemLenses.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -236,7 +236,7 @@ gboolean result = g_file_load_contents_finish(file, res, &contents, &length, NULL, error.AsOutParam()); - if (result && !error) + if (result) { self->GetLensDataFromKeyFile(file, contents.Value(), length); self->SortLensList(); @@ -246,6 +246,8 @@ LOG_WARN(logger) << "Unable to read lens file " << path.Str() << ": " << error; + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; // self is invalid now } self->cancel_map_.erase(file); @@ -350,6 +352,7 @@ ~Impl() { if (timeout_id != 0) g_source_remove (timeout_id); + finished_slot_.disconnect(); } void OnLoadingFinished(); @@ -363,6 +366,7 @@ FilesystemLenses* owner_; LensDirectoryReader::Ptr reader_; LensList lenses_; + sigc::connection finished_slot_; guint timeout_id; }; @@ -371,7 +375,7 @@ , reader_(reader) , timeout_id(0) { - reader_->load_finished.connect(sigc::mem_fun(this, &Impl::OnLoadingFinished)); + finished_slot_ = reader_->load_finished.connect(sigc::mem_fun(this, &Impl::OnLoadingFinished)); if (reader_->IsDataLoaded()) { // we won't get any signal, so let's just emit our signals after construction diff -Nru unity-5.6.0/UnityCore/GLibDBusProxy.cpp unity-5.8.0/UnityCore/GLibDBusProxy.cpp --- unity-5.6.0/UnityCore/GLibDBusProxy.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/GLibDBusProxy.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -39,13 +39,6 @@ using std::string; -struct CallData -{ - DBusProxy::ReplyCallback callback; - DBusProxy::Impl* impl; - std::string method_name; -}; - class DBusProxy::Impl { public: @@ -62,8 +55,7 @@ void StartReconnectionTimeout(); void Connect(); - void OnProxySignal(GDBusProxy* proxy, char* sender_name, char* signal_name, - GVariant* parameters); + void Call(string const& method_name, GVariant* parameters, ReplyCallback callback, @@ -74,12 +66,20 @@ void Connect(string const& signal_name, ReplyCallback callback); bool IsConnected(); - static void OnNameAppeared(GDBusConnection* connection, const char* name, - const char* name_owner, gpointer impl); - static void OnNameVanished(GDBusConnection* connection, const char* name, gpointer impl); + void OnProxyNameOwnerChanged(GDBusProxy*, GParamSpec*); + void OnProxySignal(GDBusProxy* proxy, char* sender_name, char* signal_name, + GVariant* parameters); + static void OnProxyConnectCallback(GObject* source, GAsyncResult* res, gpointer impl); static void OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data); - + + struct CallData + { + DBusProxy::ReplyCallback callback; + DBusProxy::Impl* impl; + std::string method_name; + }; + DBusProxy* owner_; string name_; string object_path_; @@ -94,6 +94,7 @@ bool connected_; glib::Signal g_signal_connection_; + glib::Signal name_owner_signal_; SignalHandlers handlers_; }; @@ -115,14 +116,6 @@ , reconnect_timeout_id_(0) , connected_(false) { - LOG_DEBUG(logger) << "Watching name " << name_; - watcher_id_ = g_bus_watch_name(bus_type_, - name.c_str(), - G_BUS_NAME_WATCHER_FLAGS_AUTO_START, - DBusProxy::Impl::OnNameAppeared, - DBusProxy::Impl::OnNameVanished, - this, - NULL); StartReconnectionTimeout(); } @@ -135,33 +128,6 @@ g_source_remove(reconnect_timeout_id_); } -void DBusProxy::Impl::OnNameAppeared(GDBusConnection* connection, - const char* name, - const char* name_owner, - gpointer impl) -{ - DBusProxy::Impl* self = static_cast(impl); - LOG_DEBUG(logger) << self->name_ << " appeared"; - - if (self->proxy_) - { - self->connected_ = true; - self->owner_->connected.emit(); - } -} - -void DBusProxy::Impl::OnNameVanished(GDBusConnection* connection, - const char* name, - gpointer impl) -{ - DBusProxy::Impl* self = static_cast(impl); - - LOG_DEBUG(logger) << self->name_ << " vanished"; - - self->connected_ = false; - self->owner_->disconnected.emit(); -} - void DBusProxy::Impl::StartReconnectionTimeout() { LOG_DEBUG(logger) << "Starting reconnection timeout for " << name_; @@ -204,6 +170,8 @@ GAsyncResult* res, gpointer impl) { + DBusProxy::Impl* self = static_cast(impl); + glib::Error error; glib::Object proxy(g_dbus_proxy_new_for_bus_finish(res, &error)); @@ -215,14 +183,44 @@ return; } - DBusProxy::Impl* self = static_cast(impl); LOG_DEBUG(logger) << "Sucessfully created proxy: " << self->object_path_; self->proxy_ = proxy; self->g_signal_connection_.Connect(self->proxy_, "g-signal", - sigc::mem_fun(self, &DBusProxy::Impl::OnProxySignal)); - self->connected_ = true; - self->owner_->connected.emit(); + sigc::mem_fun(self, &Impl::OnProxySignal)); + self->name_owner_signal_.Connect(self->proxy_, "notify::g-name-owner", + sigc::mem_fun(self, &Impl::OnProxyNameOwnerChanged)); + + // If a proxy cannot autostart a service, it doesn't throw an error, but + // sets name_owner to NULL + if (glib::String(g_dbus_proxy_get_name_owner(proxy))) + { + self->connected_ = true; + self->owner_->connected.emit(); + } +} + +void DBusProxy::Impl::OnProxyNameOwnerChanged(GDBusProxy* proxy, GParamSpec* param) +{ + glib::String name_owner(g_dbus_proxy_get_name_owner(proxy)); + + if (name_owner) + { + if (!connected_) + { + LOG_DEBUG(logger) << name_ << " appeared"; + + connected_ = true; + owner_->connected.emit(); + } + } + else if (connected_) + { + LOG_DEBUG(logger) << name_ << " vanished"; + + connected_ = false; + owner_->disconnected.emit(); + } } void DBusProxy::Impl::OnProxySignal(GDBusProxy* proxy, @@ -308,9 +306,7 @@ {} DBusProxy::~DBusProxy() -{ - delete pimpl; -} +{} void DBusProxy::Call(string const& method_name, GVariant* parameters, diff -Nru unity-5.6.0/UnityCore/GLibDBusProxy.h unity-5.8.0/UnityCore/GLibDBusProxy.h --- unity-5.6.0/UnityCore/GLibDBusProxy.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/GLibDBusProxy.h 2012-03-23 11:53:16.000000000 +0000 @@ -62,9 +62,9 @@ static void NoReplyCallback(GVariant* v) {}; // Public due to use in some callbacks - class Impl; private: - Impl* pimpl; + class Impl; + std::unique_ptr pimpl; }; } diff -Nru unity-5.6.0/UnityCore/HomeLens.cpp unity-5.8.0/UnityCore/HomeLens.cpp --- unity-5.6.0/UnityCore/HomeLens.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/HomeLens.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -770,7 +770,7 @@ if (running_searches_ <= 0) { owner_->search_finished.emit(Hints()); - LOG_DEBUG(logger) << "Search finished"; + LOG_INFO(logger) << "Search finished"; } }); @@ -911,7 +911,7 @@ { if (lens->search_in_global()) { - LOG_DEBUG(logger) << " - Global search on '" << lens->id() << "' for '" + LOG_INFO(logger) << " - Global search on '" << lens->id() << "' for '" << search_string << "'"; lens->view_type = ViewType::HOME_VIEW; lens->GlobalSearch(search_string); diff -Nru unity-5.6.0/UnityCore/Hud.cpp unity-5.8.0/UnityCore/Hud.cpp --- unity-5.6.0/UnityCore/Hud.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Hud.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -150,6 +150,7 @@ GVariant* queries = g_variant_get_child_value(query, 1); BuildQueries(queries); g_variant_unref(queries); + parent_->queries_updated.emit(queries_); } } diff -Nru unity-5.6.0/UnityCore/Indicator.cpp unity-5.8.0/UnityCore/Indicator.cpp --- unity-5.6.0/UnityCore/Indicator.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Indicator.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -35,11 +35,18 @@ Indicator::~Indicator() { - for (auto entry : entries_) { - on_entry_removed(entry->id()); - } + for (auto entry : entries_) + on_entry_removed.emit(entry->id()); entries_.clear(); + + for (auto it : entries_connections_) + { + for (auto conn : it.second) + conn.disconnect(); + + it.second.clear(); + } } std::string const& Indicator::name() const @@ -72,7 +79,12 @@ } for (auto entry : to_rm) { - on_entry_removed(entry->id()); + for (auto conn : entries_connections_[entry]) + conn.disconnect(); + + entries_connections_[entry].clear(); + + on_entry_removed.emit(entry->id()); entries_.remove(entry); } @@ -82,10 +94,19 @@ continue; // Just add the new entry, and connect it up. - new_entry->on_show_menu.connect(sigc::mem_fun(this, &Indicator::OnEntryShowMenu)); - new_entry->on_secondary_activate.connect(sigc::mem_fun(this, &Indicator::OnEntrySecondaryActivate)); - new_entry->on_scroll.connect(sigc::mem_fun(this, &Indicator::OnEntryScroll)); + sigc::connection conn; + std::vector& new_entry_connections = entries_connections_[new_entry]; + + conn = new_entry->on_show_menu.connect(sigc::mem_fun(this, &Indicator::OnEntryShowMenu)); + new_entry_connections.push_back(conn); + + conn = new_entry->on_secondary_activate.connect(sigc::mem_fun(this, &Indicator::OnEntrySecondaryActivate)); + new_entry_connections.push_back(conn); + + conn = new_entry->on_scroll.connect(sigc::mem_fun(this, &Indicator::OnEntryScroll)); entries_.push_back(new_entry); + new_entry_connections.push_back(conn); + on_entry_added.emit(new_entry); } } @@ -99,11 +120,10 @@ return Entry::Ptr(); } -void Indicator::OnEntryShowMenu(std::string const& entry_id, - int x, int y, - int timestamp, int button) +void Indicator::OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, unsigned int timestamp) { - on_show_menu.emit(entry_id, x, y, timestamp, button); + on_show_menu.emit(entry_id, xid, x, y, button, timestamp); } void Indicator::OnEntrySecondaryActivate(std::string const& entry_id, diff -Nru unity-5.6.0/UnityCore/IndicatorEntry.cpp unity-5.8.0/UnityCore/IndicatorEntry.cpp --- unity-5.6.0/UnityCore/IndicatorEntry.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/IndicatorEntry.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -27,8 +27,6 @@ namespace indicator { -std::string const Entry::UNUSED_ID("|"); - Entry::Entry(std::string const& id, std::string const &name_hint, std::string const& label, @@ -104,6 +102,12 @@ return priority_; } +bool Entry::visible() const +{ + return ((label_visible_ && !label_.empty()) || + (image_type_ != 0 && image_visible_ && !image_data_.empty())); +} + void Entry::set_active(bool active) { if (active_ == active) @@ -114,6 +118,16 @@ updated.emit(); } +void Entry::set_geometry(nux::Rect const& geometry) +{ + if (geometry_ == geometry) + return; + + geometry_ = geometry; + geometry_changed.emit(geometry); + updated.emit(); +} + void Entry::setLabel(std::string const& label, bool sensitive, bool visible) { if (label_ == label && sensitive == label_sensitive_ && visible == label_visible_) @@ -154,6 +168,11 @@ return active_; } +nux::Rect const& Entry::geometry() const +{ + return geometry_; +} + Entry& Entry::operator=(Entry const& rhs) { id_ = rhs.id_; @@ -186,28 +205,14 @@ updated.emit(); } -void Entry::MarkUnused() -{ - id_ = UNUSED_ID; - name_hint_ = ""; - label_ = ""; - label_sensitive_ = false; - label_visible_ = false; - image_type_ = 0; - image_data_ = ""; - image_sensitive_ = false; - image_visible_ = false; - updated.emit(); -} - -bool Entry::IsUnused() const +void Entry::ShowMenu(int x, int y, unsigned int button, unsigned int timestamp) { - return id_ == UNUSED_ID; + ShowMenu(0, x, y, button, timestamp); } -void Entry::ShowMenu(int x, int y, int timestamp, int button) +void Entry::ShowMenu(unsigned int xid, int x, int y, unsigned int button, unsigned int timestamp) { - on_show_menu.emit(id_, x, y, timestamp, button); + on_show_menu.emit(id_, xid, x, y, button, timestamp); } void Entry::SecondaryActivate(unsigned int timestamp) diff -Nru unity-5.6.0/UnityCore/IndicatorEntry.h unity-5.8.0/UnityCore/IndicatorEntry.h --- unity-5.6.0/UnityCore/IndicatorEntry.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/IndicatorEntry.h 2012-03-23 11:53:16.000000000 +0000 @@ -28,7 +28,7 @@ #include #include -#include "NuxCore/Rect.h" +#include namespace unity { @@ -43,7 +43,6 @@ { public: typedef boost::shared_ptr Ptr; - static std::string const UNUSED_ID; Entry(std::string const& id, std::string const& name_hint, @@ -72,8 +71,13 @@ void set_active(bool active); bool active() const; + void set_geometry(nux::Rect const& geometry); + nux::Rect const& geometry() const; + int priority() const; + bool visible() const; + /** * Whether this entry should be shown to the user. * Example uses: Application menubar items are only shown when the user @@ -82,10 +86,8 @@ bool show_now() const; void set_show_now(bool show_now); - void MarkUnused(); - bool IsUnused() const; - - void ShowMenu(int x, int y, int timestamp, int button); + void ShowMenu(int x, int y, unsigned int button, unsigned int timestamp); + void ShowMenu(unsigned int xid, int x, int y, unsigned int button, unsigned int timestamp); void SecondaryActivate(unsigned int timestamp); void Scroll(int delta); @@ -96,9 +98,10 @@ // Signals sigc::signal updated; sigc::signal active_changed; + sigc::signal geometry_changed; sigc::signal show_now_changed; - sigc::signal on_show_menu; + sigc::signal on_show_menu; sigc::signal on_secondary_activate; sigc::signal on_scroll; @@ -118,6 +121,8 @@ bool show_now_; bool active_; + + nux::Rect geometry_; }; std::ostream& operator<<(std::ostream& out, Entry const& e); diff -Nru unity-5.6.0/UnityCore/Indicator.h unity-5.8.0/UnityCore/Indicator.h --- unity-5.6.0/UnityCore/Indicator.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Indicator.h 2012-03-23 11:53:16.000000000 +0000 @@ -23,6 +23,7 @@ #include #include +#include #include "IndicatorEntry.h" @@ -39,28 +40,31 @@ typedef std::list Entries; Indicator(std::string const& name); - ~Indicator(); + virtual ~Indicator(); std::string const& name() const; + virtual bool IsAppmenu() const { return false; } + void Sync(Entries const& new_entries); Entry::Ptr GetEntry(std::string const& entry_id) const; Entries GetEntries() const; - void OnEntryShowMenu(std::string const& entry_id, int x, int y, int timestamp, int button); - void OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp); - void OnEntryScroll(std::string const& entry_id, int delta); - // Signals sigc::signal on_entry_added; sigc::signal on_entry_removed; - sigc::signal on_show_menu; + sigc::signal on_show_menu; sigc::signal on_secondary_activate; sigc::signal on_scroll; -private: +protected: + void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, int x, int y, unsigned int button, unsigned int timestamp); + void OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp); + void OnEntryScroll(std::string const& entry_id, int delta); + Entries entries_; std::string name_; + std::map> entries_connections_; friend std::ostream& operator<<(std::ostream& out, Indicator const& i); }; diff -Nru unity-5.6.0/UnityCore/Indicators.cpp unity-5.8.0/UnityCore/Indicators.cpp --- unity-5.6.0/UnityCore/Indicators.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Indicators.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -17,8 +17,9 @@ * Authored by: Neil Jagdish Patel * Tim Penhey */ -#include "Indicators.h" +#include "Indicators.h" +#include "AppmenuIndicator.h" namespace unity { @@ -35,7 +36,7 @@ : owner_(owner) {} - void ActivateEntry(std::string const& entry_id); + void ActivateEntry(std::string const& entry_id, nux::Rect const& geometry); void SetEntryShowNow(std::string const& entry_id, bool show_now); IndicatorsList GetIndicators() const; @@ -57,18 +58,14 @@ Indicators::Indicators() : pimpl(new Impl(this)) -{ -} +{} Indicators::~Indicators() -{ - delete pimpl; -} +{} -void Indicators::ActivateEntry(std::string const& entry_id) +void Indicators::ActivateEntry(std::string const& entry_id, nux::Rect const& geometry) { - pimpl->ActivateEntry(entry_id); - on_entry_activated.emit(entry_id); + pimpl->ActivateEntry(entry_id, geometry); } void Indicators::SetEntryShowNow(std::string const& entry_id, bool show_now) @@ -96,14 +93,25 @@ return pimpl->RemoveIndicator(name); } -void Indicators::Impl::ActivateEntry(std::string const& entry_id) +void Indicators::Impl::ActivateEntry(std::string const& entry_id, nux::Rect const& geometry) { if (active_entry_) + { + active_entry_->set_geometry(nux::Rect()); active_entry_->set_active(false); + } + active_entry_ = GetEntry(entry_id); + if (active_entry_) { + active_entry_->set_geometry(geometry); active_entry_->set_active(true); + owner_->on_entry_activated.emit(entry_id, geometry); + } + else + { + owner_->on_entry_activated.emit(std::string(), nux::Rect()); } } @@ -131,12 +139,27 @@ Indicator::Ptr Indicators::Impl::AddIndicator(std::string const& name) { - Indicator::Ptr indicator(new Indicator(name)); + Indicator::Ptr indicator(GetIndicator(name)); + + if (indicator) + return indicator; + + if (name == "libappmenu.so") + { + AppmenuIndicator *appmenu = new AppmenuIndicator(name); + appmenu->on_show_appmenu.connect(sigc::mem_fun(owner_, &Indicators::OnShowAppMenu)); + indicator.reset(appmenu); + } + else + { + indicator.reset(new Indicator(name)); + } // The owner Indicators class is interested in the other events. indicator->on_show_menu.connect(sigc::mem_fun(owner_, &Indicators::OnEntryShowMenu)); indicator->on_secondary_activate.connect(sigc::mem_fun(owner_, &Indicators::OnEntrySecondaryActivate)); indicator->on_scroll.connect(sigc::mem_fun(owner_, &Indicators::OnEntryScroll)); + indicators_[name] = indicator; owner_->on_object_added.emit(indicator); @@ -165,16 +188,15 @@ Entry::Ptr Indicators::Impl::GetEntry(std::string const& entry_id) { - // Since we reuse Entry objects but change the value that they are keyed on, - // we need to traverse through the Indicators asking them if they have this - // entry_id. - Entry::Ptr result; - for (IndicatorMap::iterator i = indicators_.begin(), end = indicators_.end(); - i != end && !result; ++i) + for (auto it = indicators_.begin(); it != indicators_.end(); ++it) { - result = i->second->GetEntry(entry_id); + Entry::Ptr entry = it->second->GetEntry(entry_id); + + if (entry) + return entry; } - return result; + + return Entry::Ptr(); } diff -Nru unity-5.6.0/UnityCore/Indicators.h unity-5.8.0/UnityCore/Indicators.h --- unity-5.6.0/UnityCore/Indicators.h 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Indicators.h 2012-03-23 11:53:16.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * 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 @@ -43,7 +43,7 @@ /** * internal */ - void ActivateEntry(std::string const& entry_id); + void ActivateEntry(std::string const& entry_id, nux::Rect const& geometry); /** * internal @@ -58,11 +58,22 @@ /** * internal */ - virtual void OnEntryShowMenu(std::string const& entry_id, - int x, int y, int timestamp, int button) = 0; + virtual void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, + int x, int y, unsigned int button, + unsigned int timestamp) = 0; + + /** + * internal + */ virtual void OnEntrySecondaryActivate(std::string const& entry_id, unsigned int timestamp) = 0; + /** + * internal + */ + virtual void OnShowAppMenu(unsigned int xid, int x, int y, + unsigned int timestamp) = 0; + // Signals sigc::signal on_object_added; sigc::signal on_object_removed; @@ -79,7 +90,7 @@ * An entry just got activated. View needs to repaint it. * @param entry_id entry id */ - sigc::signal on_entry_activated; + sigc::signal on_entry_activated; /** * internal @@ -89,12 +100,22 @@ /** * The service is about to show a menu. * @param entry_id entry id - * @param x x coordinate - * @param y y coordinate - * @param timestamp current time + * @param xid window xid + * @param x coordinate + * @param y coordinate * @param button pressed button + * @param timestamp current time + */ + sigc::signal on_entry_show_menu; + + /** + * The service is about to show an appmenu. + * @param xid window xid + * @param x coordinate + * @param y coordinate + * @param timestamp current time */ - sigc::signal on_entry_show_menu; + sigc::signal on_show_appmenu; protected: Indicator::Ptr GetIndicator(std::string const& name); @@ -103,7 +124,7 @@ private: class Impl; - Impl* pimpl; + std::unique_ptr pimpl; }; } diff -Nru unity-5.6.0/UnityCore/Lens.cpp unity-5.8.0/UnityCore/Lens.cpp --- unity-5.6.0/UnityCore/Lens.cpp 2012-03-12 09:16:36.000000000 +0000 +++ unity-5.8.0/UnityCore/Lens.cpp 2012-03-23 11:53:16.000000000 +0000 @@ -456,9 +456,9 @@ { LOG_DEBUG(logger) << "Searching '" << id_ << "' for '" << search_string << "'"; - if (!proxy_->IsConnected()) + if (proxy_ == NULL) { - LOG_DEBUG(logger) << "Skipping search. Proxy not connected. ('" << id_ << "')"; + LOG_DEBUG(logger) << "Skipping search. Proxy not initialized. ('" << id_ << "')"; return; }