diff -Nru unity-5.8.0/AUTHORS unity-5.10.0/AUTHORS --- unity-5.8.0/AUTHORS 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/AUTHORS 2012-04-12 13:21:21.000000000 +0000 @@ -1,6 +1,7 @@ 3v1n0 , Marco Trevisan (Treviño) agateau alanbell@ubuntu.com + Albert Astals Alejandro Piñeiro Alexandros Frantzis Alexandros Frantzis , Marc Ordinas i Llopis , Jay Taoko @@ -11,7 +12,9 @@ Andrea Cimitan Andrey Logvinov + Benjamin Kerensa Bilal Akhtar + Bilal Akhtar , Thomi Richards Brandon Schaefer Brandon Schaefer @@ -36,14 +39,18 @@ Jason Conti Jason Smith Jason Smith , Andrea Cimitan + Jason Smith , Jay Taoko , Brandon Schaefer Jason Smith , Marco Trevisan (Treviño) , Thomi Richards Jason Smith , smspillaz Jason Smith , Tim Penhey jassmith@gmail.com Jay Ó Broin Jay Taoko + Jay Taoko , Mirco Müller Jay Taoko , Robert Carr Jeremy Bicha + Kevin DuBois + Koichi Akabe Lars Uebernickel Loïc Molinari Lorenzo Mattei @@ -94,6 +101,7 @@ Thomi Richards , Alex Launi Thomi Richards , Thomi Richards Thomi Richards + Thomi Richards , Gordon Allott Thomi Richards , Jason Smith Thomi Richards , Ted Gould Thomi Richards , Thomi Richards diff -Nru unity-5.8.0/ChangeLog unity-5.10.0/ChangeLog --- unity-5.8.0/ChangeLog 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/ChangeLog 2012-04-12 13:21:21.000000000 +0000 @@ -1,3 +1,3609 @@ +2012-04-12 Michal Hruby + + Make sure the lenses search for things we want on startup. Fixes: https://bugs.launchpad.net/bugs/979799. Approved by Gord Allott. + +2012-04-12 Michal Hruby + + Make sure the lenses search for things we want on startup + +2012-04-12 Gord Allott + + creates input windows and opens/closes them on startup for the HUD and Dash. Fixes: https://bugs.launchpad.net/bugs/774447. Approved by Didier Roche. + +2012-04-12 Gord Allott + + added fixmes + +2012-04-12 Gord Allott + + opens an input window for the dash and hud and closes them immediately on startup, to fix hud/dash passthrough + +2012-04-12 Andrea Azzarone + + Fix a mistake in FilterExpanderLabel.cpp.. Fixes: . Approved by Didier Roche. + +2012-04-12 Andrea Azzarone + + Replace AddLayout with RemoveChildObject in FilterExpanderLabel.cpp + +2012-04-11 Jay Taoko + + Deactivated panel blurring when a window is maximised and the dash is open on system without GLSL support.. Fixes: https://bugs.launchpad.net/bugs/975103. Approved by Tim Penhey. + +2012-04-09 Jay Taoko + + * Fix for bug #975103 + * Deactivated panel blurring when a window is maximized and the dash is open on system without GLSL support. + +2012-04-11 Gord Allott + + HUD: Ignores service updates if user is key navigating. Fixes: https://bugs.launchpad.net/bugs/962984. Approved by Michal Hruby. + +2012-04-11 Gord Allott + + tests + +2012-04-11 Gord Allott + + doesn't update results in hud if you start to keynav + +2012-04-11 smspillaz + + Hack around the nvidia driver losing window pixmaps when minimizing windows. See LP #977189. Fixes: https://bugs.launchpad.net/bugs/977189. Approved by Michal Hruby, Didier Roche. + +2012-04-11 smspillaz + + Added manual test + +2012-04-11 smspillaz + + Force a rebind when windows are minimized + + See LP#977189. The nvidia driver seems to lose pixmap contents when we + minimize windows ... for whatever reason. Force a rebind of those contents + when the minimize animation has completed. + +2012-04-11 Andrea Cimitan + + Reduced frosty effect to 30% (was 100% before). Fixes: https://bugs.launchpad.net/bugs/978785. Approved by Didier Roche, Xi Zhu. + +2012-04-11 Andrea Cimitan + + Update dash_noise.png asset by making it more subtle + +2012-04-11 Andrea Azzarone + + Lens selection should work when clicking in the rectangle outside of the icon.. Fixes: https://bugs.launchpad.net/bugs/937193. Approved by . + +2012-04-10 Andrea Azzarone + + Fix test style. + +2012-04-10 Andrea Azzarone + + Rename DashLensBar to DashLensBarTests. + +2012-04-10 Andrea Azzarone + + Fix AP test. + +2012-04-10 Andrea Azzarone + + Add introspection to LensBarIcon. + +2012-04-10 Andrea Azzarone + + Fix bug #977961. + +2012-04-11 Andrea Azzarone + + The keyboard shortcuts overlay bottom is truncated. . Fixes: https://bugs.launchpad.net/bugs/973386. Approved by Tim Penhey. + +2012-04-11 Andrea Azzarone + + Add manual-test. + +2012-04-11 Andrea Azzarone + + Fix bug #973386. + +2012-04-11 Brandon Schaefer + + Fixed uninitialized variables in LauncherController. Fixes: . Approved by Tim Penhey. + +2012-04-10 Brandon Schaefer + + * Fixed uninitialized variables + +2012-04-11 Thomi Richards + + Ensure autopilot always attaches the unity log, even if unity crashes.. Fixes: . Approved by Tim Penhey. + +2012-04-11 Thomi Richards + + Make sure we still attach the unity log if unity has crashed. + +2012-04-11 Alex Launi + + Set the compose key before running dash compose key tests. Fixes: . Approved by Thomi Richards, Alex Launi. + +2012-04-10 Alex Launi + + remove Gio and Glib in globals.py + +2012-04-10 Alex Launi + + Pass list to check_output and keep test_dash.py PEP8 compliant + +2012-04-10 Alex Launi + + remove gi import + +2012-04-10 Alex Launi + + reset _DISPLAY after changing the keyboard map + +2012-04-10 Alex Launi + + remove line + +2012-04-10 Alex Launi + + Use gsettings to set the multi key for cases where it's not already set + +2012-04-09 Alex Launi + + Set the compose key before running multi key tests + +2012-04-10 Thomi Richards + + PanelMenuView no longer tries to dereference a pointer that has already been deleted when it's destroyed.. Fixes: . Approved by Tim Penhey, Brandon Schaefer. + +2012-04-11 Thomi Richards + + Removed nullptr assigns. + +2012-04-11 Thomi Richards + + Found a better way. + +2012-04-11 Thomi Richards + + Fixed an issue in PanelMenuView where we were dereferencing a pointer that had already been deleted. + +2012-04-10 Andrea Azzarone + + Disconnect IconLoader handle in IconTexture destructor. Fixes: https://bugs.launchpad.net/bugs/935307. Approved by Tim Penhey. + +2012-04-11 Andrea Azzarone + + Fix. + +2012-04-11 Andrea Azzarone + + Disconnect IconLoader in IconTexture dtor. + +2012-04-10 Thomi Richards + + Fix StaticCairoText so we're not reading uninitialised values in an if statement.. Fixes: . Approved by Sam Spilsbury. + +2012-04-11 Thomi Richards + + Fixed valgrind error about using uninitialised valies in an if statement. + +2012-04-10 Thomi Richards + + BGHash no longer causes an invalid read of a deleted pointer in it's destructor.. Fixes: . Approved by Alex Launi. + +2012-04-11 Thomi Richards + + BGHash no longer causes the glib::SignalManager to read a deleted pointer. + +2012-04-10 Thomi Richards + + FavoriteStore is no longer a singleton. Fixes a memory leak in FavoriteStoreGSettings.. Fixes: . Approved by Gord Allott. + +2012-04-11 Thomi Richards + + Merged trunk. + +2012-04-10 Thomi Richards + + Fixed favoritestore unit tests. + +2012-04-10 Thomi Richards + + Keep the * next to the type. + +2012-04-10 Thomi Richards + + Convert FavoriteStore from a proper singleton into a quasi-singleton, thereby fixing a memory leak in FavoriteStoreGSettings. + +2012-04-10 Thomi Richards + + Fix valgrind error: "Invalid read of size 8" inside PanelTray.. Fixes: . Approved by . + +2012-04-10 Thomi Richards + + Don't delete the gtk window twice inside PanelTray. + +2012-04-10 Thomi Richards + + Fixed a memory leak in the LauncherController.. Fixes: . Approved by Gord Allott. + +2012-04-10 Thomi Richards + + Fix memory leak in LauncherController. + +2012-04-10 Thomi Richards + + Fix memory leak in GeisAdaptor and GestureEngine.. Fixes: . Approved by Tim Penhey. + +2012-04-10 Thomi Richards + + Remove gesture_engine_ from initialiser list. + +2012-04-10 Thomi Richards + + Renamed to gesture_engine_ + +2012-04-10 Thomi Richards + + Fixed with feedback from review. + +2012-04-10 Thomi Richards + + GeisAdaptor is no longer a singleton, and we don't leak the GestureEngine either. + +2012-04-09 Thomi Richards + + ResultRendererTile no longer uses an unitialised variable to determine correct tile scaling.. Fixes: . Approved by Tim Penhey. + +2012-04-10 Thomi Richards + + ResultRenderTile no longer uses an uninitialised variable to scale icons. + +2012-04-09 Thomi Richards + + Fix memory leak in PanelIndicatorEntryView.. Fixes: . Approved by Tim Penhey. + +2012-04-10 Thomi Richards + + Fix from review feedback. + +2012-04-10 Thomi Richards + + Fix leak in a better way after code review. Use nux::ObjectPtr instead of deleting the texture manually. + +2012-04-10 Thomi Richards + + Move delete closer to the allocation. + +2012-04-10 Thomi Richards + + Delete texture when we die as well. + +2012-04-10 Thomi Richards + + Don't leak texture in Panel::Refresh method. + +2012-04-09 Thomi Richards + + Fix a memory leak in the LauncherIcon code.. Fixes: . Approved by Tim Penhey. + +2012-04-10 Thomi Richards + + Free the pango font description after we're done with it in the LauncherIcon. + +2012-04-09 Thomi Richards + + Fix a memory leak in LensDirectoryReader.. Fixes: . Approved by Tim Penhey. + +2012-04-10 Thomi Richards + + Don't leak the return value of g_keyfile_get_string. + +2012-04-09 Didier Roche + + Make Ubuntu Desktop string translated again. We can't use a namespaced version as the gettext domain isn't setup yet. + Pick already translated Alt and Press string (LP: #975815). Fixes: https://bugs.launchpad.net/bugs/975815. Approved by Sam Spilsbury. + +2012-04-09 Didier Roche + + make it a const as it doesn't change + +2012-04-09 Didier Roche + + Pick already translated Alt and Press string (LP: #975815) + +2012-04-09 Didier Roche + + make Ubuntu Desktop string translated again. We can't use a namespaced version as the gettext domain isn't setup yet + +2012-04-09 Andrea Cimitan + + Change hilight and card background color. Fixes: . Approved by . + +2012-04-07 Andrea Cimitan + + Correct card background values from design + +2012-04-06 Gord Allott + + Modifies our BGHash codebase to read the average colour from the root XWindow property + lots of code removed. + + Tests will arrive on Monday. Gord committed to it ;). Fixes: . Approved by Andrea Cimitan. + +2012-04-06 Andrea Cimitan + + Merge el trunko + +2012-04-06 Didier Roche + + sometimes you see a hundred lines of conflicts in a file… and then, you realize it's just because of a blank added line… + +2012-04-05 Gord Allott + + resolve conflicts, merged with trunk + +2012-04-05 Gord Allott + + Ensures we react to property changes on the root window + +2012-04-05 Gord Allott + + make bghash use the root window method + +2012-04-06 Didier Roche + + reverting rev 2237: caused bug #975103 and some side-effects on at least another machine making unity unusable (see comment #1). Fixes: . Approved by . + +2012-04-06 Didier Roche + + reverting rev 2237: caused bug #975103 and some side-effects on at least another machine making unity unusable (see comment #1) + +2012-04-06 Michal Hruby + + Fix stack corruption. Fixes: . Approved by Didier Roche. + +2012-04-06 Michal Hruby + + Fix stack corruption + +2012-04-06 Andrea Cimitan + + Fix average colors tweaks. Fixes: . Approved by Andrea Cimitan, Mirco Müller. + +2012-04-06 Andrea Cimitan + + Don't call MatchColor on the aubergine + +2012-04-06 Andrea Cimitan + + Process canonical Aibergine too, to fix alpha value to 0.72f + +2012-04-06 Andrea Cimitan + + Remove useless computation and improves saturation tune + +2012-04-06 Mirco Müller + + Make sure the special masking of the dash's decoration is restored when a repaint of the lens-nav-bar destroyed it.. Fixes: . Approved by Andrea Cimitan. + +2012-04-06 Mirco Müller + + Make sure the special masking of the dash's decoration is restored when a repaint of the lens-nav-bar destroyed it + +2012-04-06 Andrea Cimitan + + Fix 974408 removing a regression introduced by revision 2221. Fixes: https://bugs.launchpad.net/bugs/974408. Approved by Michal Hruby. + +2012-04-06 Andrea Cimitan + + Fix 974408 by reverting a regression introduced by revision 2221 + +2012-04-06 Michal Hruby + + Fixes a regression that caused the category icons to use default icons. Fixes: . Approved by Mirco Müller. + +2012-04-06 Michal Hruby + + Fix missing category icons + +2012-04-06 smspillaz + + Fixes LP #877778 - Introduces tests for UnityShowdesktopHandler. Fixes: https://bugs.launchpad.net/bugs/877778. Approved by Tim Penhey. + +2012-04-06 smspillaz + + Merge trunk + +2012-04-06 smspillaz + + Fix typo + +2012-04-06 smspillaz + + Fix typo + +2012-04-06 smspillaz + + Also update frame region when the window is unshowdesktoped + +2012-04-06 smspillaz + + Make pure virtual methods private + +2012-04-06 smspillaz + + Merge lp:unity and style + +2012-04-02 smspillaz + + Merge lp:unity + +2012-03-30 smspillaz + + Coding style + +2012-03-24 smspillaz + + Use some template magic to ensure that input removers are not leaked + +2012-03-24 smspillaz + + Added tests for opacity, paint masks, etc + +2012-03-24 smspillaz + + Add tests for fading out and in + +2012-03-24 smspillaz + + Added tests to ensure that the right windows are showdesktoped + +2012-03-24 smspillaz + + Testing framework for the showdesktop handler + +2012-03-24 smspillaz + + Split out the show desktop handler into its own file, break the dependency on compiz + +2012-03-23 smspillaz + + Fixes the showdesktop behaviour LP #877778 + + Animate from 0 to 1 instead of vice versa to prevent variable initializations + from breaking showdesktop, don't prematurely free the handler class and set the + window to opaque with PAINT_WINDOW_NO_CORE_INSTANCE_MASK when fully hidden + so it turns up in scale + +2012-04-06 Mirco Müller + + fontconfig changed and broke the line-spacing for the horiz. tile-renderer, so the line-spacing was adjusted to avoid text being clipped in the card-view (e.g. gwibber-lens entries with three lines of body-text). Fixes: https://bugs.launchpad.net/bugs/974523. Approved by Sam Spilsbury. + +2012-04-06 Mirco Müller + + After fontconfig changed, the line-spacing for the horiz. tile-renderer had to be adjusted, so text isn't clipped in the card-view... thus fixing LP: #974523 + +2012-04-06 Marco Trevisan (Treviño) + + Autopilot: added the testing support for the panel. Fixes: . Approved by Tim Penhey. + +2012-04-06 Marco Trevisan (Treviño) + + test_panel: added missing sleep time, waiting for app discovery + +2012-04-06 Marco Trevisan (Treviño) + + test_panel: add more sleeps... + +2012-04-06 Marco Trevisan (Treviño) + + autopilot, test_panel: make some tests more robust + +2012-04-06 Marco Trevisan (Treviño) + + PanelMenuView: added missing introspection variable (fix typo) + +2012-04-06 Marco Trevisan (Treviño) + + autopilot, test_panel: added grab area tests! + +2012-04-06 Marco Trevisan (Treviño) + + autopilot, test_panel: more indicator tests, plus panel key navigation. + +2012-04-06 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-06 Marco Trevisan (Treviño) + + autopilot, test_panel: added some indicators interaction tests + +2012-04-06 Marco Trevisan (Treviño) + + autopilot, panel: allow to get an indicator entry by the name-hint + +2012-04-05 Marco Trevisan (Treviño) + + autopilot: removed some tests duplication, added the PanelHoveringTests class + +2012-04-05 Marco Trevisan (Treviño) + + test_panel: adding menu tests + +2012-04-05 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-05 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-05 Marco Trevisan (Treviño) + + test_panel: added more window buttons tests for fitts law check + +2012-04-05 Marco Trevisan (Treviño) + + test_panel: making the tests more solid + +2012-04-05 Marco Trevisan (Treviño) + + autopilot: test_panel, some improvements to the move / maximize code + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, panel tests: some optimizations following Tim's review. + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, panel: make the click tests less prone to false positive + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: fix the "close button" test for other monitors + +2012-04-05 Marco Trevisan (Treviño) + + test_panel: even more tests for strange bugs + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, BAMF: closed is a signal... Let's use another trick + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: add some bug related window buttons tests + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: add test to check window buttons in multimonitor with overlays + +2012-04-05 Marco Trevisan (Treviño) + + DashController: use BuildWrapper and export the monitor into the introspection data + +2012-04-05 Marco Trevisan (Treviño) + + PanelMenuView: include fading timings into the introspection data + +2012-04-05 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: added even more WindowButtons tests. + +2012-04-05 Marco Trevisan (Treviño) + + DashView: add introspection data about the form-factor + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: added first tests for window buttons + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, bamf: get if a window has been closed + +2012-04-05 Marco Trevisan (Treviño) + + autopilot: panel, improved the window buttons related functions + +2012-04-05 Marco Trevisan (Treviño) + + PanelMenuView: add more introspection data + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_panel: do most of the initialization into the PanelTestsBase class + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, test_panel: added test to check that the window title has changed + +2012-04-04 Marco Trevisan (Treviño) + + test_panel: using self.screen_geo.drag_window_to_monitor instead of the self-provided function + +2012-04-04 Marco Trevisan (Treviño) + + X11: added ScreenGeometry().drag_window_to_monitor utility function + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, test_panel: added an utility function to launch application windows for a given monitor + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, bamf: add the set_focus method support + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + Merging with WindowButtons changes + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + test_panel: use maximize in cleanups, added a new test switching focused window + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, panel: added other window title related tests. + +2012-04-04 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: use absolute geometry for introspection data + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, panel: fixed some math, and more properties + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, panel: applying the Thomi's fixes + +2012-04-04 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, test_launcher: add keynav / switcher tests for focus activation + +2012-04-04 Marco Trevisan (Treviño) + + test_launcher: check if key_nav resumes the focus on cancel + +2012-04-04 Marco Trevisan (Treviño) + + autopilot, test_launcher: added tests for focus resume on launcher switcher + + Tests cover bug #970420 + +2012-04-04 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-04 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: introspection, use "entry_id", or Autopilot won't work with "id" parameters + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, test_panel: added first panel title tests + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, bamf: use the window geometry using gdk, xlib aren't working here. + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, bamf: add monitor property to window + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, keybindings: added some window management keybindings support + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, add first panel support. + +2012-04-03 Marco Trevisan (Treviño) + + Panel: use GetAbsoluteGeometry for introspection... + +2012-04-03 Marco Trevisan (Treviño) + + WindowButtons, PanelIndicatorEntryView: Set invisible items event insensitive + + Also, improve the introspection data + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-cleanup into panel-p-tests. + +2012-04-02 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: introspection add human-readable type and menu geometries + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: introspection, add introspection property if the desktop is active. + +2012-04-06 Marco Trevisan (Treviño) + + A lot of panel fixes with code cleanup and improvements to the panel code.. Fixes: https://bugs.launchpad.net/bugs/655184, https://bugs.launchpad.net/bugs/839690, https://bugs.launchpad.net/bugs/865701, https://bugs.launchpad.net/bugs/875932, https://bugs.launchpad.net/bugs/921316, https://bugs.launchpad.net/bugs/921918, https://bugs.launchpad.net/bugs/934680, https://bugs.launchpad.net/bugs/936425, https://bugs.launchpad.net/bugs/939054, https://bugs.launchpad.net/bugs/940683, https://bugs.launchpad.net/bugs/951747, https://bugs.launchpad.net/bugs/953868, https://bugs.launchpad.net/bugs/962410, https://bugs.launchpad.net/bugs/963118, https://bugs.launchpad.net/bugs/963134, https://bugs.launchpad.net/bugs/968261, https://bugs.launchpad.net/bugs/970420, https://bugs.launchpad.net/bugs/971947. Approved by Tim Penhey. + +2012-04-06 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-05 Marco Trevisan (Treviño) + + PanelView: Ops, fixing merge issue + +2012-04-05 Marco Trevisan (Treviño) + + Merging with trunk, resolving conflicts + +2012-04-05 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-05 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-05 Marco Trevisan (Treviño) + + PanelMenuView: don't allow clicks in the grab-area when an overlay is opened + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + PanelMenuView: remove the PostLayoutManagement set window-buttons' monitor + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-04 Marco Trevisan (Treviño) + + PanelController: Set the layout as the last thing, to avoid geometry changes (andyrock) + + And this finally fixes the "Cut" menus issue that happened on startup, + kudos to Andrea Azzarone for this fix. + +2012-04-04 Marco Trevisan (Treviño) + + DashController: save the dash monitor value and emit that both when showing and hiding the dash + + This caused an issue when hiding the dash in a monitor and trying to close it from another. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-04 Marco Trevisan (Treviño) + + WindowButtons: make the buttons multi-monitor aware. + + This is needed to ignore the overlay events for another monitor. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + PanelMenuView: don't ignore clicks on window buttons if the dash is opened on the given panel + +2012-04-04 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + PanelMenuView: only change the title on the target panel, when using the launcher switcher + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-04 Marco Trevisan (Treviño) + + SwitcherController: include the monitor in the UBUS_SWITCHER_SHOWN message + +2012-04-04 Marco Trevisan (Treviño) + + LauncherController: be multi-monitor aware when informing about the launcher key nav/switcher start + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-04 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-04 Marco Trevisan (Treviño) + + LauncherController: don't restore the focus if the selected icon is currently running. + +2012-04-04 Marco Trevisan (Treviño) + + PanelMenuView: s/OnMenusClosed/NotifyAllMenusClosed/g + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-03 Marco Trevisan (Treviño) + + PanelMenuView: be safer, if the current _new_application has been closed, just reset it. + + This fixes the always-visible menu issue that can happen when quickly closing/opening applications + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-03 Marco Trevisan (Treviño) + + PanelMenuView: no need to overwrite QueueDraw + +2012-04-03 Marco Trevisan (Treviño) + + PanelMenuView: adding more constants, removed unneeded _padding variable + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-03 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-03 Marco Trevisan (Treviño) + + PanelMenuView: s/AllMenusClosed/OnMenusClosed/g + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: set the maximum entries width on the PostLayout + + This fixes the missing menus / compressed menus issue that could happen on fresh start... + +2012-04-02 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelView: use Window type for tray Xid + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + PanelController: the tray can have more than one XID, on multimonitor. + + Updating unityshell for it. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + PanelTray: use Window type for xid + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: reduce the risk of getting an empty panel menu on startup + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelView: fixed some spacing issues + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelView: set some methods const + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelView: added the more generic IsActive method to get if a view is currently the active one + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-menu-view into panel-p-panel-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-02 Marco Trevisan (Treviño) + + WindowButtons: ignore the click events when the buttons are not enabled. + +2012-04-02 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: fixed typo in the comment + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelView: main code cleanup, fixed dash/HUD switch. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: fix console gtk_widget_path errors + +2012-04-02 Marco Trevisan (Treviño) + + Merging with panel-p-menu-view changes + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: removed the useless (at this point) HasOurWindowFocused... + +2012-04-02 Marco Trevisan (Treviño) + + PanelMenuView: make the possible methods const. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + WindowManager: GetGeometry* related methods set to const + + Plus removed some unneeded casts. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicators-view into panel-p-window-buttons. + +2012-04-02 Marco Trevisan (Treviño) + + PanelIndicatorsView: «don't use "using namespace indicator;" in a header file.» + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicators-view into panel-p-window-buttons. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicator-entry into panel-p-indicators-view. + +2012-04-02 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: make GetLabel const + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicators-view into panel-p-window-buttons. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicator-entry into panel-p-indicators-view. + +2012-04-02 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: don't use "using namespace ..." into the Header + + Also fixed some typo and the widget path errors + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-panel-view into panel-p-cleanup. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-core into panel-p-menu-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-manager into panel-p-core. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-tray into panel-p-window-manager. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-grab-area into panel-p-tray. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-window-buttons into panel-p-grab-area. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicators-view into panel-p-window-buttons. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-indicator-entry into panel-p-indicators-view. + +2012-04-02 Marco Trevisan (Treviño) + + Merged panel-p-style into panel-p-indicator-entry. + +2012-04-01 Marco Trevisan (Treviño) + + WindowButtons: ignore click events if not enabled. + +2012-03-31 Marco Trevisan (Treviño) + + Panel: Fixing the overlay name... + +2012-03-31 Marco Trevisan (Treviño) + + Ops... s/Overaly/Overlay/g ... + +2012-03-30 Marco Trevisan (Treviño) + + Merging with upstream + +2012-03-30 Marco Trevisan (Treviño) + + PanelMenuView: code cleanup, multimonitor bug fixes and misc improvements + + The layout system has been rewritten and now it works + natively without the workarounds we were using before, + fixed the panel paddings to match design specs; + Optimized the drawing operations, now the title texture is cached and + rebuilt only if really needed. + Fixed the panel title on Expo and Scale. + Improved the detection of the panel used to draw the app title on + multi-monitor (disabled otherwise), and the alt+tab/alt conflict. + Maximized windows list is re-populated on startup or when adding a new + screen. + +2012-03-30 Marco Trevisan (Treviño) + + Added misc changes needed to make the panel rock + +2012-03-30 Marco Trevisan (Treviño) + + WindowManager: implemented some methods to handle the window position/size. + +2012-03-30 Marco Trevisan (Treviño) + + PanelTray: code rewritten to use more C++ utilities + +2012-03-30 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: addded to unity namespace, rewritten the event handling + + The grabbing handle has been greatly improved + +2012-03-30 Marco Trevisan (Treviño) + + WindowButtons: code cleanup, more control to the buttons. + + rewritten using in a better way the subclass nux::Button + features, factorizing some code for each button into WindowButtons. + Also the handling of the controlled window is now done internally, + not by the PanelMenuView. + +2012-03-30 Marco Trevisan (Treviño) + + PanelIndicatorsView: some API cleanup, added more protected virtual members + +2012-03-30 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: + + code cleaned a lot to be more C++ conformant, and modified to be easily + extendible in the near future. Also fixed issues with the indicator entries + and Scale/Expo. Reduced some memory or CPU usage. + +2012-03-30 Marco Trevisan (Treviño) + + PanelIndicatorEntryView, PanelMenuView: set widget path types before name. + + This fixes a lot of warnings. + +2012-03-30 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: use the correct panel type to get the font + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: Set the WindowButtons padding as per design. + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: Only Scale is active for a window subset, show their app name. + + The desktop name otherwise. So on Super+S the desktop name is shown. + +2012-03-29 Marco Trevisan (Treviño) + + PluginAdapter: added IsScaleActiveForGroup to get if scale is running for a window subset + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: make the desktop name to draw in all the panels + +2012-03-29 Marco Trevisan (Treviño) + + Removing all the LIM stuff, it will be back soon! + +2012-03-29 Marco Trevisan (Treviño) + + PanelIndicatorsView: removed the "layout workaround", NUX likes us now! + + The menu/indicators layout can safely be kept and handled as the view's + layout, this saves us by doing unwanted workarounds and to just + manage its geometry. + + This also fixes an issue with multimonitor, that caused menus on + other monitors not to be clickable. + +2012-03-29 Marco Trevisan (Treviño) + + PanelView: remove useless methods + +2012-03-29 Marco Trevisan (Treviño) + + WindowButtons: don't be confused by different overlays + + Now switching from Dash to Hud and back works. See bug #963118 + +2012-03-29 Marco Trevisan (Treviño) + + unityshell: typo: s/showPanelFirstMenuKeyInitiate/showPanelFirstMenuKeyTerminate/ + +2012-03-29 Marco Trevisan (Treviño) + + Panel: s/Dash/Overlay/g + +2012-03-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: use Window type for windows. + +2012-03-29 Marco Trevisan (Treviño) + + PluginAdapter: window's can't be obscured by window in different screens. + + Checking the geometry, though. + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: use nux::Rect.IsInside where possible + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: when we don't control the active window, all clicks are over the grab area + +2012-03-29 Marco Trevisan (Treviño) + + PanelMenuView: don't draw anything on the panel located into a monitor that doesn't control the active window + +2012-03-20 Marco Trevisan (Treviño) + + PanelTray: remove the idle before destroying the window. + + Let's be paranoid! ;) + +2012-03-20 Marco Trevisan (Treviño) + + PanelTray: don't crash when unplugging a monitor. + +2012-03-20 Marco Trevisan (Treviño) + + PanelView: putting back some changes lost during merges + +2012-03-20 Marco Trevisan (Treviño) + + Merging with latest trunk. + +2012-03-20 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-19 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: don't sync our geometry if not focused + + This will make the unity-panel-service correctly handle + the keyboard navigation. + +2012-03-19 Marco Trevisan (Treviño) + + Merging with newer lp:~3v1n0/unity/lim + +2012-03-19 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/indicators-tests + +2012-03-19 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/dbus-indicators-proxy + +2012-03-19 Marco Trevisan (Treviño) + + Merging again with lp:~3v1n0/unity/indicators-p + +2012-03-10 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/indicators-p + +2012-03-10 Marco Trevisan (Treviño) + + Merging with changes in lp:~3v1n0/unity/lim + +2012-03-10 Marco Trevisan (Treviño) + + unityshell: listen also the launcher switcher signals + +2012-03-10 Marco Trevisan (Treviño) + + LauncherController: emit the right keynav signal + +2012-03-09 Marco Trevisan (Treviño) + + PluginAdapter: add some more spacing, to improve readability + +2012-03-09 Marco Trevisan (Treviño) + + PanelMenuView: put return types on the same line of the function name + +2012-03-09 Marco Trevisan (Treviño) + + PanelMenuView: add OnApplicationClosed function, to avoid casts + + Also added more controls to avoid un-hidden menus. + +2012-03-09 Marco Trevisan (Treviño) + + PanelMenuView: reset the _new_application if it points to an invalid application + +2012-03-09 Marco Trevisan (Treviño) + + PanelMenuView: add GetTopWindow method to get the top valid window, even if not in focus + + Added also utility functions such as GetBamfWindowForXid and IsValidWindow + to get a BamfView or to check if a window can be handled by us. + + We use the GetTopWindow to get the top view when an invalid one (an unity) + window is focused. + +2012-03-09 Marco Trevisan (Treviño) + + PanelMenuView: call the right function on launcher switcher end + +2012-03-08 Marco Trevisan (Treviño) + + PanelMenuView: also connect to the key-switcher ubus events + +2012-03-08 Marco Trevisan (Treviño) + + LauncherController: send the right ubus message depending on the key navigation type + +2012-03-08 Marco Trevisan (Treviño) + + PanelMenuView: show the selected icon name on the panel during key navigation + + Also, avoid to generate textures with empty labels, just nullify it + +2012-03-08 Marco Trevisan (Treviño) + + LauncherController: send UBus messages when the launcher selection has changed + +2012-03-06 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-02 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-02 Marco Trevisan (Treviño) + + PanelView: don't allow to open menus in an inactive PanelMenuView + +2012-03-02 Marco Trevisan (Treviño) + + PanelMenuView: take care of the workarea x when dragging down a window. + + Fixes the restored position in a multimonitor setup. + +2012-03-02 Marco Trevisan (Treviño) + + PanelMenuView: improve debugging strings + +2012-03-02 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: set invisible by default. + +2012-03-02 Marco Trevisan (Treviño) + + PanelMenuView: reduce the risk of getting an empty panel + +2012-03-02 Marco Trevisan (Treviño) + + PanelIndicatorAppmenuView: use area visibility as well. + + Disable the appmenu when not in use. + +2012-03-02 Marco Trevisan (Treviño) + + PanelMenuView: use PanelIndicatorsView as base for introspection data + +2012-03-02 Marco Trevisan (Treviño) + + Panel: add more debug introspection informations + +2012-03-01 Marco Trevisan (Treviño) + + PanelIndicatorsView: make each menu entry to use the most space it really can + + When setting the maximium width for the entries, we shouold care of the + current sizes. So basically, if an entry doesn't need to be resized, + we can just take its width and remove it from the maximum space we have, + then the space that the other entries can use, is computed using the + remaining space. + + This improves a lot the entries collapsing, and make sure that we always + use all the horizontal space that we have. + +2012-03-01 Marco Trevisan (Treviño) + + PanelIndicatorEntryView: improve the drawing of collapsed menus + + Consider the right_marging as well. + +2012-02-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-02-26 Marco Trevisan (Treviño) + + PanelTray: update whitelist value on runtime. + +2012-02-26 Marco Trevisan (Treviño) + + PanelTray: main code cleanup, hopefully fix crashes + +2012-02-25 Marco Trevisan (Treviño) + + Pushing back removed changes + +2012-02-25 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/lim + +2012-02-25 Marco Trevisan (Treviño) + + Merging trunk + +2012-02-25 Marco Trevisan (Treviño) + + Merging trunk + +2012-02-25 Marco Trevisan (Treviño) + + WindowButtons: manually manage the clicks on the buttons to be more Fitts conformant + + The window buttons are now put into the layout to manage their position + automatically, but we redirect the mouse events over them + to be more conformant to the Fitt's law. + +2012-02-25 Marco Trevisan (Treviño) + + WindowButtons: make the buttons more Fitt's law conformant. + +2012-02-25 Marco Trevisan (Treviño) + + WindowButton: add UpdateSize function to define the maximum button size + +2012-02-25 Marco Trevisan (Treviño) + + WindowButtons: put win-buttons into the unity namespace. + +2012-02-25 Marco Trevisan (Treviño) + + PanelTitlebarGrabAreaView: return gboolean FALSE instead of bool false on timeout + +2012-04-06 Daniel d'Andrada + + Fix pinch gesture.. Fixes: https://bugs.launchpad.net/bugs/969554. Approved by Thomi Richards. + +2012-04-04 Daniel d'Andrada + + Unit test for maximizing a window with a pinch gesture + + Tests fix for bug lp:969554 + +2012-03-30 Daniel d'Andrada + + unityshell: Fix pinch gesture radius usage + + There was a change in the maning of a pinch radius. + Before it was expressed in device units, whose resolution + can vary wildly among different device types. + + Pinch radius is now expressed as a ratio between the initial radius + and the current radius. + +2012-04-05 Daniel d'Andrada + + Fix the three-finger move for unity.. Fixes: https://bugs.launchpad.net/bugs/940612. Approved by Tim Penhey. + +2012-04-04 Daniel d'Andrada + + Unit test for moving a window with a 3-finger's drag gesture. + + Tests fix for bug lp:940612 + +2012-04-04 Daniel d'Andrada + + Adding infrastructure for testing plugins/unityshell/GestureEngine class + + Creates test-gesture-engine test along with necessary mocks + +2012-04-03 Daniel d'Andrada + + Remove unused include from GestureEngine.h + +2012-04-03 Daniel d'Andrada + + test/CmakeLists - link libraries against targets individually + + There may be targets that want to link against a different set of libraries + than the one offered by link_libraries(). + Besides link_libraries() has been deprecated in favor of targe_link_libraries() + +2012-03-30 Daniel d'Andrada + + unityshell: gesture focus is a float, not an int + +2012-03-30 Daniel d'Andrada + + unityshell gestures: Use hit-test to find window affected by 3-touch drag + + Instead of climbing up the window hierarchy with XQueryTree. That will improve + performance. + + The root cause of lp:940612 is that after the re-architecture of the UTouch stack + the child_window_id event attribute is no longer being filled. Even though + UTouch stack should have it fixed, the change made by this patch is still + an improvement on its own right. Besides, in the new architecture, UTouch might + have trouble filling this attribute in the same way as before. + +2012-04-05 Kevin DuBois + + Ensure that an animation always takes place after the Shortcut menu is shown + fixes: https://bugs.launchpad.net/unity/+bug/924636. Fixes: https://bugs.launchpad.net/bugs/924636. Approved by Marco Trevisan (Treviño). + +2012-04-05 Kevin DuBois + + update manual tests to test for this incorrect rendering scenario + +2012-04-05 Kevin DuBois + + Correct issue where shortcut animation was not taking place while mousing over launcher + +2012-04-05 Marco Trevisan (Treviño) + + autopilot, test_launcher: fix error due to missing multiply_scenarios import. Fixes: . Approved by Tim Penhey. + +2012-04-06 Marco Trevisan (Treviño) + + Fix multiply scenarios import + +2012-04-05 Jay Taoko + + * Fix a rendering call for systems with no GLSL support.. Fixes: . Approved by Jason Smith. + +2012-04-05 Jay Taoko + + * Use proper rendering call for system with no GLSL support. + * Removed a printf. + +2012-04-05 Marco Trevisan (Treviño) + + Panel style changes.. Fixes: . Approved by Tim Penhey. + +2012-04-02 Marco Trevisan (Treviño) + + PanelStyle: use &glib::String instead of glib::String.AsOutParam. + +2012-03-30 Marco Trevisan (Treviño) + + PanelStyle: general cleanup, move to UnityCore glib:: utilities + + It can be used now to check all the panel related settings, including + fonts and DPI. Emitting the changed signal when they get changed (so now + when changing the title font, it gets updated immediately). + Added better support for HighContrast themes and fallback buttons. + +2012-04-05 Alex Launi + + Refactors the launcher tests. Adds a more logical organization, and removes duplicated code.. Fixes: . Approved by Alex Launi, Marco Trevisan (Treviño). + +2012-04-05 Alex Launi + + Fix merge conflicts + +2012-03-22 Alex Launi + + merge trunk + +2012-03-15 Alex Launi + + remove 'file' that was added for no reason + +2012-03-15 Alex Launi + + refactor launcher reveal tests + +2012-03-15 Alex Launi + + refactor launcher keynav tests + +2012-03-15 Alex Launi + + refactor launcher shortcut tests + +2012-03-15 Alex Launi + + refactor switcher tests + +2012-04-05 Andrea Cimitan + + Very subtle card view background. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-04-05 Andrea Cimitan + + Very subtle card view background + +2012-04-05 Andrea Cimitan + + Removes shadow from the decoration assets.. Fixes: . Approved by Andrea Azzarone, Marco Trevisan (Treviño). + +2012-04-05 Andrea Cimitan + + Fixes horizontal parity + +2012-04-05 Andrea Cimitan + + Should fix parity at topright + +2012-04-05 Andrea Cimitan + + New dash decoration assets + +2012-04-05 Andrea Cimitan + + Less opacity on both line and background for search bar. Fixes: . Approved by Andrea Azzarone, Marco Trevisan (Treviño). + +2012-04-05 Andrea Cimitan + + Latest refinements on search bar from design: less opacity on both line and background + +2012-04-05 Jay Taoko + + * Fix: rendering of the Dash corners (top-right, bottom-left, bottom-right).. Fixes: https://bugs.launchpad.net/bugs/839476. Approved by Mirco Müller, Andrea Cimitan. + +2012-04-05 Jay Taoko + + * Fixed rendering offset error. + +2012-04-05 Jay Taoko + + * Merge + +2012-04-05 Andrea Cimitan + + Draw nicer panel/dash launcher/dash separators, following mockups + +2012-04-05 Jay Taoko + + * Merged with Unity trunk. + +2012-04-05 Jay Taoko + + * Fixed shader compilation. + +2012-04-05 Jay Taoko + + * Rendering improvements. + * Removing the inverted textures as they are no longer necessary. + +2012-04-04 Jay Taoko + + * Fixed rendering of the Dash corners. + +2012-03-27 Mirco Müller + + Re-merged with trunk + +2012-02-24 Jay Taoko + + + * Fixed blending issues when using QRP_TexMaskTexAlpha. + * A weird problems remains on the bottom left corner. + * Shine and other effects remain to be applied on the corners. + +2012-02-24 Mirco Müller + + Only use the alpha-channel in the mask-textures. Create the correct blurred texture-parts for the corners. Apply it all. + +2012-02-21 Mirco Müller + + Added mask-textures for the three color-texture making up the corners of the dash/hud decoration + +2012-04-05 Andrea Azzarone + + Use gtk_accelerator_get_label to get a translatable key binding.. Fixes: https://bugs.launchpad.net/bugs/971332. Approved by Gord Allott. + +2012-04-04 Andrea Azzarone + + Fix. + +2012-04-04 Andrea Azzarone + + Fix. + +2012-04-03 Andrea Azzarone + + Fix style issue. + +2012-04-03 Andrea Azzarone + + Fix bug #971332. + +2012-04-05 Koichi Akabe + + Ensures hud ignores key presses once ibus is active. Fixes: https://bugs.launchpad.net/bugs/957927, https://bugs.launchpad.net/bugs/964760, https://bugs.launchpad.net/bugs/973344. Approved by Brandon Schaefer, Gord Allott. + +2012-04-04 Koichi Akabe + + change to check im_preedit instead of im_active on dash (for lp:973344) + +2012-04-03 Koichi Akabe + + fix typo on autopilot test_ibus.py + remove for loop on test_ignore_key_events_on_hud + +2012-04-03 Koichi Akabe + + merge with trunk to solve conflicts + +2012-03-23 Koichi Akabe + + merge from trunk to solve conflicts + +2012-03-23 Koichi Akabe + + add autopilot test for ignoring key events while ibus is active + +2012-03-19 Koichi Akabe + + ignore tab key on dash when ibus is active + +2012-03-18 Koichi Akabe + + fix behaviour when unexpected key (left/right tab) is pressed on hud + +2012-03-17 Koichi Akabe + + add im_preedit property to get state of ibus + ignore up/down key while ibus is active + remove search_activated.emit() on HudView.cpp because it is te reason why HUD executes items twice + move query_activated.emit() to search_bar_->activated + +2012-04-05 Thomi Richards + + Fixed failing assertion in the Hud.. Fixes: . Approved by Gord Allott. + +2012-04-05 Thomi Richards + + Don't call g_variant_equal in the Hud when there's a chance that one of the variants can be NULL. + +2012-04-05 Gord Allott + + fixes widescreen icons being too small, makes them the correct aspect ratio and size. Fixes: https://bugs.launchpad.net/bugs/878015. Approved by Mirco Müller. + +2012-04-05 Gord Allott + + fix wrongly aligned icons + +2012-04-05 Gord Allott + + Fixes a long standing slight visual bug in the dash, widescreen icons now render correctly + +2012-04-05 Jason Smith + + * Fix for bug #839480 + * Fix rendering of the Dash, Launcher and Panel when "NO_BLUR" is selected in CCSM + * Added support to get a none blurred region of the display from BackgroundEffectHelper. Fixes: https://bugs.launchpad.net/bugs/839480, https://bugs.launchpad.net/bugs/941066. Approved by Gord Allott, Brandon Schaefer, Jason Smith. + +2012-04-04 Brandon Schaefer + + * Merged trunk, fixed conflict + +2012-04-04 Brandon Schaefer + + * Change dash_is_open_ to use the launcher_controller->IsOverlayOpen() + * Removed some commented out lines of code + +2012-04-02 Jay Taoko + + * Merged with Unity Trunk. + +2012-03-30 Jason Smith + + fix detection of when to paint panel background + +2012-03-28 Jay Taoko + + * Fix update of static blur case + +2012-03-26 Jay Taoko + + * Check that the maximized window is not a native window. + +2012-03-26 Jay Taoko + + * Fixes + +2012-03-24 Jay Taoko + + * Update Panel texture only when necessary. + +2012-03-23 Jay Taoko + + * Added support for panel rendering. + +2012-03-23 Jay Taoko + + * Fixing Panel background + +2012-03-23 Jay Taoko + + * Fix for bug #839480 + +2012-03-23 Jay Taoko + + * Cleanup + +2012-03-23 Jay Taoko + + * Fixes the rendering of the dash when the "No Blur" option is selected in CCSM. + +2012-04-05 Mirco Müller + + Implement new card view design. Fixes: https://bugs.launchpad.net/bugs/901164. Approved by Andrea Cimitan. + +2012-04-05 Mirco Müller + + New input from Design... tiles background tint-color is meant to be like the one used on the lens-nav-bar + +2012-04-03 Mirco Müller + + Work around a bug in QRP_QuadWireframe() not drawing the bottom-left-most pixel in the black outline around the icon + +2012-04-03 Mirco Müller + + Fixing the horizontal tile renderer (aka card-view) to comply with the design-specs + +2012-04-05 Gord Allott + + Fixes a hud translation issue, can't have const std::strings in an anonymous namespace.. Fixes: . Approved by Michal Hruby. + +2012-04-05 Gord Allott + + merged with trunk fixed conflicts + +2012-04-05 Gord Allott + + Fixed translation error in hud, "Type your command" is now properly translatable + +2012-04-05 Tim Penhey + + Allow Unity to correctly respond to a non-modifier key-binding for "show hud".. Fixes: https://bugs.launchpad.net/bugs/969256. Approved by Daniel van Vugt, Thomi Richards. + +2012-04-05 Tim Penhey + + Fix the docstring duplication. + +2012-04-05 Tim Penhey + + Use the result of ShowHud. + +2012-04-05 Tim Penhey + + Merge trunk. + +2012-04-05 Tim Penhey + + Autopilot tests. + +2012-04-05 Tim Penhey + + Allow hud initiate to be bound to a non-modifier key. + +2012-04-04 Jason Smith + + Implement sticky edge behavior as requested by design. Add EdgeBarrierController class to handle complexity of edge barriers.. Fixes: . Approved by Thomi Richards. + +2012-04-04 Jason Smith + + update edge barrier class to use sticter types + +2012-04-04 Jason Smith + + fix review issues + +2012-04-04 Jason Smith + + fix doc strings + +2012-04-04 Jason Smith + + add autopilot tests to test new behaviors + +2012-04-04 Jason Smith + + dont capture mouse when not hiding and sticky edges is off + +2012-04-03 Jason Smith + + implement edge barrier behavior as updated in spec + +2012-04-04 Thomi Richards + + Only desaturate icons when an overlay is shown if the mouse is not over the launcher.. Fixes: https://bugs.launchpad.net/bugs/973063. Approved by Jason Smith. + +2012-04-05 Thomi Richards + + Added a test for when you mose over after the dash is opened. + +2012-04-05 Thomi Richards + + Fixed bug, test passes. + +2012-04-05 Thomi Richards + + Have failing test. + +2012-04-05 Thomi Richards + + Merged trunk. + +2012-04-04 Thomi Richards + + Force launcher icons to saturate when keynav starts.. Fixes: https://bugs.launchpad.net/bugs/913569. Approved by Jason Smith. + +2012-04-04 Thomi Richards + + Fixed bug, test passes. + +2012-04-04 Thomi Richards + + Have failing test. Also fixed scenario generation for launcher tests when we're running a single monitor only. + +2012-04-04 Michal Hruby + + Ensure that the spinner is shown even for empty searches. Fixes: https://bugs.launchpad.net/bugs/965492. Approved by Gord Allott. + +2012-04-04 Michal Hruby + + Use string::empty method + +2012-04-04 Michal Hruby + + Ensure that the spinner is shown even for empty searches + +2012-04-04 Albert Astals + + Clear queries_ in HudImpl::UpdateQueryCallback + + As suggested by Ryan Lortie in https://bugs.launchpad.net/indicator-appmenu/+bug/965299 + . Fixes: https://bugs.launchpad.net/bugs/965299. Approved by Gord Allott, Thomi Richards. + +2012-04-03 Albert Astals + + Clear queries_ in HudImpl::UpdateQueryCallback + + As suggested by Ryan Lortie in https://bugs.launchpad.net/indicator-appmenu/+bug/965299 + +2012-04-03 Thomi Richards + + Make Ctrl+Tab from commands lens work correctly.. Fixes: https://bugs.launchpad.net/bugs/971850. Approved by Tim Penhey. + +2012-04-03 Thomi Richards + + Added comment. + +2012-04-03 Thomi Richards + + Have fix, tests pass. + +2012-04-03 Thomi Richards + + Have failing test. + +2012-04-03 Benjamin Kerensa + + Update tooltip in ccsm for "Show Desktop Icon".. Fixes: https://bugs.launchpad.net/bugs/934526. Approved by Marco Biscaro, Fitoschido. + +2012-03-23 Benjamin Kerensa + + Actually Fixed Now + +2012-03-22 Benjamin Kerensa + + Fixed Typo LP: #934526 + +2012-04-03 Brandon Schaefer + + Fixes the pinyin pop up box disappearing in the hud.. Fixes: https://bugs.launchpad.net/bugs/968777. Approved by Tim Penhey. + +2012-04-02 Brandon Schaefer + + * More fixes to the ap test + +2012-04-02 Brandon Schaefer + + * Merged trunk, fixed conflict + +2012-04-02 Brandon Schaefer + + * Fixed ap test + +2012-04-01 Brandon Schaefer + + * Adds auotpilot test + +2012-04-01 Brandon Schaefer + + * merged trunk + +2012-03-29 Brandon Schaefer + + * Fixes so when go from Hud to the Dash to make sure you close + the Hud BEFORE the dash opens + +2012-04-03 Thomi Richards + + Fix several failing assertions in gtk, glib, and dbusmenu.. Fixes: . Approved by Marco Trevisan (Treviño). + +2012-04-04 Thomi Richards + + LauncherIcon now stores unity icon theme inside a glib::Object wrapper. + +2012-04-03 Thomi Richards + + Fixed two places in BamfLauncherIcon where we were sending null pointers into libdbusmenu, which would cause assertions to fail. + +2012-04-03 Thomi Richards + + Fixed failing gtk assert in PanelIndicatorEntryView. + +2012-04-03 Thomi Richards + + Fixed a failing gtk assert in PanelMenuView. + +2012-04-03 Thomi Richards + + Fixed a glib assertion in the LauncherIcon - we were trying to unref a null ptr. + +2012-04-03 Andrea Azzarone + + Fix a crash in unity::launcher::DeviceLauncherIcon::ShowNotification.. Fixes: https://bugs.launchpad.net/bugs/971345. Approved by Tim Penhey. + +2012-04-03 Andrea Azzarone + + Should fix a crash bug #971345. + +2012-04-03 Marco Trevisan (Treviño) + + HudController: use the top-most valid window in the stack to fetch the icon, if an invalid window is focused. Fixes: https://bugs.launchpad.net/bugs/931548, https://bugs.launchpad.net/bugs/932371, https://bugs.launchpad.net/bugs/961161. Approved by Thomi Richards, John Lea. + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, test_hud: removed the unneeded sleep on tests base + +2012-04-03 Marco Trevisan (Treviño) + + Autopilot: test_showdesktop, remove the hardcoded 'Control+Alt+d' keybinding + +2012-04-03 Marco Trevisan (Treviño) + + autopilot: test_hud, test_switcher: use the new start_app return value + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, make start_app to return the ran BamfApplication instance + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, test_hud: use self.dash.ensure_visible() + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, test_hud: Check if the BFB icon is shown on empty desktop + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, keybindings: added the window/show_desktop keybinding + +2012-04-03 Marco Trevisan (Treviño) + + HudLauncherIcon: fix typo + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, test_hud: Move to the new icon methods + +2012-04-03 Marco Trevisan (Treviño) + + autopilot, hud: add icon property to get the current HUD icon + +2012-04-03 Marco Trevisan (Treviño) + + HudIcon: rename it as HudEmbeddedIcon for better AP integration + +2012-04-03 Marco Trevisan (Treviño) + + Merging with trunk + +2012-04-01 Marco Trevisan (Treviño) + + autpilot, test_hud: added test for Dash/HUD interaction and icon changes + +2012-04-01 Marco Trevisan (Treviño) + + HudController: use the ubuntu icon as fallback if we don't have a valid window focused + +2012-04-01 Marco Trevisan (Treviño) + + HudLauncherIcon: fallback to the BFB icon if the name is empty. + +2012-04-01 Marco Trevisan (Treviño) + + HudController: reset the focused_app_icon_ value on invalid focused view + +2012-03-31 Marco Trevisan (Treviño) + + HudController: use the monitor index = -1 to get the windows of all monitors + + Added also some comments + +2012-03-31 Marco Trevisan (Treviño) + + HudController: Check the top window if the active one is an unity window + + If the top window is an unity window, we must check the last valid + window in the stack, otherwise switching from the Dash to the HUD won't + work. + +2012-03-31 Marco Trevisan (Treviño) + + HudController: don't change the Hud Icon if unity is the active application + + This fixes the bad icon isse that we have when switching from + HUD to Dash. + +2012-04-03 Michal Hruby + + Make sure we don't display the no-results-hint if we do have results. Fixes: https://bugs.launchpad.net/bugs/971430. Approved by Gord Allott, Brandon Schaefer. + +2012-04-02 Michal Hruby + + Add a manual test + +2012-04-02 Michal Hruby + + Make sure we don't display the no-results-hint if we do have results + +2012-04-03 Thomi Richards + + Fixed a failing assert in the TrashLauncherIcon.. Fixes: . Approved by Tim Penhey. + +2012-04-03 Thomi Richards + + send glib::Error to logging framework directly. + +2012-04-03 Thomi Richards + + Fixed after Tim's code review. + +2012-04-03 Thomi Richards + + The TrashLauncherIcon would cause glib to assert if the user is running a filesystem (such as gvfs) that does not support the Trash:/// uri. This commit makes it log an error message instead. Also fixed whitespace issues. + +2012-04-02 Thomi Richards + + Prevents launcher autopilot tests from crashing.. Fixes: . Approved by Tim Penhey. + +2012-04-03 Thomi Richards + + FIxed launcher autopilot tests. + +2012-04-02 Thomi Richards + + Made autopilot code mostly PEP8 compliant.. Fixes: . Approved by Tim Penhey. + +2012-04-03 Thomi Richards + + Various PEP8 fixes for autopilot code. + +2012-04-02 Gord Allott + + Corrects a callback to use the established variant for UBUS_OVERLAY_SHOWN. Fixes: . Approved by Michal Hruby. + +2012-04-02 Gord Allott + + fix build + +2012-04-02 Gord Allott + + fixed conflict with trunk + +2012-03-29 Gord Allott + + corrects a callback to use the establised varient for UBUS_OVERLAY_SHOWN + +2012-04-02 Michal Hruby + + Make sure applications can be started from the HomeLens as soon as we get results from apps lens. Fixes: https://bugs.launchpad.net/bugs/966417. Approved by Gord Allott. + +2012-04-02 Michal Hruby + + Act on review comments + +2012-03-30 Michal Hruby + + Add an AP test for HomeLens + +2012-03-30 Michal Hruby + + Make sure applications can be started as soon as we get results from apps lens + +2012-04-01 Jason Smith + + Repaint the launcher on resume from suspend.. Fixes: https://bugs.launchpad.net/bugs/915265. Approved by Tim Penhey. + +2012-03-29 Jason Smith + + migrate to more acceptable and generic way to access resuming signals + +2012-03-29 Jason Smith + + merge trunk + +2012-03-04 Jason Smith + + fix resume from suspend corruption on certain nvidia gpu's + +2012-04-01 Thomi Richards + + Fix autopilot tests that error (instead of passing or failing).. Fixes: . Approved by Tim Penhey. + +2012-04-02 Thomi Richards + + Fixed an error in the autopilot keybindings module that was causing anumber of tests to error. Also fixed the software center launcher icon test. + +2012-04-01 Gord Allott + + Reduce stress on hud service by waiting 100ms prior to sending request.. Fixes: https://bugs.launchpad.net/bugs/948820. Approved by Tim Penhey. + +2012-03-29 Gord Allott + + added fixme + +2012-03-28 Gord Allott + + waits 100ms before asking for another search + +2012-04-01 Marco Trevisan (Treviño) + + Hud: fixed the paddings and geometries, remove the icon glitches + + I've fixed all the paddings and geometries to match design (and the dash, then), plus I've fixed a size mismatch that caused some drawing glitches of the icon. + + HUD before the fix: http://i.imgur.com/b7BO0.png | http://i.imgur.com/9vpmv.png + HUD after the fix: http://i.imgur.com/wDxPO.png | http://i.imgur.com/kSLch.png. Fixes: https://bugs.launchpad.net/bugs/931406, https://bugs.launchpad.net/bugs/964061. Approved by Andrea Cimitan, Tim Penhey. + +2012-04-01 Marco Trevisan (Treviño) + + HudView: remove unneeded includes + +2012-04-01 Marco Trevisan (Treviño) + + HudView, HudIcon: removing unneeded includes + +2012-04-01 Marco Trevisan (Treviño) + + HudIcon: add private members + +2012-04-01 Marco Trevisan (Treviño) + + HudIcon: simplify the constructor + +2012-04-01 Marco Trevisan (Treviño) + + IconTexture: don't try to load 0 sized icons. + + Otherwise the class won't work even changing the size value... + +2012-03-31 Marco Trevisan (Treviño) + + HudView: Fixed the HUD padding, removed some magic numbers. + + The Hud view padding didn't match the dash padding when the + launcher not in the auto-hide mode. + + So, fixed all the spaces, removed some spacelayouts and using pure padding. + Removed the icon layout, since it is not needed anymore. + +2012-03-31 Marco Trevisan (Treviño) + + HudIcon: Don't use a different icon renderer size, than the one provided. + + This fixes some icon drawing issues that we have with the embedded HUD. + Plus remove the unneeded constructor, and set the tile size relative + to the icon size. + + Reducing the minimum widh to the default launcher icon size. + +2012-04-01 Marco Trevisan (Treviño) + + LauncherEntryRemote: added tests for the entry remote class. Fixes: . Approved by Thomi Richards. + +2012-03-31 Marco Trevisan (Treviño) + + Merged with latest lp:~3v1n0/unity/launcher-remote-model-c++ + +2012-03-28 Marco Trevisan (Treviño) + + tests: added a test suite for LauncherEntryRemote + +2012-04-01 Marco Trevisan (Treviño) + + LauncherRemoteModel rewritten to be more C++ friendly. Fixes: . Approved by Michal Hruby, Thomi Richards. + +2012-03-31 Marco Trevisan (Treviño) + + Merging with trunk. + +2012-03-31 Marco Trevisan (Treviño) + + tests: test_desktop_utilities added test for TestGetDataDirectory + +2012-03-30 Marco Trevisan (Treviño) + + tests, added test for DesktopUtilities functions + +2012-03-30 Marco Trevisan (Treviño) + + FavoriteStoreGSettings, FavoriteStorePrivate: Move to DesktopUtilities::GetDesktopID + + And tests disabled + +2012-03-30 Marco Trevisan (Treviño) + + BamfLauncherIcon, LauncherEntryRemote: move to DesktopUtilities::GetDesktopID + +2012-03-30 Marco Trevisan (Treviño) + + UnityCore, added the DesktopUtilities class + + Inside there are static members to get the User and System data directories + Plus an utility to get the desktop ID from a desktop path for the given + data directories. + +2012-03-30 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-29 Marco Trevisan (Treviño) + + LauncherEntryRemote: moving out the useless .get() from Ptr check... + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel: more code cleanup... + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel: use nullptr and move to more nice names for cb functions + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel: use glib::String to parse the removed parameters + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel:: use smart pointer for emitting signals + + Code updated against this. + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel, more LauncherEntryRemote::Ptr usage + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemote: move to shared_ptr + + Using the simpler std::shared_ptr ensures all the functionalities and more clean code. + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemoteModel: rewritten to be more C++ friendly + +2012-03-30 Brandon Schaefer + + * Adds CJK autopilot test for the Hud. Fixes: . Approved by Thomi Richards. + +2012-03-30 Brandon Schaefer + + * Merged with trunk, and fixed an ap error I commited + +2012-03-29 Brandon Schaefer + + * Fixed ap problems! + +2012-03-29 Brandon Schaefer + + * Re-worked the hud emulator and added a Hud class + * Added CJK test for the Hud + +2012-03-30 Marco Trevisan (Treviño) + + LauncherRemoteEntry: code rewritten to be more C++ friendly, and moved into unity namespace. Fixes: . Approved by Thomi Richards. + +2012-03-30 Marco Trevisan (Treviño) + + LauncherEntryRemote: Added missing ';'... Ops! + +2012-03-29 Marco Trevisan (Treviño) + + LauncherEntryRemote: glib::Variant explained + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemote: Quicklist returns the glib::Object + + Plus both accepts variant strings and objects paths for QL. + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemote: making some methods const + +2012-03-28 Marco Trevisan (Treviño) + + LauncherEntryRemote: More C++ friendly and moved into unity namespace + +2012-03-30 Andrea Azzarone + + Inserting items into launcher makes unnecessary animations on other monitors. Fixes: https://bugs.launchpad.net/bugs/925021. Approved by Marco Trevisan (Treviño). + +2012-03-26 Andrea Azzarone + + Fix bug #925021 + +2012-03-26 Andrea Azzarone + + Update prerequiste branch. + +2012-03-26 Andrea Azzarone + + Merge prerequiste branch. + +2012-03-30 Marco Trevisan (Treviño) + + LauncherIcon: use std::string for RemoteUri. Fixes: . Approved by Thomi Richards. + +2012-03-28 Marco Trevisan (Treviño) + + LauncherIcon: use std::string for RemoteUri + +2012-03-30 Michal Hruby + + Fix warnings coming from HomeLens' filters merger. Fixes: . Approved by Mikkel Kamstrup Erlandsen. + +2012-03-30 Michal Hruby + + Add a couple of comments + +2012-03-29 Michal Hruby + + Fix warnings coming from HomeLens' filters merger + +2012-03-30 Brandon Schaefer + + Fixes unityshell.cpp not taking into account of the hud overlay being active.. Fixes: . Approved by Thomi Richards. + +2012-03-29 Brandon Schaefer + + * merged trunk, conficts resolved + +2012-03-27 Brandon Schaefer + + * removed new line! + +2012-03-27 Brandon Schaefer + + * Autopilot test fixes + +2012-03-27 Brandon Schaefer + + * Added autopilot test + +2012-03-27 Brandon Schaefer + + * Exposed HideDash(), so we can correctly exit from the dash, if the hud is about to show + +2012-03-26 Brandon Schaefer + + * Fixed an uninitialized which could cause a crash. Though very unlikley. + +2012-03-26 Brandon Schaefer + + * Added a new IsOverlayOpen, which checks if any overlay exist on any moniter + +2012-03-26 Brandon Schaefer + + * Changed unityshell to use the launcher IsOverlayOpen() as the hud was getting + ignored when it shoudn't + * Autopilot test coming! + +2012-03-29 Marco Trevisan (Treviño) + + LauncherIcon_ added MonitorVisibility property and subclass SingleMonitorLauncherIcon + + Thanks to that, and making HudLauncherIcon to subclass it, we have that in case of locked launcher: + - BFB should be shown in all the monitors where there is not an HUD icon opened. + - HUD icon should only be shown in the monitor where the HUD is actually opened. + + Plus, don't desaturate the icons placed in a launcher that has no an overalay attached.. Fixes: . Approved by Andrea Azzarone. + +2012-03-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-28 Marco Trevisan (Treviño) + + autopilot, test_hud: updated against the new support for monitor-visible icons + +2012-03-28 Marco Trevisan (Treviño) + + autopilot, launcher: added method to get the icons for each monitor + +2012-03-28 Marco Trevisan (Treviño) + + autopilot, icons: add monitor visibility related methods + +2012-03-28 Marco Trevisan (Treviño) + + HudLauncherIcon: always set it invisible on autohide setting changed + +2012-03-28 Marco Trevisan (Treviño) + + Merging again with: lp:~3v1n0/unity/hud-lock-out-monitors-tests + +2012-03-27 Marco Trevisan (Treviño) + + LauncherIcon: add monitor visibility informations to the debug introspection + +2012-03-27 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/hud-lock-out-monitors-tests + +2012-03-27 Marco Trevisan (Treviño) + + test: added SingleMonitorLauncherIcon unit-test + +2012-03-26 Marco Trevisan (Treviño) + + MockLauncherIcon: implemented missing methods + +2012-03-26 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/hud-lock-out-monitors-tests + +2012-03-26 Marco Trevisan (Treviño) + + Launcher: only desaturate icons on the monitor where there's an overlay opened + +2012-03-26 Marco Trevisan (Treviño) + + Launcher: don't show icons invisible on the launcher's monitor + +2012-03-26 Marco Trevisan (Treviño) + + HudLauncherIcon: subclass SingleMonitorLauncherIcon, show only on target monitor + +2012-03-26 Marco Trevisan (Treviño) + + BFBLauncherIcon: hide the BFB icon only on the monitor where there's an HUD open + +2012-03-26 Marco Trevisan (Treviño) + + SingleMonitorLauncherIcon: new class to control icons visible only in one monitor + +2012-03-26 Marco Trevisan (Treviño) + + AbstractLauncherIcon: add support for icons visible only on selected monitors + +2012-03-29 Andrea Azzarone + + Increase dash height.. Fixes: . Approved by Andrea Cimitan. + +2012-03-29 Andrea Azzarone + + Increse the dash height. + +2012-03-29 Andrea Azzarone + + Merge prerequiste branch. + +2012-03-29 Andrea Azzarone + + Makes the dash search entry horizontally extensible.. Fixes: https://bugs.launchpad.net/bugs/841907. Approved by Marco Trevisan (Treviño), Andrea Cimitan. + +2012-03-27 Andrea Azzarone + + Add 10px border between the search entry text and the right border. + +2012-03-27 Andrea Azzarone + + Fix bug #841907. + +2012-03-29 Thomi Richards + + Fixed a memory leak in the file-system lens - we were leaking LensFileData objects.. Fixes: . Approved by Jason Smith, Marco Trevisan (Treviño). + +2012-03-29 Thomi Richards + + Filesystem lens no longer leaks LensFileData objects. + +2012-03-29 Marco Trevisan (Treviño) + + Added HUD_TYPE for Icons, this allow to draw the active triangle on that only (and not on BFB).. Fixes: https://bugs.launchpad.net/bugs/961230. Approved by Gord Allott. + +2012-03-29 Marco Trevisan (Treviño) + + Fixing previous merge... + +2012-03-29 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-26 Marco Trevisan (Treviño) + + Merging with lp:~3v1n0/unity/hud-lock-out-monitors-tests changes + +2012-03-25 Marco Trevisan (Treviño) + + autopilot: test_hudm, added active icon status check + +2012-03-25 Marco Trevisan (Treviño) + + AbstractLauncherIcon: Add TYPE_HUD icon type + + This fixes the visual issue causing that both the BFB and HUD to draw + a right triangle. + +2012-03-29 Marco Trevisan (Treviño) + + HudController: Fixed geometries for single-launcher mode. + + And added tests for multimonitor in HUD, with lock-out support.. Fixes: https://bugs.launchpad.net/bugs/963577. Approved by Thomi Richards. + +2012-03-28 Marco Trevisan (Treviño) + + autopilot, updated changes following thomi's review + +2012-03-28 Marco Trevisan (Treviño) + + BamfLauncherIcon: add GetDesktopID function to perform the common operations + +2012-03-28 Marco Trevisan (Treviño) + + autopliot, test_hud: check that the HUD icon is not desaturated + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, use start_app with one more locale parameter, more than start_app_c_locale + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, test_showdesktop: be more locale friendly + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, test_switcher: use BAMF application names, to work with different locales + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, switcher: update against new introspection values + +2012-03-27 Marco Trevisan (Treviño) + + autopilot: allow to launch applications with C locale + + And use it for gedit HUD test + +2012-03-27 Marco Trevisan (Treviño) + + BamfLauncherIcon: use GVariantBuilder to build the xids array + +2012-03-27 Marco Trevisan (Treviño) + + BamfLauncherIcon: g_variant_new_array can compute the array size automatically + +2012-03-27 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, test_hud: test splitted in multiple parts, use multiply_scenarios + +2012-03-27 Marco Trevisan (Treviño) + + autopilot: default tests, use C locale to launch applications. + +2012-03-27 Marco Trevisan (Treviño) + + autopilot, hud: Removed unneeded print + +2012-03-26 Marco Trevisan (Treviño) + + autopilot: test_hud some cleanups + +2012-03-26 Marco Trevisan (Treviño) + + autopilot, launcher: allow to get the bfb launcher icon from LauncherModel + +2012-03-26 Marco Trevisan (Treviño) + + autopilot, X11: fix typo... actually use rect when checking for monitor geo! + +2012-03-26 Marco Trevisan (Treviño) + + HudController: make the HUD relayout if the monitor has changed + +2012-03-26 Marco Trevisan (Treviño) + + HudView: no need to remove the introspection child on destruction + +2012-03-26 Marco Trevisan (Treviño) + + autopilot, hud: add test to check if the hud icon shows the proper emblem + +2012-03-26 Marco Trevisan (Treviño) + + autopilot, test_hud: updated the tests against the new embedded icon introspection + +2012-03-26 Marco Trevisan (Treviño) + + HudView: set the icon as introspectable child. + + And add and remove it when needed. + +2012-03-26 Marco Trevisan (Treviño) + + HudIcon: make it Introspectable, and use the new IconTexture API + +2012-03-26 Marco Trevisan (Treviño) + + IconTexture: move to std::string + +2012-03-26 Marco Trevisan (Treviño) + + SimpleLauncherIcon: add the icon_name to the introspection properties + +2012-03-26 Marco Trevisan (Treviño) + + BamfLauncherIcon: use the GetWindows function when we can + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, test_hud: simplify the desaturated test + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, hud emulator: removing deprecated get_geometry method + +2012-03-25 Marco Trevisan (Treviño) + + HudController: removed typo + +2012-03-25 Marco Trevisan (Treviño) + + unityshell: make sure we initialize the HudController multiple_launchers property + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, test_hud: Check if the launcher icons (except the HUD one) are desaturated + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, test_hud: get icon by desktop id, not by tooltip_text + + It fixes internationalization issues. + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, launcher emulator: update against icon introspection changes + + Allow to get an icon by its desktop id + +2012-03-25 Marco Trevisan (Treviño) + + autopilot: update icon properties against new quirkless names + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, test HUD: added checks for the HUDLauncherIcon + +2012-03-25 Marco Trevisan (Treviño) + + LauncherIcon: added autopilot introspection friendly properties + +2012-03-25 Marco Trevisan (Treviño) + + HudController: oops... g_strcmp != 0 => str1 != str2 ;) + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, hud: added new HudController / HudView properties + + They allow to check if the HUD is locked to the launcher, in which + monitor is shown and if the embedded icon is shown on the view. + + Added an extra assert to check if hud_monitor equals hud.monitor + +2012-03-25 Marco Trevisan (Treviño) + + HudView: simplify the embedded icon showing API, add some introspection + +2012-03-25 Marco Trevisan (Treviño) + + HudController: some code cleanup, use functions to reduce code duplication + +2012-03-24 Marco Trevisan (Treviño) + + autopilot, test_hud: added checks for geometry for both locked and unlocked status + +2012-03-24 Marco Trevisan (Treviño) + + HudController: add support for the multiple launchers feature + + The HUD should show at the left edge of the screen when multiple + launchers are disabled and the mouse pointer is on a non-primary screen. + +2012-03-24 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-24 Marco Trevisan (Treviño) + + autopilot, tests: updated against Thomi's suggestions + +2012-03-21 Marco Trevisan (Treviño) + + autopilot: test_hud, correctly check the window geometry on multimonitor + +2012-03-21 Marco Trevisan (Treviño) + + Hud: add geometry introspection informations + +2012-03-21 Marco Trevisan (Treviño) + + autopilot: added hud monitor-aware tests + +2012-03-29 Thomi Richards + + Don't leak shortcut hints.. Fixes: . Approved by Andrea Azzarone, Marco Trevisan (Treviño). + +2012-03-29 Thomi Richards + + Don't play fast and loose with raw pointers to shortcuts. + +2012-03-29 Thomi Richards + + Fix memory leak in PanelView.. Fixes: . Approved by Tim Penhey. + +2012-03-29 Thomi Richards + + Used local typedef. + +2012-03-29 Thomi Richards + + PanelView no longer leaks a nux::ColorLayer on exit. + +2012-03-28 Tim Penhey + + Make the favourite store a bit more robust around empty environments.. Fixes: . Approved by Thomi Richards, Tim Penhey. + +2012-03-29 Tim Penhey + + Make the method public for testing, and test it. + +2012-03-28 Thomi Richards + + Don't leak a UbusMessageInfo in ubus_server if there's no handlers defined for a message.. Fixes: . Approved by Tim Penhey. + +2012-03-29 Thomi Richards + + Don't leak in ubus_server when there's no handlers for a particular message, + +2012-03-28 Bilal Akhtar + + Add animation of icon moving to the launcher, and the wiggle when installation is complete.. Fixes: https://bugs.launchpad.net/bugs/955147. Approved by Tim Penhey. + +2012-03-29 Thomi Richards + + Merged branch that stops launcher tests from failing. + +2012-03-29 Thomi Richards + + Merged trunk. + +2012-03-29 Thomi Richards + + Merged branch that had the fix for version 1 of this code, to make sure this still merges cleanly with trunk. + +2012-03-28 Thomi Richards + + Merged trunk. + +2012-03-21 Thomi Richards + + Merged trunk. + +2012-03-16 Thomi Richards + + Store drag window in a nux::ObjectPtr. + +2012-03-16 Thomi Richards + + Whitespace fixes. + +2012-03-16 Thomi Richards + + Merged trunk. + +2012-03-16 Thomi Richards + + Member variable rename. + +2012-03-16 Thomi Richards + + Forward declare as much as we can in header files. + +2012-03-16 Thomi Richards + + Removed more debug logging. + +2012-03-16 Thomi Richards + + GetIconSize should be const. + +2012-03-16 Thomi Richards + + Don't call c_str() on a std::string when assigning to another std::string. + +2012-03-16 Thomi Richards + + Removed more debug logging. + +2012-03-16 Thomi Richards + + Removed some unneeded down-casts. + +2012-03-16 Thomi Richards + + Removed some debugging code that's no longer needed. + +2012-03-16 Thomi Richards + + Icon now invisible while animation is running. + +2012-03-16 Thomi Richards + + Works now, just need to make the icon invisible in the launcher while the animation runs. + +2012-03-15 Thomi Richards + + Removed some unnecessary casting. + +2012-03-15 Thomi Richards + + Removed some cruft, now it kind-of works, except that anim_complete signal doesn't fire correctly. + +2012-03-15 Thomi Richards + + Only unref property_value if we got it. + +2012-03-15 Thomi Richards + + Indentation fixes. + +2012-03-15 Thomi Richards + + Trying to remove ptr hacks, crashes. + +2012-03-15 Thomi Richards + + Fixed indentation, removed un-needed initialisers. + +2012-03-14 Bilal Akhtar + + Merge from trunk + +2012-03-14 Bilal Akhtar + + Cleanup tests even further, follow Alex's recommendations, thanks a lot Alex + +2012-03-14 Bilal Akhtar + + Cleanup at the end, move function to the proper class + +2012-03-14 Bilal Akhtar + + Make changes in tests, merge function into LauncherTests, etc + +2012-03-13 Bilal Akhtar + + Cleanup tests, also first ensure Software Center is removed + +2012-03-13 Bilal Akhtar + + Merge from trunk, fix conflicts + +2012-03-13 Bilal Akhtar + + Fix crash on second install, THANKS THOMI + +2012-03-08 Bilal Akhtar + + Fix a line in tests + +2012-03-08 Bilal Akhtar + + Change C-style casts + +2012-03-08 Bilal Akhtar + + Use SC icon instead of iBus + +2012-03-08 Bilal Akhtar + + Get all tests working + +2012-03-08 Bilal Akhtar + + Thanks Thomi for the helper function on getting icon from desktop file + +2012-03-08 Bilal Akhtar + + Merge from trunk + +2012-03-08 Bilal Akhtar + + Try to get test working + +2012-03-07 Bilal Akhtar + + Merge from trunk + +2012-03-05 Bilal Akhtar + + Make changes in code as per Marco's review, thanks a lot! + +2012-03-04 Bilal Akhtar + + Cleanup code + +2012-03-03 Bilal Akhtar + + Get the launcher to hide/unhide as needed + +2012-03-03 Bilal Akhtar + + Get the DragWindow to disappear properly after the animation + +2012-03-03 Bilal Akhtar + + Get the Animation target right + +2012-03-02 Bilal Akhtar + + Everything's compete now, except the animation target + +2012-03-02 Bilal Akhtar + + Add test animation, get everything else working + +2012-03-02 Bilal Akhtar + + Code cleanup + +2012-03-02 Bilal Akhtar + + Get the dragwindow working, YAY + +2012-03-02 Bilal Akhtar + + Add GetIconSize function to Launcher + +2012-02-29 Bilal Akhtar + + First steps towards getting a DragWindow working + +2012-02-27 Bilal Akhtar + + Merge from trunk and fix runtime failure + +2012-02-26 Bilal Akhtar + + Try to get baseWindow working + +2012-02-23 Bilal Akhtar + + Fix build failures + +2012-02-23 Bilal Akhtar + + Send icon_x, y and size to the SCLauncherIcon constructor + +2012-02-23 Bilal Akhtar + + Merge from trunk + +2012-03-28 Tim Penhey + + Move TestPlacesGroupImpl google test into the group that needs X.. Fixes: . Approved by Sam Spilsbury. + +2012-03-29 Tim Penhey + + The lensview_impl gtest needs X. + +2012-03-28 Thomi Richards + + Autopilot launcher tests now skip instead of fail when running the nvidia chipset.. Fixes: . Approved by Alex Launi. + +2012-03-29 Thomi Richards + + Merged trunk, made docstring and error messages more explicit. + +2012-03-29 Thomi Richards + + Raise BlacklistedDriverError sooner, since nvidia chipsets can't even get the monitor name. + +2012-03-29 Thomi Richards + + Fix scenario generation. + +2012-03-28 Thomi Richards + + Made some autopilot exception messages more informative and explicit.. Fixes: . Approved by Tim Penhey. + +2012-03-29 Thomi Richards + + Even better. + +2012-03-29 Thomi Richards + + Made ValueExceptions more explicit in the ScreenGeometry class. + +2012-03-28 Thomi Richards + + Fix a crash in the launcher software center integration code.. Fixes: https://bugs.launchpad.net/bugs/963718. Approved by Tim Penhey. + +2012-03-29 Thomi Richards + + Don't need AsOutParam. + +2012-03-28 Thomi Richards + + Initialise ptr to nullptr to appease Tim. + +2012-03-28 Thomi Richards + + Merged trunk. + +2012-03-26 Gord Allott + + fixes a gvariant unref bug + +2012-03-28 Michal Hruby + + Fix inversion of logic in the glib logger. Fixes: . Approved by . + +2012-03-28 Michal Hruby + + Fix inversion of logic in the glib logger + +2012-03-28 Andrea Cimitan + + 1px subtle change: 1st pixel of shadow from (0, 0, 0, 0.58f) to (0, 0, 0, 0.60f). Fixes: . Approved by Marco Trevisan (Treviño). + +2012-03-28 Andrea Cimitan + + Super subtle refinement to the top pixel of the panel shadow + +2012-03-27 Andrea Azzarone + + Reduce the spread delay for all items other than the initial item the select lands on after alt-tab opens.. Fixes: https://bugs.launchpad.net/bugs/838232. Approved by Thomi Richards. + +2012-03-28 Andrea Azzarone + + Fix typo. + +2012-03-27 Andrea Azzarone + + Use two different timeout lenghts for the alt-tab details mode. Fix Bug #838232. + +2012-03-27 Andrea Cimitan + + Smaller but sharper panel shadow, from design. Fixes: . Approved by Andrea Azzarone, Marco Trevisan (Treviño). + +2012-03-27 Andrea Cimitan + + New panel shadow + +2012-03-27 Andrea Azzarone + + Fix crash on PointerBarrier.. Fixes: https://bugs.launchpad.net/bugs/944217. Approved by Thomi Richards. + +2012-03-28 Andrea Azzarone + + Update manual test. + +2012-03-27 Andrea Azzarone + + Adds a manual test. + +2012-03-27 Andrea Azzarone + + Disconnect smoothing_handle_ on PointerBarrierWrapper destruction. + +2012-03-27 Marco Trevisan (Treviño) + + Autopilot: added tests for the primary-monitor aware LauncherController. Fixes: . Approved by Thomi Richards. + +2012-03-27 Marco Trevisan (Treviño) + + Merging with thomi's multiply_scenarios branch + +2012-03-28 Thomi Richards + + Launcher tests now use multiply_scenarios to generate test scenarios. + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, launcher: added tests to check the number of launchers + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, X11: get the glxinfo output only once. + +2012-03-25 Marco Trevisan (Treviño) + + test_launcher: code updated to follow the thomi's suggestions ;) + +2012-03-25 Marco Trevisan (Treviño) + + autopilot, X11: add BlacklistedDriverError + +2012-03-25 Marco Trevisan (Treviño) + + Merging with trunk + +2012-03-21 Marco Trevisan (Treviño) + + autopilot, test_launcher: skip the tests if we can't set the primary monitor. + +2012-03-21 Marco Trevisan (Treviño) + + autopilot: X11 emulator, add blacklist of drivers to skip the primary monitor set + +2012-03-21 Marco Trevisan (Treviño) + + autopilot: test launcher, added scenarios to test with more configurations + +2012-03-21 Marco Trevisan (Treviño) + + autpilot, X11: allow to set the primary monitor via xrandr + +2012-03-26 Thomi Richards + + Converted several classes to use std::string instead of const char* or const gchar*.. Fixes: . Approved by Brandon Schaefer. + +2012-03-27 Thomi Richards + + Use initialiser list. + +2012-03-27 Thomi Richards + + Updated to coding standards. + +2012-03-27 Thomi Richards + + LauncherIcon::SetEmblemText now takes a std::string. + +2012-03-27 Thomi Richards + + LauncherIcon::emblem now uses std::string instead of const char* + +2012-03-27 Thomi Richards + + Made PlacesTileSimple::uri a std::string, and updated dependant code. + +2012-03-27 Thomi Richards + + Made PlacesSimpleTile::lable a std::string. + +2012-03-27 Thomi Richards + + Removed const char* from IconTexture class, and all places that call it. + +2012-03-26 Brandon Schaefer + + Disable Alt+F1 mode when the dash is open.. Fixes: . Approved by Thomi Richards. + +2012-03-26 Brandon Schaefer + + * Added autopilot test + +2012-03-26 Brandon Schaefer + + * Disable alt+f1 when the dash is open + +2012-03-26 Marco Trevisan (Treviño) + + Launcher: Connect the already present icons to signals when setting the model. + + When a new launcher is added, we need to connect the icons that are already on the model to the needs_redraw signal, or the new launcher won't redraw when they ask that.. Fixes: https://bugs.launchpad.net/bugs/964851. Approved by Thomi Richards. + +2012-03-26 Marco Trevisan (Treviño) + + Launcher: Connect the already present icons to signals when setting the model. + + This fixes the bug #964851 + +2012-03-26 Alex Launi + + Reorganize and refactor the manual tests. Fixes: . Approved by Alex Launi, Thomi Richards. + +2012-03-26 Alex Launi + + add newline to end of Hud.txt + +2012-03-26 Alex Launi + + merge trunk + +2012-03-23 Alex Launi + + Reorganize and refactor the manual tests + +2012-03-26 Andrea Cimitan + + Set 0.2 as new alpha value for dimmed icons, apply tweaks to edges. Fixes: https://bugs.launchpad.net/bugs/938620. Approved by Marco Trevisan (Treviño). + +2012-03-22 Andrea Cimitan + + Dim icons in the launcher for 938620 + +2012-03-26 Andrea Azzarone + + Fix the alignment of the dash window buttons.. Fixes: https://bugs.launchpad.net/bugs/963019. Approved by Marco Trevisan (Treviño), Andrea Cimitan. + +2012-03-23 Andrea Azzarone + + Fix. + +2012-03-23 Andrea Azzarone + + Remove the if. + +2012-03-23 Andrea Azzarone + + Fix dash window buttons alignment. + +2012-03-23 Didier Roche + + Release\ 5.8.0 + 2012-03-23 Marco Trevisan (Treviño) BamfLauncherIcon: implement WindowsOnViewport to get only windows on visible VP diff -Nru unity-5.8.0/CMakeLists.txt unity-5.10.0/CMakeLists.txt --- unity-5.8.0/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/CMakeLists.txt 2012-04-12 13:21:21.000000000 +0000 @@ -8,7 +8,7 @@ # set (PROJECT_NAME "unity") set (UNITY_MAJOR 5) -set (UNITY_MINOR 8) +set (UNITY_MINOR 10) set (UNITY_MICRO 0) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "5.0") diff -Nru unity-5.8.0/debian/changelog unity-5.10.0/debian/changelog --- unity-5.8.0/debian/changelog 2012-04-13 16:25:29.000000000 +0000 +++ unity-5.10.0/debian/changelog 2012-04-13 16:25:31.000000000 +0000 @@ -1,3 +1,178 @@ +unity (5.10.0-0ubuntu3) precise-proposed; urgency=low + + [ Oliver Grawert ] + * Enable subarch specific quilt support + * add linaros disable_standalone-clients.patch to make unity build with GLES + + [ Didier Roche ] + * remove a symlink and replace with a real file for + debian/patches/series. as not supported in non v3 (and we don't + want v3 format with full source upstream derived branch) + + -- Didier Roche Fri, 13 Apr 2012 14:34:15 +0200 + +unity (5.10.0-0ubuntu2) precise-proposed; urgency=low + + [ Ricardo Salveti de Araujo ] + * Enabling build with OpenGL ES2.0 support for ARM and disable maintainer + mode on that arch to avoid -Werror failure (LP: #980544) + + -- Didier Roche Fri, 13 Apr 2012 09:13:07 +0200 + +unity (5.10.0-0ubuntu1) precise-proposed; urgency=low + + * New upstream release: + - bamfdaemon crashed with SIGABRT in g_assertion_message() (LP: #926208) + - We are using 1 bad hack for compiz hanging on startup (LP: #963264) + - GConf backend steals glib events from compiz (LP: #965220) + - when I closed QupZill brawser it crashed and then and then I sow + worrning that compiz crashed but fire fox and chrome is estle working. + gtk-window-decorator crashed with SIGSEGV in max_window_name_width() + (LP: #948580) + - compiz crashed with SIGSEGV in std::basic_string<...>::basic_string() + from unity::launcher::HudLauncherIcon::HudLauncherIcon()::{lambda} from + unity::UBusManager::OnCallback (LP: #964897) + - unity-panel-service crashed due to heap corruption in g_free() from + service_proxy_name_changed() [libindicator/indicator-service- + manager.c:574] (LP: #969360) + - Opening dash while an application is maximized makes unity completely + useless, have to relogin (LP: #975103) + - unity crash on alt-tab (LP: #975168) + - Top bar - Menus should be condensed to fit panel/overlay of appmenu + (LP: #655184) + - Topbar - window controls for maximised windows in the top bar should + conform to Fitts's law (LP: #839690) + - [FFe, UIFe] Dash - When the Dash is open and there is a maximised app in + the background, the top bar background should not disappear + (LP: #839480) + - Dash - The inner bottom left, bottom right and top right corners of the + desktop dash border are rendered incorrectly (LP: #839476) + - Showdesktoped window contents invisible in window spread (LP: #877778) + - Maximized windows can be accidentally closed from wrong monitor. + (LP: #865701) + - Unity launcher on-screen corruption on resume from suspend with nVidia + proprietary driver (LP: #915265) + - Launcher - Inserting items into launcher makes unnecessary animations on + other monitors (LP: #925021) + - Far left character in panel (and launcher popups) distorted + (LP: #927441) + - Jenkins build failure: SetAcceptKeyNavFocusOnMouseEnter not declared + (LP: #938037) + - super+ and sometimes super+ keys now cause launch + to wedge with the key hints shown and retains focus instead of selecting + the requested window (LP: #934084) + - three-finger move does not move (Precise) (LP: #940612) + - compiz crashed with SIGSEGV in std::__detail::_List_node_base::_M_hook() + from unity::ui::PointerBarrierWrapper::EmitCurrentData (LP: #944217) + - indicators appear intertwined with global menu (LP: #953868) + - [5.8 pre staging] "sticky edge" option does nothing visible + (LP: #961285) + - HUD: The selection always returns to the first item whenever menus are + updated (LP: #962984) + - Multimonitor - Using single launcher, the HUD draws incorrectly on a + secondary monitor (LP: #963577) + - Type your command does not appear translated in the HUD (LP: #964074) + - HUD doesnt receive input after pressing Tab (LP: #964760) + - compiz crashed with SIGSEGV in g_variant_unref() from + unity::launcher::SoftwareCenterLauncherIcon::OnPropertyChanged + (LP: #963718) + - HUD denial of service (LP: #948820) + - Application launch time increased with type-to-search in unity 5.8 + (LP: #966417) + - Weird translation on the shortcut overlay dialog (LP: #971332) + - compiz crashed with SIGSEV in g_type_check_instance_is_a from + unity::launcher::DeviceLauncherIcon::ShowNotification (LP: #971345) + - Launcher - launcher have a weird background if cursor is over it while + opening dash (LP: #974408) + - compiz crashed with SIGSEGV in + unity::hud::HudIconTextureSource::ColorForIcon() (LP: #935307) + - Compiz: Growing idle memory consumption with latest Nux/Unity (~60 + MiB/h) in unity::PanelIndicatorEntryView::Refresh() (LP: #975801) + - [nvidia] minimized windows are white in the window spread (LP: #977189) + - compiz crashed with SIGSEGV in nux::Rect::Rect() from + unity::launcher::LauncherIcon::OpenQuicklist() from RecvMouseDown() from + unity::launcher::LauncherIcon::RecvMouseDown() (LP: #954736) + - Alt-tab - Reduce the spread delay for all items other than the initial + item the select lands on after alt-tab opens (LP: #838232) + - Dash - The Dash search box should expand horizontally when the Dash + switches to full screen mode (LP: #841907) + - window selected via ALT+F1 doesn't get focus in unity (LP: #875932) + - Non square icons don't fill result tiles as much as they should + (LP: #878015) + - Dash - the spinner and the 'clear' button (the circle with the X) in the + Dash is blurry (LP: #891691) + - Dash - Update the Dash card view so that the implementation conforms to + the attached designs (LP: #901164) + - Launcher bar doesn't saturate when focused via keynav when dash opened + (LP: #913569) + - Global menu doesn't work with multiple monitors (twinview) (LP: #921918) + - Number shortcut overlay won't show if mouse hovers launcher bar area + (LP: #924636) + - Colour of launcher on second monitor is not restored after closing the + dash (LP: #925442) + - [autohide] app icons in HUD are poorly scaled (LP: #931406) + - Show default HUD icon for Desktop (nautilus) menus (LP: #931548) + - Hud shows wrong application icon when activated with the dash showing + (LP: #932371) + - Window management - Dragging down a maximized window from the panel has + not predictable results (LP: #934680) + - Launcher - Properly colorize icons (LP: #938620) + - lens bar clickable area needs to be expanded (LP: #937193) + - Multimonitor - hidden menu indicators are shown in the non active + monitor (LP: #951747) + - Wrong glib #include in Hud.h (LP: #952117) + - [FFe, UIFe] New animation for adding launchers for newly installed + applications (LP: #955147) + - HUD remembers icon of last used app (LP: #961161) + - Launcher - window buttons are not horizontally ad vertically aligned + (LP: #963019) + - Opening HUD after dash shows window title in the panel (LP: #963134) + - Dash picking a really odd color with default wallpaper (LP: #963140) + - HUD overlay has one pixel gap on left side (LP: #964061) + - Launcher icon indicators doesn't redraw when changing the launcher + settings (LP: #964851) + - Dash home results take too long to appear (LP: #965492) + - Multimonitor - Only the panel that controls the focused window should + draw its title (LP: #968261) + - Performing a pinch gesture over a window has no effect (LP: #969554) + - Dash section header icons are missing (LP: #971233) + - Unity displays "no search results" with results present (LP: #971430) + - Pressing Ctrl+Tab from the command lens switches to the wrong lens + (LP: #971850) + - PanelMenuView causes gtk assertion to fail (LP: #971947) + - [regression] The keyboard shortcuts overlay bottom is truncated. + (LP: #973386) + - Not minimizable windows have an enabled "minimize" button on the unity + panel (LP: #936425) + - HUD maximize button affects Dash (LP: #939054) + - Panel opacity toggle doesn't quite work (LP: #940683) + - Dash is totally broken when disabling the blur effect (LP: #941066) + - Dash collapsed view has scrollbar (LP: #956500) + - HUD too many triangles with new transition effect (LP: #961230) + - Menu bar not transparent when invoking dash with super key whilst HUD + enabled and vice versa (LP: #962410) + - Windows controls lost if dash is opened after HUD (LP: #963118) + - HUD service returning more than 5 entries (LP: #965299) + - Dash - Search box text is clipped (LP: #966424) + - IBus Pinyin pup box disappears in the hud (LP: #968777) + - Dash and HUD search fields appear in slightly different places + (LP: #969404) + - Super+Tab, super, loses focus (LP: #970420) + - Dash - reduce frosty effect (LP: #978785) + - HUD doesn't ignore key events while ibus is active (LP: #957927) + - "Show Dekstop icon" typo in Unity's translation template (LP: #934526) + - Starting dash or hud with mouse over launcher desaturates all icons + (LP: #973063) + - Untranslatable strings in the hints screen (LP: #975815) + - Dash text input does not get focus (LP: #774447) + - dash ignore queries done just after session start (LP: #979799) + * Cherry-pick an additional commit for a crash + * debian/control: + - build-dep on latest libnux-2.0-dev for ABI break + - bump Standards-Version to latest + + -- Didier Roche Thu, 12 Apr 2012 15:22:36 +0200 + unity (5.8.0-0ubuntu2) precise; urgency=low * Cherry-picked upstream: diff -Nru unity-5.8.0/debian/control unity-5.10.0/debian/control --- unity-5.8.0/debian/control 2012-04-13 16:25:29.000000000 +0000 +++ unity-5.10.0/debian/control 2012-04-13 16:25:31.000000000 +0000 @@ -25,7 +25,7 @@ libunity-misc-dev (>= 4.0.4), libutouch-grail-dev (>= 1.0.20), libxcb-icccm4-dev, - libnux-2.0-dev (>= 2.8.0), + libnux-2.0-dev (>= 2.10.0), compiz-dev (>= 1:0.9.7.2), libcompizconfig0-dev (>= 0.9.7.0~bzr428-0ubuntu6~), xsltproc, @@ -40,7 +40,7 @@ libgdu-dev, libunity-dev (>= 5.2.0), libxfixes-dev (>= 1:5.0-4ubuntu4), -Standards-Version: 3.9.2 +Standards-Version: 3.9.3 Homepage: https://launchpad.net/unity Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/unity/ubuntu diff -Nru unity-5.8.0/debian/patches/disable_standalone-clients.patch unity-5.10.0/debian/patches/disable_standalone-clients.patch --- unity-5.8.0/debian/patches/disable_standalone-clients.patch 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/debian/patches/disable_standalone-clients.patch 2012-04-13 16:25:31.000000000 +0000 @@ -0,0 +1,10 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e01c178..7e3a4f5 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -156,7 +156,7 @@ add_subdirectory(tests) + add_subdirectory(tools) + add_subdirectory(UnityCore) + add_subdirectory(guides) +-add_subdirectory(standalone-clients EXCLUDE_FROM_ALL) ++#add_subdirectory(standalone-clients EXCLUDE_FROM_ALL) diff -Nru unity-5.8.0/debian/patches/series.armel unity-5.10.0/debian/patches/series.armel --- unity-5.8.0/debian/patches/series.armel 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/debian/patches/series.armel 2012-04-13 16:25:31.000000000 +0000 @@ -0,0 +1 @@ +disable_standalone-clients.patch diff -Nru unity-5.8.0/debian/patches/series.armhf unity-5.10.0/debian/patches/series.armhf --- unity-5.8.0/debian/patches/series.armhf 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/debian/patches/series.armhf 2012-04-13 16:25:31.000000000 +0000 @@ -0,0 +1 @@ +disable_standalone-clients.patch diff -Nru unity-5.8.0/debian/rules unity-5.10.0/debian/rules --- unity-5.8.0/debian/rules 2012-04-13 16:25:29.000000000 +0000 +++ unity-5.10.0/debian/rules 2012-04-13 16:25:31.000000000 +0000 @@ -3,6 +3,8 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 +DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) +gles2_architectures := armel armhf DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ') @@ -11,8 +13,31 @@ CORE_ABIVERSION := $(shell sed -rn 's/^\#define[[:space:]]+CORE_ABIVERSION[[:space:]]+//p' /usr/include/compiz/core/abiversion.h ) NUX_ABIVERSION := $(shell sed -rn 's/^\#define[[:space:]]+NUX_ABIVERSION[[:space:]]+//p' /usr/include/Nux-2.0/Nux/ABI.h ) +override_dh_quilt_patch: + dh_quilt_patch + if test -r debian/patches/series.$(DEB_HOST_ARCH); then \ + pc=".pc.$(DEB_HOST_ARCH)"; \ + test -d "$(CURDIR)/$$pc" || mkdir "$(CURDIR)/$$pc"; \ + cp debian/patches/series.$(DEB_HOST_ARCH) $(CURDIR)/$$pc/series; \ + cd $(CURDIR); \ + QUILT_PC="$$pc" quilt upgrade || true; \ + QUILT_PC="$$pc" QUILT_PATCHES="debian/patches/" quilt push -a || true; \ + fi; \ + +override_dh_quilt_unpatch: + if test -r debian/patches/series.$(DEB_HOST_ARCH); then \ + pc=".pc.$(DEB_HOST_ARCH)"; \ + cd $(CURDIR); \ + QUILT_PC="$$pc" QUILT_PATCHES="debian/patches/" quilt pop -a || true; \ + fi; \ + dh_quilt_unpatch + override_dh_auto_configure: +ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), $(gles2_architectures))) + dh_auto_configure -- -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CFLAGS=ON +else dh_auto_configure -- -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package +endif override_dh_install: find debian/tmp/usr/lib -name \*.*a -exec rm {} \; diff -Nru unity-5.8.0/manual-tests/AllButton.txt unity-5.10.0/manual-tests/AllButton.txt --- unity-5.8.0/manual-tests/AllButton.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/AllButton.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -Test Filter "All" Button -======================== -These tests show that the dash "All" button works well. - - -Test "All" Button 1 -------------------- - -#. Just after the login open the "Filter results". - -Outcome - "All" should be selected by default in every filter category. - -Test "All" Button 2 -------------------- - -#. Make sure the "All" button is selected. -#. Try to activate it. - -Outcome - Click on it should do nothing. - - -Test "All" Button 3 -------------------- - -#. Make sure the "All" button is selected. -#. Select another item in the filter category. - -Outcome: - The all button should automatically toggle to the un-selected state. - -Test "All" Button 4 -------------------- - -#. Make sure the one or more items is selected in a filter category. -#. Deselect all items. - -Outcome: - The all button should automatically toggle to the selected state. diff -Nru unity-5.8.0/manual-tests/AltCombos.txt unity-5.10.0/manual-tests/AltCombos.txt --- unity-5.8.0/manual-tests/AltCombos.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/AltCombos.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -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.8.0/manual-tests/AutoMaximize.txt unity-5.10.0/manual-tests/AutoMaximize.txt --- unity-5.8.0/manual-tests/AutoMaximize.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/AutoMaximize.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -auto-maximize window -======================= -Thit test make sure that the auto-maximize window feature is disabled for -resolution above the 1024x600. - -- Open the display panel -- Set a resolution greater then 1024x600 (e.g 1366x768) -- Open a window, that usually doesn't start maximized - -Outcome -The window should not be in the maximized state. - -- Open the display panel -- Set a resolution lower or equal to 1024x600. -- Open the ccsm and change the automaximize-threshold option to 20 (experimental-tab of unity-plugin). -- Open nautilus, that usually doesn't start maximized - -Outcome -The window should be in the maximized state. diff -Nru unity-5.8.0/manual-tests/Dash.txt unity-5.10.0/manual-tests/Dash.txt --- unity-5.8.0/manual-tests/Dash.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Dash.txt 2012-04-12 13:21:21.000000000 +0000 @@ -1,38 +1,245 @@ +Dash Tests +============= + +Super Tap Timing on Slow Systems +Note: Should be automated +-------------------------------- +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. + +Setup: +#. 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 + +Action: +#. 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. Super+Shift+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. + + Dash SearchBar middle-click +Note: Should be automated --------------------------- This test shows how the middle click over the dash search bar should work (see lp:842462) -#. Open a text editor, and write some dummy text -#. Select some text part of the written dummy text with mouse +Action: +#. Select this text with you mouse. #. Press Super or Alt+F2 to open the Dash -#. Move the mouse over the dash search bar -#. Press middle click to paste the content of your primary clipboard +#. Move the mouse cursor over the dash search entry box. +#. Middle click. -Outcome +Outcome: 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) +Action: #. 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 +#. Ensure that a category in the results has a "See X more results" label +#. Expand category that has "See X more results" label +#. Count the number of results + +Outcome: + The number of results counted and the value for X in "See X more results" are the same. -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"). +Action: +#. Open the files lens (Super+A) +#. Type an arbitrary search string -Outcome +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. + + +Dash no-results-hint +-------------------- +This tests that the text displaying "Sorry nothing matches your search" is hidden when results are present (even in hard-to-automatically-test scenarios). + +Action: +#. Start guest session +#. Open the Dash - there shouldn't be any results displayed, since this user + account didn't interact with anything yet +#. Run an application not present in the launcher (for example gedit) +#. Close previously opened application + +Outcome: + When Dash is opened 'gedit' (or application you launched) should be + displayed in the "Recent Apps" category. You shouldn't see + "Sorry nothing matches your search" text. + + +Filter Results Tests +======================== +These tests show that the dash "All" button works well. + + +Test "All" Button 1 +Note: Should be automated +------------------- + +Setup: +#. Open app lens, and the "Filter results" sidebar + +Outcome: + "All" should be selected by default in every filter category. + +Test "All" Button 2 +Note: Should be automated +------------------- + +Setup: +#. Open app lens, and the "Filter results" sidebar +#. Make sure the "All" button is selected. + +Action: +#. Try to activate it. + +Outcome: + Click on it should do nothing. + + +Test "All" Button 3 +Note: Should be automated +------------------- + +Setup: +#. Open app lens, and the "Filter results" sidebar +#. Make sure the "All" button is selected. + +Action: +#. Select another item in the filter category. + +Outcome: + The all button should automatically toggle to the un-selected state. + +Test "All" Button 4 +Note: Should be automated +------------------- + +Setup: +#. Open app lens, and the "Filter results" sidebar +#. Make sure the one or more items is selected in a filter category. + +Action: +#. Deselect all selected items. + +Outcome: + The all button should automatically toggle to the selected state. + +Test Expand/Collapse Filters +------------------------------- +This test shows that the expand/collapse arrow of a filter category +header works well. + +Setup: +#. Open the app lens. +#. If necessary, show the results filter sidebar. +#. Make sure that a collapse arrow is shown adjacent to every + filter category header. + +Action: +#. Click on a category header arrow. + +Outcome: + The filter category should collapse. + +Action: +#. Click on the arrow (again). + +Outcome: + The filter category should expand. + + +Drag and drop tests +==================== + +Launcher drop target saturation test +--------------------------------------- + +Setup: +# open the files lens + +Action: +# select and drag a document-file (e.g. text or image) to the launcher + +Outcome: + 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. + +Lens Tests +============ + +Restarting of crashed lenses +---------------------------- +This test makes sure that if a lens crashes, searching in the dash +automatically restarts it. + +Setup: +#. Open a terminal +#. Make sure there are some results in the apps lens + +Action: +#. 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. + + +Lazy start lenses test +Regression testcase for https://bugs.launchpad.net/unity/+bug/929506 +Note: Should be automated +---------------------------------------------------- + +Setup: +#. Restart your computer to get a clean unity instance + +Action: +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. \ No newline at end of file diff -Nru unity-5.8.0/manual-tests/DragDropDashLauncher.txt unity-5.10.0/manual-tests/DragDropDashLauncher.txt --- unity-5.8.0/manual-tests/DragDropDashLauncher.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/DragDropDashLauncher.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -- 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.8.0/manual-tests/EjectNotificationIcon.txt unity-5.10.0/manual-tests/EjectNotificationIcon.txt --- unity-5.8.0/manual-tests/EjectNotificationIcon.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/EjectNotificationIcon.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Test Eject Notification Icon (USB) -------------------- -This test shows that the correct icon is shown in the OSD notification when a -USB pen drive is ejected using drag and drop into the trash. - -#. Plug in a USB pen drive -#. Wait for device icon to appear in the launcher -#. Drag and drop it into the trash icon - -Outcome - The usb pen drive will be "ejected" and an OSD-notification will appear. The - icon in the notification is the same icon used for the launcher icon. - - - -Test Eject Notification Icon (CD) -------------------- -This test shows that the correct icon is shown in the OSD notification when a -CD is ejected using drag and drop into the trash. - -#. Insert a CD -#. Wait for device icon to appear in the launcher -#. Drag and drop it into the trash icon - -Outcome - The cd will be"ejected and an OSD-notification will appear. The - icon in the notification is the same icon used for the launcher icon. diff -Nru unity-5.8.0/manual-tests/Filters.txt unity-5.10.0/manual-tests/Filters.txt --- unity-5.8.0/manual-tests/Filters.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Filters.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Test Expand/Collapse Filters -======================== -This test shows that the expand/collapse arrow of a filter category -header works well. - -#. Open the dash. -#. Make sure that a collapse arrow is shown adjacent to every - filter category header. -#. Click on it. -#. The filter category should collapse. -#. Make sure that an expand arrow is shown ajacent to every filter - category header. -#. Click on it (again). -#. The filter category should expand. diff -Nru unity-5.8.0/manual-tests/Hud.txt unity-5.10.0/manual-tests/Hud.txt --- unity-5.8.0/manual-tests/Hud.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Hud.txt 2012-04-12 13:21:21.000000000 +0000 @@ -1,27 +1,16 @@ -For reference, the term Tap means to press the indicated key and release it, within a timeframe of 50ms - -Hud Invocate ------------ -This test makes sure that the hud presents itself, the launcher hides -and the panel changes - -#. Tap Alt - -Outcome - The hud interface presents itself with no other interface such as the dash present. - The Launcher hides, the panel becomes transparent with a colour tint matching the hud - The HUD search bar is focused and typing text enters text into it - Hud Search ----------- This test makes sure that the hud will search and activate items. +Setup: #. Ensure the devices indicator is present + +Action: #. Tap Alt #. Type "system" to search for the "System settings..." item in the devices indicator #. Press return to activate the search query. -Outcome +Outcome: The system settings interface presents itself, the hud disappears. If the hud does not disappear, this test failed. If the system settings interface did not present itself, this test did *not* fail. @@ -31,13 +20,16 @@ ----------- This test ensures the hud key navigation is intact +Setup: #. Ensure the messaging indicator is present + +Action: #. Tap Alt #. Type "Message" to search for items from the messaging indicator #. Press down twice #. Press return -Outcome +Outcome: The item selected will activate and the hud with disappear. If the hud does not disappear, this test failed. If the buttons under the search box do not highlight, this test failed. @@ -47,38 +39,41 @@ ---------- This test ensures that the hud is dismissable +Action: #. Tap Alt #. Type "test" #. Press escape #. Click anywhere on the screen that is not the hud interface -Outcome +Outcome: 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 +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. -#. Ensure the launchers hide mode is set to "Never" -#. Tap Alt +Note: Should be automated -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 +Setup: +#. Open gnome-terminal +Action: +#. While holding Alt, tap arrow keys: Up, Down, Right, Left -Hud Sending Undo ----------------- -This test ensure that the undo action is properly handle in a text editor. +Outcome: + The terminal should show the keycodes were received as text "ABCD". -#. Open GEdit and start a new document -#. Type "0 1" -#. Tap Alt -#. Type "undo" -#. Press and release the Enter Key +Alt+Enter Crash +--------------- +Tests that Alt+Enter does not cause unity to crash (LP: #960957) + +Action: +#. Press Alt+Enter. + +Expected Outcome: + Nothing happens -Outcome - After pressing the Enter key the text in GEdit should be "0 " +Wrong Outcome: + Unity/compiz crashes diff -Nru unity-5.8.0/manual-tests/Indicators.txt unity-5.10.0/manual-tests/Indicators.txt --- unity-5.8.0/manual-tests/Indicators.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Indicators.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Middle-clicking or Scrolling over active Indicators ---------------------------------------------------- -This test shows how the indicators icons should react to events when active. - -#. Start on a clean screen -#. Open an indicator Menu (i.e. indicator-sound, not a global menu item) -#. Move the mouse pointer over the indicator-sound and middle-click or scroll - over it. - -Outcome - The indicator-sound should mute/unmute on middle-clicks, and change the system - volume on scroll. - Middle-clicking over global-menu items should work as before (causing the open - indicator menu to close). diff -Nru unity-5.8.0/manual-tests/Launcher.txt unity-5.10.0/manual-tests/Launcher.txt --- unity-5.8.0/manual-tests/Launcher.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Launcher.txt 2012-04-12 13:21:21.000000000 +0000 @@ -1,6 +1,3 @@ -Note, for simplification, one pip is defined as a single filled in arrow to the - left of a launcher. - Test Launcher Icon with Windows in multiple workspaces ------------------------------------------------------ This test shows how the launcher should draw when there are application windows @@ -170,6 +167,95 @@ Outcome: * The icon should go back to its correct position in the launcher. +Drag USB Device Launcher to Eject +------------------- +This test shows that the correct icon is shown in the OSD notification when a +USB pen drive is ejected using drag and drop into the trash. + +Setup: +#. Plug in a USB pen drive +#. Wait for device icon to appear in the launcher + +Action: +#. Drag and drop it into the trash icon + +Outcome: + The usb pen drive will be "ejected" and an OSD-notification will appear. The + icon in the notification is the same icon used for the launcher icon. + + + +Drag CD Device Launcher to Eject +------------------- +This test shows that the correct icon is shown in the OSD notification when a +CD is ejected using drag and drop into the trash. + +Setup: +#. Insert a CD +#. Wait for device icon to appear in the launcher + +Action: +#. Drag and drop it into the trash icon + +Outcome: + The cd will be"ejected and an OSD-notification will appear. The + icon in the notification is the same icon used for the launcher icon. + + +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. + +Setup: +#. 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 + +Action: +#. 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. + + +Test Quicklist while on Expo +----------------------------- +This test shows how the launcher quicklists work when the expo plugin is activated. + +Setup: +#. Start with a clear screen +#. Press Super+S or select the workspace switcher on the launcher + +Action: +#. When the workspace switcher is running, right-click over a launcher icon + +Outcome: + The expo should terminate, and the quicklist should be shown once the + workspace switcher has been closed. + +Test highlight BFB +------------------- +This test shows that the BFB launcher icon highlights during key navigation. + +Setup: +#. Start with a clear screen +#. Press ALT+F1 + +Outcome: + The launcher key navigation starts and the BFB launcher icon highlights. + It looks like `this`__: + __https://launchpadlibrarian.net/85700200/bfb85.png Test launchers with multiple monitors ------------------------------------- @@ -358,3 +444,24 @@ Expected Result: The launchers on each monitor have saturated icons (normal looking, not the desaturated look that there is while the dash is open). + +Test number overlays while shortcut help is active +------------------------------ +Setup: +have a launcher with a few icons in it + +Actions: +# Hold down Super until the "Keyboard Shortcuts" screen appears + +Expected Result: +The numbers [1-9] should be displayed overlaid on the icons. +"Keyboard Shortcut" menu should appear as well. + +Actions: +# Mouse over an icon in the launcher +# Hold down Super until the "Keyboard Shortcuts" screen appears + +Expected Result: +The numbers [1-9] should be displayed overlaid on the icons. +"Keyboard Shortcut" menu should appear as well. + diff -Nru unity-5.8.0/manual-tests/Lenses.txt unity-5.10.0/manual-tests/Lenses.txt --- unity-5.8.0/manual-tests/Lenses.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Lenses.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -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.8.0/manual-tests/lp929506.txt unity-5.10.0/manual-tests/lp929506.txt --- unity-5.8.0/manual-tests/lp929506.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/lp929506.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -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.8.0/manual-tests/Menus.txt unity-5.10.0/manual-tests/Menus.txt --- unity-5.8.0/manual-tests/Menus.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Menus.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -Menu Color ----------- -This test shows the color of the menus using the Ambiance theme: - -#. Start with a clean screen -#. Open an application window with menus -#. Go on the top panel and open a menu - -Outcome: - The menu should have a black background (i.e. #403f3a) diff -Nru unity-5.8.0/manual-tests/MMOptions.txt unity-5.10.0/manual-tests/MMOptions.txt --- unity-5.8.0/manual-tests/MMOptions.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/MMOptions.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -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.8.0/manual-tests/MultiMonitor.txt unity-5.10.0/manual-tests/MultiMonitor.txt --- unity-5.8.0/manual-tests/MultiMonitor.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/MultiMonitor.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,37 @@ +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. + + +Test Barrier Unplugging Monitor +---------------------------------------------------- +Setup: + #. Get a system with 2 (or more) monitors + #. Enable the "Capture Mouse" setting in CCSM + +Actions: + #. Move mouse slowly over barrier to primary monitor + #. Quickly unplug external monitor + +Expected Result: + No crash. + diff -Nru unity-5.8.0/manual-tests/NvMinimizedWindows.txt unity-5.10.0/manual-tests/NvMinimizedWindows.txt --- unity-5.8.0/manual-tests/NvMinimizedWindows.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/NvMinimizedWindows.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,11 @@ +Nvidia white windows in spread +---------- +This test ensures that windows are not white in the spread using nvidia. + +#. Ensure unity is running on a machine with a nvidia GPU using the nvidia driver +#. Open two windows of the same app +#. Minimize one +#. Click the launcher icon to activate the spread + +Outcome: + The contents of both windows should be visible. diff -Nru unity-5.8.0/manual-tests/NvResumeFromSuspend.txt unity-5.10.0/manual-tests/NvResumeFromSuspend.txt --- unity-5.8.0/manual-tests/NvResumeFromSuspend.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/NvResumeFromSuspend.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,11 @@ +Nvidia resume from suspend corruption +---------- +This test ensures the screen is not corrupted after resume from suspend on nvidia cards. + +#. Ensure unity is running on a machine with a nvidia GPU using the proprietary nvidia driver +#. Put the machine to sleep +#. Resume the machine from sleep +#. Observe the area where the launcher would normally show + +Outcome: + The screen should not display any visual corruption once X is finished updating after a resume. diff -Nru unity-5.8.0/manual-tests/PanelIndicators.txt unity-5.10.0/manual-tests/PanelIndicators.txt --- unity-5.8.0/manual-tests/PanelIndicators.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/PanelIndicators.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -Menus and Active Indicators ---------------------------- -This test shows the interaction between the global menu and open indicators. - -#. Start on a clean screen -#. Open an application that has menus (i.e a gnome-terminal) -#. Open an indicator Menu (i.e. indicator sound) -#. Move the mouse pointer on the PanelMenuGrabArea (i.e the area between the - indicators and the global menu) - -Outcome - The menu should appear. This was happening only when going over the menus, - not over the empty panel area. - - -Window Buttons and Active Indicators ------------------------------------- -This test shows the interaction between the window buttons and open indicators. - -#. Start on a clean screen -#. Open an application that has menus (i.e a gnome-terminal) -#. Maximize it -#. Open an indicator Menu (i.e. indicator sound) -#. Move the mouse pointer on the top-left corner of the screen - -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.8.0/manual-tests/Panel.txt unity-5.10.0/manual-tests/Panel.txt --- unity-5.8.0/manual-tests/Panel.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Panel.txt 2012-04-12 13:21:21.000000000 +0000 @@ -17,22 +17,6 @@ Once all the maximized windows are closed, restored or not visible, the panel should go back to its defined opacity. - -Panel Menus Revelation ----------------------- -This test shows how the menus should be revealed when a new application has been -launched. - -#. Start with a clear screen -#. Open a new application that has menus (i.e. gnome-terminal) - -Outcome - The panel should show the menus in global menu bar for two seconds. - If a new gnome-terminal window is opened, the menus are not shown again. - If more than one application is open at once, the menus of each application - are shown once is focused. - - Panel Double Clicks ------------------- This test shows how the double click over the top panel should work. @@ -46,21 +30,31 @@ The maximized window should restore. If no maximized window is available on the current workspace, nothing should happen. - -Panel on Alt+Tab ----------------- -This test shows react on Alt+Tab - -#. Start with a clear screen -#. Open some new applications -#. Press Alt+Tab +Menu Color +---------- +This test shows the color of the menus using the Ambiance theme: + +#. Start with a clean screen +#. Open an application window with menus +#. Go on the top panel and open a menu + +Outcome: + The menu should have a black background (i.e. #403f3a) + +Middle-clicking or Scrolling over active Indicators +--------------------------------------------------- +This test shows how the indicators icons should react to events when active. + +#. Start on a clean screen +#. Open an indicator Menu (i.e. indicator-sound, not a global menu item) +#. Move the mouse pointer over the indicator-sound and middle-click or scroll + over it. Outcome - When you press Alt+Tab to switch window, the application title in the top left - 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. - + The indicator-sound should mute/unmute on middle-clicks, and change the system + volume on scroll. + Middle-clicking over global-menu items should work as before (causing the open + indicator menu to close). Panel appearance with overlays ------------------------------ @@ -74,3 +68,4 @@ Expected Result: The panel should stay translucent + diff -Nru unity-5.8.0/manual-tests/QuicklistOnExpo.txt unity-5.10.0/manual-tests/QuicklistOnExpo.txt --- unity-5.8.0/manual-tests/QuicklistOnExpo.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/QuicklistOnExpo.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Test Quicklist while on Expo -============================ - -This test shows how the launcher quicklists work when the expo plugin is activated. - -#. Start with a clear screen -#. Press Super+S or select the workspace switcher on the launcher -#. When the workspace switcher is running, right-click over a launcher icon - -Outcome - The expo should terminate, and the quicklist should be shown once the - workspace switcher has been closed. - Clicking over a quicklist item should work as expected and clicking outside - that quicklist, should close it. diff -Nru unity-5.8.0/manual-tests/ReadMe.txt unity-5.10.0/manual-tests/ReadMe.txt --- unity-5.8.0/manual-tests/ReadMe.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/ReadMe.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -============== -Manual Testing -============== - -Outline -------- -Sometimes it is not possible to easily make an automated test for some -use-cases. However just because something isn't easily tested automatically -doesn't mean that there isn't value in creating a test for it, just that the -test needs to be executed by a person until it is converted into an automated -test. - - -Format ------- -Manual tests take the format of text files in this directory (the manual-test -one). These files are formatted using `reStructured Text`_. A very -comprehensive `quick reference`_ is available. - -.. _reStructured Text: http://en.wikipedia.org/wiki/ReStructuredText -.. _quick reference: http://docutils.sourceforge.net/docs/user/rst/quickref.html - -Tests have a header, steps to follow, and an expected outcome, as demonstrated -by the following example: - -There can be multiple tests in a single file, but they should all be related, -and the filename should indicate the tests it contains. - - -Test Dash ---------- -This test shows that the dash appears when the super key is pushed. - -#. Start with a clear screen -#. Press the key - -Outcome - The dash appears, and focus is in the search box. The icons on the laucher - are desaturated except for the ubuntu button at the top. The icons in the - panel go white. - - -Directory Structure -------------------- -It is expected that as we grow a number of manual tests, we will use -directories to organise them. - diff -Nru unity-5.8.0/manual-tests/README.txt unity-5.10.0/manual-tests/README.txt --- unity-5.8.0/manual-tests/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/README.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,55 @@ +============== +Manual Testing +============== + +Outline +------- +Sometimes it is not possible to easily make an automated test for some +use-cases. However just because something isn't easily tested automatically +doesn't mean that there isn't value in creating a test for it, just that the +test needs to be executed by a person until it is converted into an automated +test. + +However please be very discriminatory about your manual tests. It's highly likely that you can automate whatever it is you're testing, and doing so will be of much more value to the quality of Unity. Manual tests are a last resort. They should not be written lightly, and should give you a feeling of shame. If you're to the point where you believe you need a manual test, then please come talk to the QA team and we will see if we can find an automatable solution. + + +Format +------ +Manual tests take the format of text files in this directory (the manual-test +one). These files are formatted using `reStructured Text`_. A very +comprehensive `quick reference`_ is available. + +.. _reStructured Text: http://en.wikipedia.org/wiki/ReStructuredText +.. _quick reference: http://docutils.sourceforge.net/docs/user/rst/quickref.html + +Tests have a header, steps to follow, and an expected outcome, as demonstrated +by the following example: + +There can be multiple tests in a single file, but they should all be related, +and the filename should indicate the tests it contains. + + +Test Dash +--------- +This test shows that the dash appears when the super key is pushed. + +#. Start with a clear screen +#. Press the key + +Outcome + The dash appears, and focus is in the search box. The icons on the laucher + are desaturated except for the ubuntu button at the top. The icons in the + panel go white. + + +Directory Structure +------------------- +It is expected that as we grow a number of manual tests, we will use +directories to organise them. + + +========= +Glossary +========= +Tap - to press the indicated key and release it, within a timeframe of 50ms. +Pip - one pip is defined as a single filled in arrow to the left of a launcher icon. \ No newline at end of file diff -Nru unity-5.8.0/manual-tests/ShortcutsOverlay.txt unity-5.10.0/manual-tests/ShortcutsOverlay.txt --- unity-5.8.0/manual-tests/ShortcutsOverlay.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/ShortcutsOverlay.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,14 @@ +The keyboard shortcuts overlay bottom is truncated +--------------------------- +This test ensures that the keyboard shortcuts overlay bottom is not truncated. +(see lp:973386) + +Setup: +#. Make sure you have a monitor with a resoultion bigger than 1024x768. + +Action: +#. Move your mouse in that monitor. +#. Press "Super" key. + +Outcome: + The keyboard shortcuts overlay bottom is not truncated. diff -Nru unity-5.8.0/manual-tests/SuperTab.txt unity-5.10.0/manual-tests/SuperTab.txt --- unity-5.8.0/manual-tests/SuperTab.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/SuperTab.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Super Tab Launcher Switcher ---------------------------- -This test shows how the Super+Tab launcher switcher works - -#. Open some applications pinned to the launcher -#. Press Super+Tab -#. Release and Press again Tab some times -#. Press also the Shift key and press again Tab -#. Release all the keys - -Outcome: - The first launcher item should be highlighted. - Pressing Tab multiple times makes the next launcher icon to be highlighted. - If clicking on the launcher while the Super+Tab switcher is active, the switcher - should terminate and the standard click action should be done. - When also the Shift modifier is pressed, pressing Tab highlights the previous - icon. - When releasing Super the highlighted launcher icon should be activated, and - the default launcher icon action should be performed. - If in the launcher there are many icons and they are shown as collapsed, - when the Super+Tab is activated and the icons should be expanded when - neeeded. - - -Escaping from Super Tab switcher --------------------------------- -This test shows how to escape from the Super+Tab switcher. - -#. Start with a clean screen -#. Press Super+Tab one or more times to make the launcher switcher to initialize -#. Press the Escape key when still pressing Super - -Outcome: - The Super Tab launcher switcher should terminate without performing any action - The previously selected launcher item should be deselected. diff -Nru unity-5.8.0/manual-tests/Switcher.txt unity-5.10.0/manual-tests/Switcher.txt --- unity-5.8.0/manual-tests/Switcher.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Switcher.txt 2012-04-12 13:21:21.000000000 +0000 @@ -3,16 +3,38 @@ This test only applies for multiple monitor. App names here are an example, any apps will do. +Setup: #. Start with no apps open (or at least remember what is open where) #. Start terminal on workspace 1 #. Start firefox on workspace 2 #. Move to workspace 2 -Now do the following on both monitors +Scenario 1: Perform on workspace 1 +Scenario 2: Perform on workspace 2 -#. Hold Alt, and press Tab, hold and observe -#. Release Alt. +Action: +#. Hold Alt, press tab +#. Observe +#. Release Alt -Outcomes - While alt is held, Firefox should appear in the tab list, and - terminal should not +Scenario 1 Outcome: + Terminal is shown in the alt-tab switcher, but firefox on workspace 2 is not. +Scenario 2 Outcome: + Firefox is shown in the alt-tab switcher, but the terminal on workspace 1 is not. + + +Panel on Alt+Tab +---------------- +This tests that the panel title changes with Alt+Tab + +Setup: +#. Open some new applications + +Action: +#. Press Alt+Tab + +Outcome + When you press Alt+Tab to switch window, the application title in the top left + 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. \ No newline at end of file diff -Nru unity-5.8.0/manual-tests/Tapping.txt unity-5.10.0/manual-tests/Tapping.txt --- unity-5.8.0/manual-tests/Tapping.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Tapping.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -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.8.0/manual-tests/UserInvisibleWindows.txt unity-5.10.0/manual-tests/UserInvisibleWindows.txt --- unity-5.8.0/manual-tests/UserInvisibleWindows.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/UserInvisibleWindows.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Running Application with both visible and invisible windows ------------------------------------------------------------ -This test shows how unity should manage applications with both user visible -and invisible windows. - -#. Start on a clean screen -#. Open one or more windows of an application with the skip-taskbar flag set to OFF -#. Open one or more windows of that application with the skip-taskbar flag set to ON - -Outcome - The launcher icon should count with left icon indicators (pips) only the visible - window(s); when clicking on it or selecting it via Alt+Tab unity should bring - to focus only the visible windows, while at the second click over the launcher - the spread with both visible and invisible windows should be activated. - When all the user-visible windows are closed, the application should stay in - the launcher or in the Alt+Tab (and show as running) only if is sticky, - otherwise the icon should hide. diff -Nru unity-5.8.0/manual-tests/Wakeups.txt unity-5.10.0/manual-tests/Wakeups.txt --- unity-5.8.0/manual-tests/Wakeups.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/manual-tests/Wakeups.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -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. - diff -Nru unity-5.8.0/manual-tests/WindowManagement.txt unity-5.10.0/manual-tests/WindowManagement.txt --- unity-5.8.0/manual-tests/WindowManagement.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/manual-tests/WindowManagement.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,51 @@ +Running Application with both visible and invisible windows +----------------------------------------------------------- +This test shows how unity should manage applications with both user visible +and invisible windows. + +Setup: +#. Open gedit +#. Open the 'open files' dialog + +Outcome: + The launcher icon should count with left icon indicators (pips) only the visible + window(s); + +Action: +#. Click the gedit launcher icon + +Outcome: + The main gedit window should come into focus + +Action: +#. Click the gedit launcher icon again, gedit still focused + +Outcome: + Spread with both visible and invisible windows should be activated. + + +Auto-maximize window +---------------------- +Thit test make sure that the auto-maximize window feature is disabled for +resolution above the 1024x600. + +Setup: +#. Open the display panel +#. Set a resolution greater then 1024x600 (e.g 1366x768) + +Action: +#. Open nautilus + +Outcome: + The window should not be in the maximized state. + +Setup: +#. Open the display panel +#. Set a resolution lower or equal to 1024x600. +#. Open the ccsm and change the automaximize-threshold option to 20 (experimental-tab of unity-plugin). + +Action: +#. Open nautilus, that usually doesn't start maximized + +Outcome: + The window should be in the maximized state. Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_border_tile_mask.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_border_tile_mask.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_border_tile.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_border_tile.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_left_corner_mask.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_left_corner_mask.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_left_corner.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_left_corner.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_right_corner_mask.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_right_corner_mask.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_bottom_right_corner.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_bottom_right_corner.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_left_tile.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_left_tile.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_noise.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_noise.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_right_border_tile_mask.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_right_border_tile_mask.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_right_border_tile.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_right_border_tile.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_top_right_corner_mask.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_top_right_corner_mask.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_top_right_corner.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_top_right_corner.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/dash_top_tile.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/dash_top_tile.png differ Binary files /tmp/H7HhLYySUQ/unity-5.8.0/plugins/unityshell/resources/panel-shadow.png and /tmp/NuklTHfeWf/unity-5.10.0/plugins/unityshell/resources/panel-shadow.png differ diff -Nru unity-5.8.0/plugins/unityshell/src/AbstractLauncherIcon.h unity-5.10.0/plugins/unityshell/src/AbstractLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/AbstractLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/AbstractLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -85,6 +85,7 @@ TYPE_NONE, TYPE_BEGIN, TYPE_HOME, + TYPE_HUD, TYPE_FAVORITE, TYPE_APPLICATION, TYPE_EXPO, @@ -175,7 +176,7 @@ virtual IconType GetIconType() = 0; - virtual const gchar* RemoteUri() = 0; + virtual std::string RemoteUri() = 0; virtual std::list Menus() = 0; @@ -187,9 +188,8 @@ virtual void SendDndLeave() = 0; - virtual void InsertEntryRemote(LauncherEntryRemote* remote) = 0; - - virtual void RemoveEntryRemote(LauncherEntryRemote* remote) = 0; + virtual void InsertEntryRemote(LauncherEntryRemote::Ptr const& remote) = 0; + virtual void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote) = 0; virtual std::string DesktopFile() = 0; @@ -197,6 +197,10 @@ virtual bool IsVisible() const = 0; + virtual bool IsVisibleOnMonitor(int monitor) const = 0; + + virtual void SetVisibleOnMonitor(int monitor, bool visible) = 0; + virtual void AboutToRemove() = 0; virtual void Stick(bool save = true) = 0; diff -Nru unity-5.8.0/plugins/unityshell/src/AbstractShortcutHint.h unity-5.10.0/plugins/unityshell/src/AbstractShortcutHint.h --- unity-5.8.0/plugins/unityshell/src/AbstractShortcutHint.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/AbstractShortcutHint.h 2012-04-12 13:21:21.000000000 +0000 @@ -43,13 +43,14 @@ class AbstractHint { public: + typedef std::shared_ptr Ptr; // Ctor - AbstractHint(std::string const& category, + AbstractHint(std::string const& category, std::string const& prefix, std::string const& postfix, std::string const& description, OptionType const type, - std::string const& arg1, + std::string const& arg1, std::string const& arg2 = "", std::string const& arg3 = "") : category(category) @@ -62,7 +63,7 @@ , arg3(arg3) { } - + // Copy ctor AbstractHint(unity::shortcut::AbstractHint const& obj) : category(obj.category()) @@ -77,13 +78,13 @@ , shortkey(obj.shortkey()) { } - + // Dtor virtual ~AbstractHint(){}; - + // Public Methods virtual bool Fill() = 0; - + // Properties nux::Property category; nux::Property prefix; diff -Nru unity-5.8.0/plugins/unityshell/src/BackgroundEffectHelper.cpp unity-5.10.0/plugins/unityshell/src/BackgroundEffectHelper.cpp --- unity-5.8.0/plugins/unityshell/src/BackgroundEffectHelper.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BackgroundEffectHelper.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -321,3 +321,89 @@ cache_dirty = false; return blur_texture_; } + +nux::ObjectPtr BackgroundEffectHelper::GetRegion(nux::Geometry geo, bool force_update) +{ + bool should_update = force_update || cache_dirty; + + /* Static blur: only update when the size changed */ + if ((!should_update) + && blur_texture_.IsValid() + && (geo == blur_geometry_)) + { + return blur_texture_; + } + + nux::GraphicsEngine* graphics_engine = nux::GetGraphicsDisplay()->GetGraphicsEngine(); + + int monitor_width = BackgroundEffectHelper::monitor_rect_.width; + int monitor_height = BackgroundEffectHelper::monitor_rect_.height; + + nux::Geometry temp = geo; + temp.OffsetPosition(-monitor_rect_.x, -monitor_rect_.y); + blur_geometry_ = nux::Geometry(0, 0, monitor_width, monitor_height).Intersect(temp); + + nux::GpuDevice* gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice(); + if (blur_geometry_.IsNull() || !gpu_device->backup_texture0_.IsValid()) + { + return nux::ObjectPtr(); + } + + // save the current fbo + nux::ObjectPtr current_fbo = gpu_device->GetCurrentFrameBufferObject(); + gpu_device->DeactivateFrameBuffer(); + + // Set a viewport to the requested size + // FIXME: We need to do multiple passes for the dirty region + // on the underlying backup texture so that we're only updating + // the bits that we need + graphics_engine->SetViewport(0, 0, blur_geometry_.width, blur_geometry_.height); + graphics_engine->SetScissor(0, 0, blur_geometry_.width, blur_geometry_.height); + // Disable nux scissoring + graphics_engine->GetRenderStates ().EnableScissor (false); + + // The background texture is the same size as the monitor where we are rendering. + nux::TexCoordXForm texxform__bg; + texxform__bg.flip_v_coord = false; + texxform__bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform__bg.uoffset = ((float) blur_geometry_.x) / monitor_width; + texxform__bg.voffset = ((float) monitor_height - blur_geometry_.y - blur_geometry_.height) / monitor_height; + + { + nux::ObjectPtr device_texture = gpu_device->backup_texture0_; + nux::ObjectPtr noise_device_texture = graphics_engine->CacheResource(noise_texture_); + + unsigned int offset = 0; + int quad_width = blur_geometry_.width; + int quad_height = blur_geometry_.height; + + unsigned int buffer_width = quad_width + 2 * offset; + unsigned int buffer_height = quad_height + 2 * offset; + + texxform__bg.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST); + texxform__bg.flip_v_coord = true; + + // Copy source texture + graphics_engine->QRP_GetCopyTexture(buffer_width, buffer_height, + blur_texture_, device_texture, + texxform__bg, nux::color::White); + } + + if (current_fbo.IsValid()) + { + current_fbo->Activate(true); + graphics_engine->Push2DWindow(current_fbo->GetWidth(), current_fbo->GetHeight()); + graphics_engine->GetRenderStates ().EnableScissor (true); + } + else + { + graphics_engine->SetViewport(0, 0, monitor_width, monitor_height); + graphics_engine->Push2DWindow(monitor_width, monitor_height); + + graphics_engine->ApplyClippingRectangle(); + } + + cache_dirty = false; + return blur_texture_; +} + diff -Nru unity-5.8.0/plugins/unityshell/src/BackgroundEffectHelper.h unity-5.10.0/plugins/unityshell/src/BackgroundEffectHelper.h --- unity-5.8.0/plugins/unityshell/src/BackgroundEffectHelper.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BackgroundEffectHelper.h 2012-04-12 13:21:21.000000000 +0000 @@ -50,6 +50,8 @@ // We could add more functions here to get different types of effects based on the background texture nux::ObjectPtr GetPixelatedRegion(nux::Rect rect, int pixel_size, bool update); + nux::ObjectPtr GetRegion(nux::Geometry geo, bool force_update = false); + void DirtyCache(); static void ProcessDamage(nux::Geometry geo); diff -Nru unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/BamfLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BamfLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -20,7 +20,10 @@ #include #include + #include +#include +#include #include "BamfLauncherIcon.h" #include "FavoriteStore.h" @@ -33,8 +36,6 @@ #include #include -#include - namespace unity { namespace launcher @@ -303,7 +304,7 @@ { if (!BAMF_IS_WINDOW(l->data)) continue; - + auto window = static_cast(l->data); auto view = static_cast(l->data); @@ -335,7 +336,7 @@ std::vector BamfLauncherIcon::WindowsOnViewport() { - WindowFilterMask filter; + WindowFilterMask filter = 0; filter |= WindowFilter::MAPPED; filter |= WindowFilter::USER_VISIBLE; filter |= WindowFilter::ON_CURRENT_DESKTOP; @@ -346,7 +347,7 @@ std::vector BamfLauncherIcon::WindowsForMonitor(int monitor) { - WindowFilterMask filter; + WindowFilterMask filter = 0; filter |= WindowFilter::MAPPED; filter |= WindowFilter::USER_VISIBLE; filter |= WindowFilter::ON_CURRENT_DESKTOP; @@ -455,26 +456,18 @@ void BamfLauncherIcon::AddProperties(GVariantBuilder* builder) { - LauncherIcon::AddProperties(builder); + SimpleLauncherIcon::AddProperties(builder); - GList* children, *l; - children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); - GVariant* xids[(int) g_list_length(children)]; - - int i = 0; - for (l = children; l; l = l->next) - { - if (!BAMF_IS_WINDOW(l->data)) - continue; + GVariantBuilder xids_builder; + g_variant_builder_init(&xids_builder, G_VARIANT_TYPE ("au")); - Window xid = bamf_window_get_xid(static_cast(l->data)); - xids[i++] = g_variant_new_uint32(xid); - } - g_list_free(children); + for (auto xid : GetWindows()) + g_variant_builder_add(&xids_builder, "u", xid); variant::BuilderWrapper(builder) - .add("desktop-file", DesktopFile()) - .add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i)) + .add("desktop_file", DesktopFile()) + .add("desktop_id", GetDesktopID()) + .add("xids", g_variant_builder_end(&xids_builder)) .add("sticky", IsSticky()); } @@ -627,26 +620,8 @@ bool BamfLauncherIcon::Spread(bool current_desktop, int state, bool force) { - GList* children, *l; - children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); - WindowManager* wm = WindowManager::Default(); - - std::vector windowList; - for (l = children; l; l = l->next) - { - if (!BAMF_IS_WINDOW(l->data)) - continue; - - Window xid = bamf_window_get_xid(static_cast(l->data)); - - if (!current_desktop || (current_desktop && wm->IsWindowOnCurrentDesktop(xid))) - { - windowList.push_back(xid); - } - } - - g_list_free(children); - return WindowManager::Default()->ScaleWindowGroup(windowList, state, force); + auto windows = GetWindows(current_desktop ? WindowFilter::ON_CURRENT_DESKTOP : 0); + return WindowManager::Default()->ScaleWindowGroup(windows, state, force); } void BamfLauncherIcon::EnsureWindowState() @@ -684,8 +659,13 @@ if (desktop_file.empty()) return; - for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next) - _gsignals.Disconnect(l->data, "item-activated"); + if (_menu_desktop_shortcuts) + { + for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next) + { + _gsignals.Disconnect(l->data, "item-activated"); + } + } _menu_desktop_shortcuts = dbusmenu_menuitem_new(); dbusmenu_menuitem_set_root(_menu_desktop_shortcuts, TRUE); @@ -750,11 +730,11 @@ g_list_free(children); // add dynamic quicklist - if (DBUSMENU_IS_CLIENT(_menuclient_dynamic_quicklist)) + if (_menuclient_dynamic_quicklist && DBUSMENU_IS_CLIENT(_menuclient_dynamic_quicklist.RawPtr())) { if (_menu_clients["dynamicquicklist"] != _menuclient_dynamic_quicklist) { - _menu_clients["dynamicquicklist"] = glib::Object(_menuclient_dynamic_quicklist); + _menu_clients["dynamicquicklist"] = _menuclient_dynamic_quicklist; } } else if (_menu_clients["dynamicquicklist"]) @@ -797,7 +777,7 @@ bamf_view_set_sticky(BAMF_VIEW(_bamf_app.RawPtr()), true); if (save && !desktop_file.empty()) - FavoriteStore::GetDefault().AddFavorite(desktop_file, -1); + FavoriteStore::Instance().AddFavorite(desktop_file, -1); } void BamfLauncherIcon::UnStick() @@ -813,7 +793,7 @@ Remove(); if (!desktop_file.empty()) - FavoriteStore::GetDefault().RemoveFavorite(desktop_file); + FavoriteStore::Instance().RemoveFavorite(desktop_file); } void BamfLauncherIcon::ToggleSticky() @@ -882,6 +862,8 @@ { GList* child = nullptr; DbusmenuClient* client = it->second; + if (!client) + continue; DbusmenuMenuitem* root = dbusmenu_client_get_root(client); if (!root || !dbusmenu_menuitem_property_get_bool(root, DBUSMENU_MENUITEM_PROP_VISIBLE)) @@ -1049,20 +1031,27 @@ UpdateIconGeometries(center); } -const gchar* BamfLauncherIcon::GetRemoteUri() +std::string BamfLauncherIcon::GetDesktopID() +{ + std::string const& desktop_file = DesktopFile(); + + return DesktopUtilities::GetDesktopID(desktop_file); +} + +std::string BamfLauncherIcon::GetRemoteUri() { if (_remote_uri.empty()) { const std::string prefix = "application://"; - glib::String basename(g_path_get_basename(DesktopFile().c_str())); + std::string const& desktop_id = GetDesktopID(); - if (!basename.Str().empty()) + if (!desktop_id.empty()) { - _remote_uri = prefix + basename.Str(); + _remote_uri = prefix + desktop_id; } } - return _remote_uri.c_str(); + return _remote_uri; } std::set BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& uris) diff -Nru unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.h unity-5.10.0/plugins/unityshell/src/BamfLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/BamfLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BamfLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -43,7 +43,7 @@ BamfLauncherIcon(BamfApplication* app); virtual ~BamfLauncherIcon(); - void ActivateLauncherIcon(ActionArg arg); + virtual void ActivateLauncherIcon(ActionArg arg); std::string DesktopFile(); @@ -81,7 +81,7 @@ std::list GetMenus(); std::set ValidateUrisForLaunch(unity::DndData& dnd_data); - const gchar* GetRemoteUri(); + std::string GetRemoteUri(); std::string BamfName() const; bool HandlesSpread() { return true; } @@ -113,8 +113,9 @@ bool OwnsWindow(Window w) const; - std::vector GetWindows(WindowFilterMask filter, int monitor = -1); + std::vector GetWindows(WindowFilterMask filter = 0, int monitor = -1); const std::set& GetSupportedTypes(); + std::string GetDesktopID(); glib::Object _bamf_app; diff -Nru unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/BFBLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/BFBLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BFBLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -63,14 +63,20 @@ 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) + if (overlay_identity.Str() == "dash" && IsVisibleOnMonitor(overlay_monitor)) { - SetQuirk(QUIRK_VISIBLE, !visible); + SetQuirk(QUIRK_ACTIVE, visible); EmitNeedsRedraw(); } + // If the hud is open, we hide the BFB if we have a locked launcher + else if (overlay_identity.Str() == "hud") + { + if (launcher_hide_mode_ == LAUNCHER_HIDE_NEVER) + { + SetVisibleOnMonitor(overlay_monitor, !visible); + EmitNeedsRedraw(); + } + } } nux::Color BFBLauncherIcon::BackgroundColor() diff -Nru unity-5.8.0/plugins/unityshell/src/BGHash.cpp unity-5.10.0/plugins/unityshell/src/BGHash.cpp --- unity-5.8.0/plugins/unityshell/src/BGHash.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BGHash.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -16,7 +16,11 @@ * Authored by: Gordon Allott */ + #include "BGHash.h" +#include +#include +#include #include #include #include @@ -31,707 +35,269 @@ nux::logging::Logger logger("unity.BGHash"); } -namespace { - int level_of_recursion; - const int MAX_LEVEL_OF_RECURSION = 16; - const int MIN_LEVEL_OF_RECURSION = 2; -} -namespace unity { - - BGHash::BGHash () - : _transition_handler (0), - _bg_slideshow (NULL), - _current_slide (NULL), - _slideshow_handler(0), - _current_color (unity::colors::Aubergine), - _new_color (unity::colors::Aubergine), - _old_color (unity::colors::Aubergine), - _hires_time_start(10), - _hires_time_end(20), - _ubus_handle_request_colour(0) - { - _override_color.alpha= 0.0f; - UnSerializeCache(); - - background_monitor = gnome_bg_new (); - client = g_settings_new ("org.gnome.desktop.background"); - - signal_manager_.Add( - new glib::Signal(background_monitor, - "changed", - sigc::mem_fun(this, &BGHash::OnBackgroundChanged))); - - signal_manager_.Add( - new glib::Signal(client, - "changed", - sigc::mem_fun(this, &BGHash::OnGSettingsChanged))); - - UBusServer *ubus = ubus_server_get_default (); - - gnome_bg_load_from_preferences (background_monitor, client); - - std::string filepath_hash = CreateFilepathHash(glib::String(g_strdup(gnome_bg_get_filename(background_monitor)))); - if (G_LIKELY(cache_map_.count(filepath_hash))) - { - nux::Color color(cache_map_[filepath_hash]); - LOG_DEBUG(logger) << "cache hit: " << color.red << ", " << color.green << ", " << color.blue; - TransitionToNewColor(cache_map_[filepath_hash]); - } - else - { - LOG_DEBUG(logger) << "cache miss: " << filepath_hash; - g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc)ForceUpdate, (gpointer)this, NULL); - } - - - // avoids making a new object method when all we are doing is - // calling a method with no logic - auto request_lambda = [](GVariant *data, gpointer self) { - reinterpret_cast(self)->DoUbusColorEmit(); - }; - _ubus_handle_request_colour = ubus_server_register_interest (ubus, UBUS_BACKGROUND_REQUEST_COLOUR_EMIT, - (UBusCallback)request_lambda, - this); - } - - BGHash::~BGHash () - { - // serialize our cache - SerializeCache(); - g_object_unref (client); - g_object_unref (background_monitor); - UBusServer *ubus = ubus_server_get_default (); - ubus_server_unregister_interest (ubus, _ubus_handle_request_colour); - } - - void BGHash::OverrideColor (nux::Color color) - { - _override_color = color; - OnBackgroundChanged(background_monitor); - } - - gboolean BGHash::ForceUpdate (BGHash *self) - { - self->OnBackgroundChanged(self->background_monitor); - return FALSE; - } - - void BGHash::OnGSettingsChanged (GSettings *settings, gchar *key) - { - gnome_bg_load_from_preferences (background_monitor, settings); - } - - void BGHash::OnBackgroundChanged (GnomeBG *bg) - { - if (_override_color.alpha) - { - TransitionToNewColor (_override_color); - return; - } - - const gchar *filename = gnome_bg_get_filename (bg); - if (filename == NULL) - { - // we might have a gradient instead - GdkColor color_primary, color_secondary; - GDesktopBackgroundShading shading_type; - nux::Color parsed_color; - - gnome_bg_get_color (bg, &shading_type, &color_primary, &color_secondary); - if (shading_type == G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL || - shading_type == G_DESKTOP_BACKGROUND_SHADING_SOLID) - { - parsed_color = nux::Color(static_cast(color_primary.red) / 65535, - static_cast(color_primary.green) / 65535, - static_cast(color_primary.blue) / 65535, - 1.0f); - } - else - { - nux::Color primary = nux::Color(static_cast(color_primary.red) / 65535, - static_cast(color_primary.green) / 65535, - static_cast(color_primary.blue) / 65535, - 1.0f); - - nux::Color secondary = nux::Color(static_cast(color_secondary.red) / 65535, - static_cast(color_secondary.green) / 65535, - static_cast(color_secondary.blue) / 65535, - 1.0f); - - parsed_color = (primary + secondary) * 0.5f; - } - nux::Color new_color = MatchColor (parsed_color); - TransitionToNewColor (new_color); - } - else - { - if (_bg_slideshow != NULL) - { - slideshow_unref (_bg_slideshow); - _bg_slideshow = NULL; - _current_slide = NULL; - } - - if (_slideshow_handler) - { - g_source_remove (_slideshow_handler); - _slideshow_handler = 0; - } - - if (g_str_has_suffix (filename, "xml")) - { - GError *error = NULL; - - if (_bg_slideshow != NULL) - { - slideshow_unref (_bg_slideshow); - _bg_slideshow = NULL; - } - - _bg_slideshow = read_slideshow_file (filename, &error); - - if (error != NULL) - { - LOG_WARNING(logger) << "Could not load filename \"" << filename << "\": " << error->message; - g_error_free (error); - } - else if (_bg_slideshow == NULL) - { - LOG_WARNING(logger) << "Could not load filename \"" << filename << "\""; - } - else - { - // we loaded fine, hook up to the slideshow - time_t current_time = time(0); - double now = (double) current_time; - - double time_diff = now - _bg_slideshow->start_time; - double progress = fmod (time_diff, _bg_slideshow->total_duration); - - // progress now holds how many seconds we are in to this slideshow. - // iterate over the slideshows until we get in to the current slideshow - Slide *slide_iteration; - Slide *slide_current = NULL; - double elapsed = 0; - double time_to_next_change = 0; - GList *list; - - for (list = _bg_slideshow->slides->head; list != NULL; list = list->next) - { - slide_iteration = reinterpret_cast(list->data); - if (elapsed + slide_iteration->duration > progress) - { - slide_current = slide_iteration; - time_to_next_change = slide_current->duration- (progress - elapsed); - break; - } - - elapsed += slide_iteration->duration; - } - - if (slide_current == NULL) - { - slide_current = reinterpret_cast(g_queue_peek_head(_bg_slideshow->slides)); - time_to_next_change = slide_current->duration; - } - - // time_to_next_change now holds the seconds until the next slide change - // the next slide change may or may not be a fixed slide. - _slideshow_handler = g_timeout_add ((guint)(time_to_next_change * 1000), - (GSourceFunc)OnSlideshowTransition, - (gpointer)this); - - // find our current slide now - if (slide_current->file1 == NULL) - { - LOG_WARNING(logger) << "Could not load filename \"" << filename << "\""; - } - else - { - FileSize *fs = reinterpret_cast(slide_current->file1->data); - filename = reinterpret_cast(fs->file); - } - - _current_slide = slide_current; - } - } - - LoadFileToHash(filename); - } - } +namespace unity +{ - gboolean BGHash::OnSlideshowTransition (BGHash *self) - { - // the timing might be a bit weird, GnomeBG works in floating points - // for the time value, so we might end up being a bit before the change - // or a bit after, after is fine, but before is bad - // so we need to check if the slide gnomebg tells us we are on is the - // old slide or a new one - double delta = 0.0; - Slide *proposed_slide = get_current_slide (self->_bg_slideshow, &delta); - if (proposed_slide == self->_current_slide) - { - // boo, so we arrived early, we need to get the next slide - GList *list = g_queue_find (self->_bg_slideshow->slides, self->_current_slide); - if (list->next == NULL) - { - // we hit the end of the slideshow, so we wrap around - proposed_slide = reinterpret_cast(self->_bg_slideshow->slides->head->data); - } - else - { - proposed_slide = reinterpret_cast(list->next->data); - } - } +BGHash::BGHash () + : _transition_handler (0), + _current_color (unity::colors::Aubergine), + _new_color (unity::colors::Aubergine), + _old_color (unity::colors::Aubergine), + _hires_time_start(10), + _hires_time_end(20), + _ubus_handle_request_colour(0) +{ + _override_color.alpha= 0.0f; - // at this point proposed_slide contains the slide we currently have - // if its a transition slide, we need to transition to the next image - // if its fixed, we can stay still, the previous transition slide already - // got us to this image. - - // quickly hook up the next transition - - self->_slideshow_handler = g_timeout_add ((guint)(proposed_slide->duration * 1000), - (GSourceFunc)OnSlideshowTransition, - (gpointer)self); + background_monitor_ = gnome_bg_new (); + client_ = g_settings_new ("org.gnome.desktop.background"); - if (proposed_slide->fixed == FALSE) - { - const gchar *filename = NULL; - if (proposed_slide->file1 == NULL) - { - LOG_WARNING(logger) << "Could not load filename \"" << filename << "\""; - } - else - { - FileSize *fs = reinterpret_cast(proposed_slide->file2->data); - filename = reinterpret_cast(fs->file); - } + signal_manager_.Add( + new glib::Signal(background_monitor_, + "changed", + sigc::mem_fun(this, &BGHash::OnBackgroundChanged))); + + signal_manager_.Add( + new glib::Signal(client_, + "changed", + sigc::mem_fun(this, &BGHash::OnGSettingsChanged))); + + UBusServer *ubus = ubus_server_get_default (); + + gnome_bg_load_from_preferences (background_monitor_, client_); + + + // avoids making a new object method when all we are doing is + // calling a method with no logic + auto request_lambda = [](GVariant *data, gpointer self) { + reinterpret_cast(self)->DoUbusColorEmit(); + }; + _ubus_handle_request_colour = ubus_server_register_interest (ubus, UBUS_BACKGROUND_REQUEST_COLOUR_EMIT, + (UBusCallback)request_lambda, + this); + RefreshColor(); +} - if (filename != NULL) - self->LoadFileToHash (filename); - } +BGHash::~BGHash () +{ + // We need to disconnect the signals before we delete the objects they're connected to, + // otherwise the signal manager reads a pointer that's been deleted already. + signal_manager_.Disconnect(client_, "changed"); + // serialize our cache + g_object_unref (client_); + signal_manager_.Disconnect(background_monitor_, "changed"); + g_object_unref (background_monitor_); + UBusServer *ubus = ubus_server_get_default (); + ubus_server_unregister_interest (ubus, _ubus_handle_request_colour); +} - self->_current_slide = proposed_slide; - return false; - } +void BGHash::OverrideColor (nux::Color color) +{ + _override_color = color; + OnBackgroundChanged(background_monitor_); +} - nux::Color BGHash::InterpolateColor (nux::Color colora, nux::Color colorb, float value) - { - // takes two colours, transitions between them, we can do it linearly or whatever - // i don't think it will matter that much - // it doesn't happen too often - return colora + ((colorb - colora) * value); +void BGHash::RefreshColor() +{ + Atom real_type; + gint result; + gint real_format; + gulong items_read; + gulong items_left; + gchar* colors; + Atom representative_colors_atom; + Display* display; + GdkRGBA color_gdk; + + representative_colors_atom = gdk_x11_get_xatom_by_name ("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"); + display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); + + gdk_error_trap_push (); + result = XGetWindowProperty (display, + GDK_ROOT_WINDOW (), + representative_colors_atom, + 0L, + G_MAXLONG, + False, + XA_STRING, + &real_type, + &real_format, + &items_read, + &items_left, + (guchar **) &colors); + gdk_flush (); + gdk_error_trap_pop_ignored (); + + if (result == Success && items_read) + { + gdk_rgba_parse(&color_gdk, colors); + nux::Color new_color(color_gdk.red, + color_gdk.green, + color_gdk.blue, + 1.0f); + TransitionToNewColor(MatchColor(new_color)); + XFree (colors); } - void BGHash::TransitionToNewColor(nux::color::Color new_color) - { - if (new_color == _current_color) - return; - - if (_transition_handler) - { - // we are currently in a transition - g_source_remove (_transition_handler); - } +} - _old_color = _current_color; - _new_color = new_color; +gboolean BGHash::ForceUpdate (BGHash *self) +{ + self->OnBackgroundChanged(self->background_monitor_); + return FALSE; +} - _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); - } +void BGHash::OnGSettingsChanged (GSettings *settings, gchar *key) +{ + gnome_bg_load_from_preferences (background_monitor_, settings); +} - gboolean BGHash::OnTransitionCallback(BGHash *self) +void BGHash::OnBackgroundChanged (GnomeBG *bg) +{ + if (_override_color.alpha) { - return self->DoTransitionCallback(); + TransitionToNewColor (_override_color); + return; } - gboolean BGHash::DoTransitionCallback () - { - guint64 current_time = g_get_monotonic_time(); - float timediff = ((float)current_time - _hires_time_start) / _hires_time_end; - - timediff = std::max(std::min(timediff, 1.0f), 0.0f); - - _current_color = InterpolateColor(_old_color, - _new_color, - timediff); - DoUbusColorEmit (); + RefreshColor(); +} - if (current_time > _hires_time_start + _hires_time_end) - { - _transition_handler = 0; - return FALSE; - } - else - { - return TRUE; - } - } +nux::Color BGHash::InterpolateColor (nux::Color colora, nux::Color colorb, float value) +{ + // takes two colours, transitions between them, we can do it linearly or whatever + // i don't think it will matter that much + // it doesn't happen too often + return colora + ((colorb - colora) * value); +} - void BGHash::DoUbusColorEmit() +void BGHash::TransitionToNewColor(nux::color::Color new_color) +{ + if (new_color == _current_color) { - ubus_server_send_message(ubus_server_get_default(), - UBUS_BACKGROUND_COLOR_CHANGED, - g_variant_new ("(dddd)", - _current_color.red, - _current_color.green, - _current_color.blue, - _current_color.alpha) - ); + LOG_DEBUG(logger) << "rejecting colour"; + return; } - GdkPixbuf *BGHash::GetPixbufFromBG () + if (_transition_handler) { - GnomeDesktopThumbnailFactory *factory; - GdkPixbuf *pixbuf; - GdkScreen *screen = gdk_screen_get_default (); - int width = 0, height = 0; - - factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE); - gnome_bg_get_image_size (background_monitor, factory, - gdk_screen_get_height(screen), - gdk_screen_get_width (screen), - &width, &height); - - pixbuf = gnome_bg_create_thumbnail (background_monitor, factory, - gdk_screen_get_default (), - width, height); - - return pixbuf; + // we are currently in a transition + g_source_remove (_transition_handler); } - void BGHash::LoadPixbufToHash(GdkPixbuf *pixbuf) - { - nux::Color new_color; - if (pixbuf == NULL) - { - LOG_WARNING(logger) << "Passed in a bad pixbuf, defaulting colour"; - new_color = unity::colors::Aubergine; - } - else - { - new_color = HashColor (pixbuf); - } + LOG_DEBUG(logger) << "transitioning from: " << _current_color.red << " to " << new_color.red; - TransitionToNewColor (new_color); - } + _old_color = _current_color; + _new_color = new_color; - void BGHash::LoadFileToHash(const std::string path) - { - std::string filepath_hash = CreateFilepathHash(path); - if (G_LIKELY(cache_map_.count(filepath_hash))) - { - TransitionToNewColor(cache_map_[filepath_hash]); - } - else - { - glib::Error error; - glib::Object pixbuf(gdk_pixbuf_new_from_file (path.c_str (), &error)); + _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); +} - if (error) - { - LOG_WARNING(logger) << "Could not load filename \"" << path << "\": " << error.Message(); - _current_color = unity::colors::Aubergine; +gboolean BGHash::OnTransitionCallback(BGHash *self) +{ + return self->DoTransitionCallback(); +} - // try and get a colour from gnome-bg, for various reasons, gnome bg might not - // return a correct image which sucks =\ but this is a fallback - pixbuf = GetPixbufFromBG(); - } +gboolean BGHash::DoTransitionCallback () +{ + guint64 current_time = g_get_monotonic_time(); + float timediff = ((float)current_time - _hires_time_start) / _hires_time_end; - LoadPixbufToHash (pixbuf); - - cache_map_[filepath_hash] = _new_color; - } - } + timediff = std::max(std::min(timediff, 1.0f), 0.0f); - std::string BGHash::CreateFilepathHash(std::string path) - { - glib::Error error; - glib::Object file(g_file_new_for_path(path.c_str())); - glib::Object file_info(g_file_query_info(file, - G_FILE_ATTRIBUTE_TIME_MODIFIED, - G_FILE_QUERY_INFO_NONE, - NULL, &error)); - if (G_UNLIKELY(error)) - { - LOG_ERROR(logger) << "could not hash path (" << path << ")" - << ": " << error.Message(); - return std::string(""); - } - else - { - glib::String modified_time(g_file_info_get_attribute_as_string(file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED)); - return path + modified_time.Str(); - } - } + _current_color = InterpolateColor(_old_color, + _new_color, + timediff); + DoUbusColorEmit (); - namespace + if (current_time > _hires_time_start + _hires_time_end) { - const std::string cachedirectory("/unity/"); - const std::string cachefilename("bgcachefile"); + _transition_handler = 0; + return FALSE; } - - void BGHash::SerializeCache() + else { - glib::Error error; - glib::String cachedir(g_build_filename(g_get_user_cache_dir(), cachedirectory.c_str(), NULL)); - glib::String fullpath(g_build_filename(cachedir, cachefilename.c_str(), NULL)); - g_mkdir_with_parents(cachedir, 0744); - glib::Object cachefile(g_file_new_for_path(fullpath)); - glib::Object output_stream(G_OUTPUT_STREAM(g_file_replace(cachefile, - NULL, FALSE, G_FILE_CREATE_NONE, - NULL, &error))); - LOG_DEBUG(logger) << "serializing cache: " << fullpath; - if (G_UNLIKELY(error)) - { - LOG_ERROR(logger) << "could not open file (" << fullpath << ")" - << ": " << error.Message(); - } - else - { - glib::Error write_error; - std::ostringstream buffer; - for (auto ittr=cache_map_.begin(); ittr != cache_map_.end(); ittr++) - { - std::string key = (*ittr).first; - nux::Color value((*ittr).second); - - buffer << key << ":" - << int(value.red * 255) << ":" - << int(value.green * 255) << ":" - << int(value.blue * 255); - if (ittr != --cache_map_.end()) - { - buffer << ","; - } - } - - const char* base_buffer = buffer.str().c_str(); - gsize bytes_written = 0; - LOG_DEBUG(logger) << "writing to buffer (" << buffer.str() << ")"; - g_output_stream_write_all(output_stream, base_buffer, strlen(base_buffer), &bytes_written, NULL, &write_error); - if (write_error) - { - LOG_ERROR(logger) << "could not write to file (" << fullpath << ")" - << ": " << error.Message(); - } - - g_output_stream_close(output_stream, NULL, NULL); - } + return TRUE; } +} - void BGHash::UnSerializeCache() - { - glib::Error error; - glib::String cachedir(g_build_filename(g_get_user_cache_dir(), cachedirectory.c_str(), NULL)); - glib::String fullpath(g_build_filename(cachedir, cachefilename.c_str(), NULL)); - glib::Object cachefile(g_file_new_for_path(fullpath)); - glib::String contents; - gsize length; - g_file_get_contents(fullpath, &contents, &length, &error); +void BGHash::DoUbusColorEmit() +{ + ubus_server_send_message(ubus_server_get_default(), + UBUS_BACKGROUND_COLOR_CHANGED, + g_variant_new ("(dddd)", + _current_color.red, + _current_color.green, + _current_color.blue, + _current_color.alpha) + ); +} - if (G_UNLIKELY(error)) - { - LOG_ERROR(logger) << "could not open file (" << fullpath << ")" - << ": " << error.Message(); - } - else - { - LOG_DEBUG(logger) << "Loading from hash file (" << fullpath << " - " << length << "): " << contents; - // data is filenamehash:red:green:blue, - // using glib instead of C++ stuff like boost because boost just corrupted everything, very weird. - gchar** super_tokens = NULL; - super_tokens = g_strsplit(contents, ",", -1); - if (super_tokens != NULL) - { - for (int superi = 0; super_tokens[superi]; superi++) - { - glib::String super_token(super_tokens[superi]); - char** sub_tokens = g_strsplit(super_token, ":", 4); - if (sub_tokens != NULL) - { - std::string name, red, green, blue; - for (int i = 0; sub_tokens[i]; i++) - { - glib::String token(sub_tokens[i]); - switch(i) - { - case 0: name = token.Str(); break; - case 1: red = token.Str(); break; - case 2: green = token.Str(); break; - case 3: blue = token.Str(); break; - default: break; - } - } - if (!name.empty()) - { - LOG_DEBUG(logger) << "Unserialized cache value " << name; - cache_map_[name] = nux::Color(atof(red.c_str()) / 255.0f, - atof(green.c_str()) / 255.0f, - atof(blue.c_str()) / 255.0f, 1); - } - g_free(sub_tokens); // only g_free because glib:String will free the strings for us - } - } - g_free(super_tokens); // only g_free because glib::String will free the strings for us - } +nux::Color BGHash::MatchColor (const nux::Color base_color) +{ + nux::Color colors[12]; - } - } + colors[ 0] = nux::Color (0x540e44); + colors[ 1] = nux::Color (0x6e0b2a); + colors[ 2] = nux::Color (0x841617); + colors[ 3] = nux::Color (0x84371b); + colors[ 4] = nux::Color (0x864d20); + colors[ 5] = nux::Color (0x857f31); + colors[ 6] = nux::Color (0x1d6331); + colors[ 7] = nux::Color (0x11582e); + colors[ 8] = nux::Color (0x0e5955); + colors[ 9] = nux::Color (0x192b59); + colors[10] = nux::Color (0x1b134c); + colors[11] = nux::Color (0x2c0d46); - inline nux::Color GetPixbufSample (GdkPixbuf *pixbuf, int x, int y) - { - guchar *img = gdk_pixbuf_get_pixels (pixbuf); - guchar *pixel = img + ((y * gdk_pixbuf_get_rowstride(pixbuf)) + (x * gdk_pixbuf_get_n_channels (pixbuf))); - return nux::Color (static_cast(*(pixel + 0)), - static_cast(*(pixel + 1)), - static_cast(*(pixel + 2))); - } + float closest_diff = 200.0f; + nux::Color chosen_color; + nux::color::HueSaturationValue base_hsv (base_color); - inline bool is_color_different (const nux::Color color_a, const nux::Color color_b) + if (base_hsv.saturation < 0.08) { - nux::Color diff = color_a - color_b; - if (fabs (diff.red) > 0.15 || fabs (diff.green) > 0.15 || fabs (diff.blue) > 0.15) - return true; - - return false; + // grayscale image + LOG_DEBUG (logger) << "got a grayscale image"; + chosen_color = nux::Color (46 , 52 , 54 ); + chosen_color.alpha = 0.72f; } - - nux::Color GetQuadAverage (int x, int y, int width, int height, GdkPixbuf *pixbuf) + else { - level_of_recursion++; - // samples four corners - // c1-----c2 - // | | - // c3-----c4 - - nux::Color corner1 = GetPixbufSample(pixbuf, x , y ); - nux::Color corner2 = GetPixbufSample(pixbuf, x + width, y ); - nux::Color corner3 = GetPixbufSample(pixbuf, x , y + height); - nux::Color corner4 = GetPixbufSample(pixbuf, x + width, y + height); - - nux::Color centre = GetPixbufSample(pixbuf, x + (width/2), y + (height / 2)); - - // corner 1 - if ((is_color_different(corner1, centre) || - level_of_recursion < MIN_LEVEL_OF_RECURSION) && - level_of_recursion < MAX_LEVEL_OF_RECURSION) - { - corner1 = GetQuadAverage(x, y, width/2, height/2, pixbuf); - } - - // corner 2 - if ((is_color_different(corner2, centre) || - level_of_recursion < MIN_LEVEL_OF_RECURSION) && - level_of_recursion < MAX_LEVEL_OF_RECURSION) + LOG_DEBUG (logger) << "got a colour image"; + // full colour image + for (int i = 0; i < 11; i++) { - corner2 = GetQuadAverage(x + width/2, y, width/2, height/2, pixbuf); - } - - // corner 3 - if ((is_color_different(corner3, centre) || - level_of_recursion < MIN_LEVEL_OF_RECURSION) && - level_of_recursion < MAX_LEVEL_OF_RECURSION) - { - corner3 = GetQuadAverage(x, y + height/2, width/2, height/2, pixbuf); - } - - // corner 4 - if ((is_color_different(corner4, centre) || - level_of_recursion < MIN_LEVEL_OF_RECURSION) && - level_of_recursion < MAX_LEVEL_OF_RECURSION) - { - corner4 = GetQuadAverage(x + width/2, y + height/2, width/2, height/2, pixbuf); - } + nux::color::HueSaturationValue comparison_hsv (colors[i]); + float color_diff = fabs(base_hsv.hue - comparison_hsv.hue); - nux::Color average = ( (corner1 * 3) - + (corner3 * 3) - + (centre * 2) - + corner2 - + corner4) * 0.1; - level_of_recursion--; - return average; - } - - nux::Color BGHash::HashColor(GdkPixbuf *pixbuf) - { - level_of_recursion = 0; - nux::Color average = GetQuadAverage (0, 0, - gdk_pixbuf_get_width (pixbuf) - 1, - gdk_pixbuf_get_height (pixbuf) - 1, - pixbuf); - nux::Color matched_color = MatchColor (average); - return matched_color; - } - - nux::Color BGHash::MatchColor (const nux::Color base_color) - { - nux::Color colors[12]; - - colors[ 0] = nux::Color (0x540e44); - colors[ 1] = nux::Color (0x6e0b2a); - colors[ 2] = nux::Color (0x841617); - colors[ 3] = nux::Color (0x84371b); - colors[ 4] = nux::Color (0x864d20); - colors[ 5] = nux::Color (0x857f31); - colors[ 6] = nux::Color (0x1d6331); - colors[ 7] = nux::Color (0x11582e); - colors[ 8] = nux::Color (0x0e5955); - colors[ 9] = nux::Color (0x192b59); - colors[10] = nux::Color (0x1b134c); - colors[11] = nux::Color (0x2c0d46); - - float closest_diff = 200.0f; - nux::Color chosen_color; - nux::color::HueSaturationValue base_hsv (base_color); - - if (base_hsv.saturation < 0.08) - { - // grayscale image - LOG_DEBUG (logger) << "got a grayscale image"; - chosen_color = nux::Color (46 , 52 , 54 ); - chosen_color.alpha = 0.72f; - } - else - { - LOG_DEBUG (logger) << "got a colour image"; - // full colour image - for (int i = 0; i < 11; i++) + if (color_diff < closest_diff) { - nux::color::HueSaturationValue comparison_hsv (colors[i]); - float color_diff = fabs(base_hsv.hue - comparison_hsv.hue); - - if (color_diff < closest_diff) - { - chosen_color = colors[i]; - closest_diff = color_diff; - } + chosen_color = colors[i]; + closest_diff = color_diff; } - - nux::color::HueSaturationValue hsv_color (chosen_color); - - 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 + nux::color::HueSaturationValue hsv_color (chosen_color); + hsv_color.saturation = std::min(base_hsv.saturation, hsv_color.saturation); + hsv_color.saturation *= (2.0f - hsv_color.saturation); + hsv_color.value = std::min(std::min(base_hsv.value, hsv_color.value), 0.26f); - LOG_DEBUG(logger) << "eventually chose " - << chosen_color.red << ", " - << chosen_color.green << ", " - << chosen_color.blue; - return chosen_color; + chosen_color = nux::Color (nux::color::RedGreenBlue(hsv_color)); + chosen_color.alpha = 0.72f; } - nux::Color BGHash::CurrentColor () - { - return _current_color; - } + LOG_DEBUG(logger) << "eventually chose " + << chosen_color.red << ", " + << chosen_color.green << ", " + << chosen_color.blue; + return chosen_color; +} + +nux::Color BGHash::CurrentColor () +{ + return _current_color; +} + } diff -Nru unity-5.8.0/plugins/unityshell/src/BGHash.h unity-5.10.0/plugins/unityshell/src/BGHash.h --- unity-5.8.0/plugins/unityshell/src/BGHash.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/BGHash.h 2012-04-12 13:21:21.000000000 +0000 @@ -40,38 +40,26 @@ ~BGHash (); static gboolean ForceUpdate(BGHash *self); - void LoadFileToHash (const std::string path); - void LoadPixbufToHash (GdkPixbuf *pixbuf); - GdkPixbuf *GetPixbufFromBG (); nux::Color CurrentColor (); void OnBackgroundChanged (GnomeBG *bg); void OnGSettingsChanged (GSettings *settings, gchar *key); void OverrideColor (nux::Color color); - + void RefreshColor(); + private: - static gboolean OnSlideshowTransition (BGHash *self); - static gboolean OnTransitionCallback (BGHash *self); gboolean DoTransitionCallback (); + static gboolean OnTransitionCallback (BGHash *self); void DoUbusColorEmit (); void TransitionToNewColor (nux::Color new_color); nux::Color InterpolateColor (nux::Color colora, nux::Color colorb, float value); - nux::Color HashColor(GdkPixbuf *pixbuf); nux::Color MatchColor (nux::Color base_color); - std::string CreateFilepathHash(std::string path); - - void SerializeCache(); - void UnSerializeCache(); private: - GnomeBG *background_monitor; - GSettings *client; + GnomeBG *background_monitor_; + GSettings *client_; guint _transition_handler; - SlideShow *_bg_slideshow; - Slide *_current_slide; - guint _slideshow_handler; - nux::Color _current_color; // the current colour, including steps in transitions nux::Color _new_color; // in transitions, the next colour, otherwise the current colour nux::Color _old_color; // the last colour chosen, used for transitions @@ -83,7 +71,6 @@ glib::SignalManager signal_manager_; uint _ubus_handle_request_colour; - std::map cache_map_; }; }; diff -Nru unity-5.8.0/plugins/unityshell/src/compizminimizedwindowhandler.h unity-5.10.0/plugins/unityshell/src/compizminimizedwindowhandler.h --- unity-5.8.0/plugins/unityshell/src/compizminimizedwindowhandler.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/compizminimizedwindowhandler.h 2012-04-12 13:21:21.000000000 +0000 @@ -298,7 +298,12 @@ if (CompOption::getBoolOptionNamed (o, "active", false)) minimizingWindows.push_back (w); else + { + /* Ugly hack for LP#977189 */ + CompositeWindow::get (w)->release (); + GLWindow::get (w)->release (); minimizingWindows.remove (w); + } } } } diff -Nru unity-5.8.0/plugins/unityshell/src/DashController.cpp unity-5.10.0/plugins/unityshell/src/DashController.cpp --- unity-5.8.0/plugins/unityshell/src/DashController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashController.cpp 2012-04-13 16:25:31.000000000 +0000 @@ -40,19 +40,22 @@ Controller::Controller() : launcher_width(64) , use_primary(false) + , monitor_(0) , window_(0) , visible_(false) , need_show_(false) , timeline_id_(0) , last_opacity_(0.0f) , start_time_(0) + , view_(nullptr) { SetupRelayoutCallbacks(); RegisterUBusInterests(); - ensure_id_ = g_timeout_add_seconds(60, [] (gpointer data) -> gboolean { static_cast(data)->EnsureDash(); return FALSE; }, this); + SetupWindow(); + Settings::Instance().changed.connect([&]() { if (window_) @@ -82,6 +85,12 @@ window_->ShowWindow(false); window_->SetOpacity(0.0f); window_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow)); + + /* FIXME - first time we load our windows there is a race that causes the input window not to actually get input, this side steps that by causing an input window show and hide before we really need it. */ + PluginAdapter::Default()->saveInputFocus (); + window_->EnableInputWindow(true, "Dash", true, false); + window_->EnableInputWindow(false, "Dash", true, false); + PluginAdapter::Default()->restoreInputFocus (); } void Controller::SetupDashView() @@ -126,7 +135,7 @@ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); // hide if something else is coming up - if (g_strcmp0(overlay_identity, "dash")) + if (overlay_identity.Str() != "dash") { HideDash(true); } @@ -135,17 +144,18 @@ void Controller::EnsureDash() { - if (window_) - return; - LOG_DEBUG(logger) << "Initializing Dash"; + if (!window_) + SetupWindow(); - SetupWindow(); - SetupDashView(); - Relayout(); - ensure_id_ = 0; + if (!view_) + { + SetupDashView(); + Relayout(); + ensure_id_ = 0; - on_realize.emit(); + on_realize.emit(); + } } nux::BaseWindow* Controller::window() const @@ -272,7 +282,8 @@ StartShowHideTimeline(); - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor()); + monitor_ = GetIdealMonitor(); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_); ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info); } @@ -298,7 +309,7 @@ StartShowHideTimeline(); - GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor()); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_); ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info); } @@ -382,7 +393,8 @@ void Controller::AddProperties(GVariantBuilder* builder) { - g_variant_builder_add (builder, "{sv}", "visible", g_variant_new_boolean (visible_) ); + variant::BuilderWrapper(builder).add("visible", visible_) + .add("monitor", monitor_); } diff -Nru unity-5.8.0/plugins/unityshell/src/DashController.h unity-5.10.0/plugins/unityshell/src/DashController.h --- unity-5.8.0/plugins/unityshell/src/DashController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashController.h 2012-04-12 13:21:21.000000000 +0000 @@ -56,6 +56,8 @@ sigc::signal on_realize; + void HideDash(bool restore_focus = true); + protected: std::string GetName() const; void AddProperties(GVariantBuilder* builder); @@ -78,7 +80,6 @@ void OnActivateRequest(GVariant* variant); void ShowDash(); - void HideDash(bool restore_focus = true); void StartShowHideTimeline(); static gboolean OnViewShowHideFrame(Controller* self); @@ -88,6 +89,7 @@ private: glib::SignalManager sig_manager_; UBusManager ubus_manager_; + int monitor_; nux::BaseWindow* window_; bool visible_; diff -Nru unity-5.8.0/plugins/unityshell/src/DashStyle.cpp unity-5.10.0/plugins/unityshell/src/DashStyle.cpp --- unity-5.8.0/plugins/unityshell/src/DashStyle.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashStyle.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -194,13 +194,18 @@ int number_of_columns_; LazyLoadTexture dash_bottom_texture_; + LazyLoadTexture dash_bottom_texture_mask_; LazyLoadTexture dash_right_texture_; + LazyLoadTexture dash_right_texture_mask_; LazyLoadTexture dash_corner_texture_; + LazyLoadTexture dash_corner_texture_mask_; LazyLoadTexture dash_fullscreen_icon_; LazyLoadTexture dash_left_edge_; LazyLoadTexture dash_left_corner_; + LazyLoadTexture dash_left_corner_mask_; LazyLoadTexture dash_left_tile_; LazyLoadTexture dash_top_corner_; + LazyLoadTexture dash_top_corner_mask_; LazyLoadTexture dash_top_tile_; LazyLoadTexture dash_shine_; @@ -232,13 +237,18 @@ , text_height_(0) , number_of_columns_(6) , dash_bottom_texture_("/dash_bottom_border_tile.png") + , dash_bottom_texture_mask_("/dash_bottom_border_tile_mask.png") , dash_right_texture_("/dash_right_border_tile.png") + , dash_right_texture_mask_("/dash_right_border_tile_mask.png") , dash_corner_texture_("/dash_bottom_right_corner.png") + , dash_corner_texture_mask_("/dash_bottom_right_corner_mask.png") , dash_fullscreen_icon_("/dash_fullscreen_icon.png") , dash_left_edge_("/dash_left_edge.png") , dash_left_corner_("/dash_bottom_left_corner.png") + , dash_left_corner_mask_("/dash_bottom_left_corner_mask.png") , dash_left_tile_("/dash_left_tile.png") , dash_top_corner_("/dash_top_right_corner.png") + , dash_top_corner_mask_("/dash_top_right_corner_mask.png") , dash_top_tile_("/dash_top_tile.png") , dash_shine_("/dash_sheen.png") , search_magnify_texture_("/search_magnify.png") @@ -2060,16 +2070,30 @@ return pimpl->dash_bottom_texture_.texture(); } +nux::BaseTexture* Style::GetDashBottomTileMask() +{ + return pimpl->dash_bottom_texture_mask_.texture(); +} + nux::BaseTexture* Style::GetDashRightTile() { return pimpl->dash_right_texture_.texture(); } +nux::BaseTexture* Style::GetDashRightTileMask() +{ + return pimpl->dash_right_texture_mask_.texture(); +} + nux::BaseTexture* Style::GetDashCorner() { return pimpl->dash_corner_texture_.texture(); } +nux::BaseTexture* Style::GetDashCornerMask() +{ + return pimpl->dash_corner_texture_mask_.texture(); +} nux::BaseTexture* Style::GetDashLeftEdge() { @@ -2081,6 +2105,11 @@ return pimpl->dash_left_corner_.texture(); } +nux::BaseTexture* Style::GetDashLeftCornerMask() +{ + return pimpl->dash_left_corner_mask_.texture(); +} + nux::BaseTexture* Style::GetDashLeftTile() { return pimpl->dash_left_tile_.texture(); @@ -2091,6 +2120,11 @@ return pimpl->dash_top_corner_.texture(); } +nux::BaseTexture* Style::GetDashTopCornerMask() +{ + return pimpl->dash_top_corner_mask_.texture(); +} + nux::BaseTexture* Style::GetDashTopTile() { return pimpl->dash_top_tile_.texture(); @@ -2235,7 +2269,7 @@ int Style::GetSpaceBetweenLensAndFilters() const { - return 9; + return 10; } int Style::GetFilterViewRightPadding() const diff -Nru unity-5.8.0/plugins/unityshell/src/DashStyle.h unity-5.10.0/plugins/unityshell/src/DashStyle.h --- unity-5.8.0/plugins/unityshell/src/DashStyle.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashStyle.h 2012-04-12 13:21:21.000000000 +0000 @@ -166,13 +166,18 @@ int GetTextLineHeight() const; nux::BaseTexture* GetDashBottomTile(); + nux::BaseTexture* GetDashBottomTileMask(); nux::BaseTexture* GetDashRightTile(); + nux::BaseTexture* GetDashRightTileMask(); nux::BaseTexture* GetDashCorner(); + nux::BaseTexture* GetDashCornerMask(); nux::BaseTexture* GetDashFullscreenIcon(); nux::BaseTexture* GetDashLeftEdge(); nux::BaseTexture* GetDashLeftCorner(); + nux::BaseTexture* GetDashLeftCornerMask(); nux::BaseTexture* GetDashLeftTile(); nux::BaseTexture* GetDashTopCorner(); + nux::BaseTexture* GetDashTopCornerMask(); nux::BaseTexture* GetDashTopTile(); nux::BaseTexture* GetDashShine(); @@ -228,8 +233,6 @@ int GetCategorySeparatorLeftPadding() const; int GetCategorySeparatorRightPadding() const; - const static int SEARCH_BAR_EXTRA_PADDING = 1; - sigc::signal changed; private: diff -Nru unity-5.8.0/plugins/unityshell/src/DashView.cpp unity-5.10.0/plugins/unityshell/src/DashView.cpp --- unity-5.8.0/plugins/unityshell/src/DashView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashView.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -146,6 +146,9 @@ active_lens_view_->lens()->view_type = ViewType::LENS_VIEW; } + // this will make sure the spinner animates if the search takes a while + search_bar_->ForceSearchChanged(); + renderer_.AboutToShow(); } @@ -176,17 +179,17 @@ SetLayout(layout_); content_layout_ = new DashLayout(NUX_TRACKER_LOCATION); - content_layout_->SetTopAndBottomPadding(style.GetDashViewTopPadding() - style.SEARCH_BAR_EXTRA_PADDING, 0); + content_layout_->SetTopAndBottomPadding(style.GetDashViewTopPadding(), 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); + search_bar_layout_->SetLeftAndRightPadding(style.GetSearchBarLeftPadding(), 0); 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_->SetMinimumHeight(style.GetSearchBarHeight()); + search_bar_->SetMaximumHeight(style.GetSearchBarHeight()); 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)); @@ -269,12 +272,14 @@ width = MAX(width, tile_width * 6); - width += 19 + 40; // add the left padding and the group plugin padding + width += 20 + 40; // add the left padding and the group plugin padding height = search_bar_->GetGeometry().height; height += tile_height * 3; - height += 46 * 3; // adding three group headers - //height += lens_bar_->GetGeometry().height; + height += (style.GetPlacesGroupTopSpace() - 2 + 24 + 8) * 3; // adding three group headers + height += 1*2; // hseparator height + height += style.GetDashViewTopPadding(); + height += lens_bar_->GetGeometry().height; if (for_geo.width > 800 && for_geo.height > 550) { @@ -436,7 +441,7 @@ LOG_DEBUG(logger) << "Live search reached: " << search_string; if (active_lens_view_) { - active_lens_view_->search_string = search_string; + active_lens_view_->PerformSearch(search_string); } } @@ -454,7 +459,26 @@ lens->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply)); lens->search_finished.connect(sigc::mem_fun(this, &DashView::OnSearchFinished)); + lens->connected.changed.connect([&] (bool value) + { + std::string const& search_string = search_bar_->search_string; + if (value && lens->search_in_global && active_lens_view_ == home_view_ + && !search_string.empty()) + { + // force a (global!) search with the correct string + lens->GlobalSearch(search_bar_->search_string); + } + }); + // global search done is handled by the home lens, no need to connect to it + // BUT, we will special case global search finished coming from + // the applications lens, because we want to be able to launch applications + // immediately without waiting for the search finished signal which will + // be delayed by all the lenses we're searching + if (id == "applications.lens") + { + lens->global_search_finished.connect(sigc::mem_fun(this, &DashView::OnAppsGlobalSearchFinished)); + } } void DashView::OnLensBarActivated(std::string const& id) @@ -481,6 +505,10 @@ search_bar_->search_string = view->search_string; search_bar_->search_hint = view->lens()->search_hint; + // lenses typically return immediately from Search() if the search query + // doesn't change, so SearchFinished will be called in a few ms + // FIXME: if we're forcing a search here, why don't we get rid of view types? + search_bar_->ForceSearchChanged(); bool expanded = view->filters_expanded; search_bar_->showing_filters = expanded; @@ -529,6 +557,22 @@ OnSearchFinished(hints); } +void DashView::OnAppsGlobalSearchFinished(Lens::Hints const& hints) +{ + if (active_lens_view_ == home_view_) + { + /* HACKITY HACK! We're resetting the state of search_in_progress when + * doing searches in the home lens and we get results from apps lens. + * This way typing a search query and pressing enter immediately will + * wait for the apps lens results and will run correct application. + * See lp:966417 and lp:856206 for more info about why we do this. + */ + search_in_progress_ = false; + if (activate_on_finish_) + this->OnEntryActivated(); + } +} + void DashView::OnUriActivated(std::string const& uri) { last_activated_uri_ = uri; @@ -698,8 +742,16 @@ if (active_lens_view_) num_rows += active_lens_view_->GetNumRows(); + std::string form_factor("unknown"); + + if (Settings::Instance().GetFormFactor() == FormFactor::NETBOOK) + form_factor = "netbook"; + else if (Settings::Instance().GetFormFactor() == FormFactor::DESKTOP) + form_factor = "desktop"; + unity::variant::BuilderWrapper wrapper(builder); - wrapper.add("num-rows", num_rows); + wrapper.add("num_rows", num_rows); + wrapper.add("form_factor", form_factor); } nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction) @@ -780,7 +832,7 @@ // DashView::KeyNavIteration. nux::InputArea* focus_area = nux::GetWindowCompositor().GetKeyFocusArea(); - if (key_symbol == nux::NUX_KEYDOWN) + if (key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit) { std::list tabs; for (auto category : active_lens_view_->categories()) @@ -855,7 +907,7 @@ } } - if (direction == KEY_NAV_NONE || search_bar_->im_active) + if (direction == KEY_NAV_NONE || search_bar_->im_preedit) { // then send the event to the search entry return search_bar_->text_entry(); diff -Nru unity-5.8.0/plugins/unityshell/src/DashView.h unity-5.10.0/plugins/unityshell/src/DashView.h --- unity-5.8.0/plugins/unityshell/src/DashView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DashView.h 2012-04-12 13:21:21.000000000 +0000 @@ -90,6 +90,7 @@ void OnLensBarActivated(std::string const& id); void OnSearchFinished(Lens::Hints const& hints); void OnGlobalSearchFinished(Lens::Hints const& hints); + void OnAppsGlobalSearchFinished(Lens::Hints const& hints); void OnUriActivated(std::string const& uri); void OnUriActivatedReply(std::string const& uri, HandledType type, Lens::Hints const&); bool DoFallbackActivation(std::string const& uri); diff -Nru unity-5.8.0/plugins/unityshell/src/DeviceLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/DeviceLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/DeviceLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DeviceLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -64,11 +64,12 @@ void DeviceLauncherIcon::UpdateDeviceIcon() { - glib::String name(g_volume_get_name(volume_)); + name_ = glib::String(g_volume_get_name(volume_)).Str(); + glib::Object icon(g_volume_get_icon(volume_)); glib::String icon_string(g_icon_to_string(icon)); - tooltip_text = name.Str(); + tooltip_text = name_; icon_name = icon_string.Str(); SetIconType(TYPE_DEVICE); @@ -206,8 +207,6 @@ void DeviceLauncherIcon::ShowMount(GMount* mount) { - glib::String name(g_volume_get_name(volume_)); - if (G_IS_MOUNT(mount)) { glib::Object root(g_mount_get_root(mount)); @@ -221,20 +220,20 @@ if (error) { - LOG_WARNING(logger) << "Cannot open volume '" << name + LOG_WARNING(logger) << "Cannot open volume '" << name_ << "': Unable to show " << uri << ": " << error; } } else { - LOG_WARNING(logger) << "Cannot open volume '" << name + LOG_WARNING(logger) << "Cannot open volume '" << name_ << "': Mount has no root"; } } else { - LOG_WARNING(logger) << "Cannot open volume '" << name + LOG_WARNING(logger) << "Cannot open volume '" << name_ << "': Mount-point is invalid"; } } @@ -270,11 +269,8 @@ } else { - glib::String name(g_volume_get_name(self->volume_)); - - g_warning("Cannot open volume '%s': %s", - name.Value(), - error ? error.Message().c_str() : "Mount operation failed"); + LOG_WARNING(logger) << "Cannot open volume '" << self->name_ << "' : " << + (error ? error.Message() : "Mount operation failed"); } } @@ -285,17 +281,16 @@ if (g_volume_eject_with_operation_finish(self->volume_, result, NULL)) { IconLoader::GetDefault().LoadFromGIconString(self->icon_name(), 48, - sigc::mem_fun(self, &DeviceLauncherIcon::ShowNotification)); + sigc::bind(sigc::mem_fun(self, &DeviceLauncherIcon::ShowNotification), self->name_)); } } void DeviceLauncherIcon::ShowNotification(std::string const& icon_name, unsigned size, - GdkPixbuf* pixbuf) + GdkPixbuf* pixbuf, + std::string const& name) { - - glib::String name(g_volume_get_name(volume_)); - glib::Object notification(notify_notification_new(name, + glib::Object notification(notify_notification_new(name.c_str(), _("The drive has been successfully ejected"), NULL)); diff -Nru unity-5.8.0/plugins/unityshell/src/DeviceLauncherIcon.h unity-5.10.0/plugins/unityshell/src/DeviceLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/DeviceLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/DeviceLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -64,11 +64,12 @@ static void OnUnmountReady(GObject* object, GAsyncResult* result, DeviceLauncherIcon* self); static void OnDriveStop(DbusmenuMenuitem* item, int time, DeviceLauncherIcon* self); void OnSettingsChanged(); - void ShowNotification(std::string const& icon_name, unsigned size, GdkPixbuf* pixbuf); + void ShowNotification(std::string const&, unsigned, GdkPixbuf*, std::string const&); private: GVolume* volume_; glib::String device_file_; + std::string name_; glib::Object gdu_device_; bool keep_in_launcher_; }; diff -Nru unity-5.8.0/plugins/unityshell/src/EdgeBarrierController.cpp unity-5.10.0/plugins/unityshell/src/EdgeBarrierController.cpp --- unity-5.8.0/plugins/unityshell/src/EdgeBarrierController.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/EdgeBarrierController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,189 @@ +// -*- 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: Jason Smith + */ + +#include "EdgeBarrierController.h" +#include "Decaymulator.h" +#include "UScreen.h" + +namespace unity { +namespace ui { + +struct EdgeBarrierController::Impl +{ + Impl(EdgeBarrierController *parent); + ~Impl(); + + void ResizeBarrierList(std::vector const& layout); + void SetupBarriers(std::vector const& layout); + + void OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); + + std::vector barriers_; + Decaymulator::Ptr decaymulator_; + float edge_overcome_pressure_; + EdgeBarrierController* parent_; + std::vector subscribers_; +}; + +EdgeBarrierController::Impl::Impl(EdgeBarrierController *parent) + : decaymulator_(Decaymulator::Ptr(new Decaymulator())) + , edge_overcome_pressure_(0) + , parent_(parent) +{ + UScreen *uscreen = UScreen::GetDefault(); + + auto monitors = uscreen->GetMonitors(); + ResizeBarrierList(monitors); + + uscreen->changed.connect([&](int primary, std::vector& layout) { + ResizeBarrierList(layout); + SetupBarriers(layout); + }); + + parent_->sticky_edges.changed.connect([&](bool value) { + SetupBarriers(UScreen::GetDefault()->GetMonitors()); + }); + + parent_->options.changed.connect([&](launcher::Options::Ptr options) { + options->option_changed.connect([&]() { + SetupBarriers(UScreen::GetDefault()->GetMonitors()); + }); + SetupBarriers(UScreen::GetDefault()->GetMonitors()); + }); +} + +EdgeBarrierController::Impl::~Impl() +{ + +} + +void EdgeBarrierController::Impl::ResizeBarrierList(std::vector const& layout) +{ + size_t num_monitors = layout.size(); + if (barriers_.size() > num_monitors) + { + barriers_.resize(num_monitors); + } + + while (barriers_.size() < num_monitors) + { + auto barrier = PointerBarrierWrapper::Ptr(new PointerBarrierWrapper()); + barrier->barrier_event.connect(sigc::mem_fun(this, &EdgeBarrierController::Impl::OnPointerBarrierEvent)); + barriers_.push_back(barrier); + } +} + +void EdgeBarrierController::Impl::SetupBarriers(std::vector const& layout) +{ + bool edge_resist = parent_->options()->edge_resist(); + + size_t size = layout.size(); + for (size_t i = 0; i < size; i++) + { + auto barrier = barriers_[i]; + auto monitor = layout[i]; + + barrier->DestroyBarrier(); + + if (!edge_resist && (subscribers_[i] == nullptr || parent_->options()->hide_mode() == launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER)) + continue; + + barrier->x1 = monitor.x; + barrier->x2 = monitor.x; + barrier->y1 = monitor.y; + barrier->y2 = monitor.y + monitor.height; + barrier->index = i; + + barrier->threshold = parent_->options()->edge_stop_velocity(); + barrier->max_velocity_multiplier = parent_->options()->edge_responsiveness(); + + if (edge_resist) + barrier->direction = BarrierDirection::BOTH; + else + barrier->direction = BarrierDirection::LEFT; + + barrier->ConstructBarrier(); + } + + float decay_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * .3f) + 1; + decaymulator_->rate_of_decay = parent_->options()->edge_decay_rate() * decay_responsiveness_mult; + + float overcome_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * 1.0f) + 1; + edge_overcome_pressure_ = parent_->options()->edge_overcome_pressure() * overcome_responsiveness_mult; +} + +void EdgeBarrierController::Impl::OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) +{ + int monitor = owner->index; + bool process = true; + + if ((size_t)monitor <= subscribers_.size()) + { + auto subscriber = subscribers_[monitor]; + if (subscriber && subscriber->HandleBarrierEvent(owner, event)) + process = false; + } + + if (process && owner->x1 > 0) + { + decaymulator_->value = decaymulator_->value + event->velocity; + if (decaymulator_->value > edge_overcome_pressure_ || !parent_->options()->edge_resist()) + { + owner->ReleaseBarrier(event->event_id); + decaymulator_->value = 0; + } + } + else + { + decaymulator_->value = 0; + } +} + +EdgeBarrierController::EdgeBarrierController() + : sticky_edges(false) + , pimpl(new Impl(this)) +{ +} + +EdgeBarrierController::~EdgeBarrierController() +{ + +} + +void EdgeBarrierController::Subscribe(EdgeBarrierSubscriber* subscriber, int monitor) +{ + if (pimpl->subscribers_.size() <= (size_t)monitor) + pimpl->subscribers_.resize(monitor + 1); + pimpl->subscribers_[monitor] = subscriber; + + pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); +} + +void EdgeBarrierController::Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor) +{ + if (pimpl->subscribers_.size() < (size_t)monitor || pimpl->subscribers_[monitor] != subscriber) + return; + pimpl->subscribers_[monitor] = nullptr; + + pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); +} + + +} +} diff -Nru unity-5.8.0/plugins/unityshell/src/EdgeBarrierController.h unity-5.10.0/plugins/unityshell/src/EdgeBarrierController.h --- unity-5.8.0/plugins/unityshell/src/EdgeBarrierController.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/EdgeBarrierController.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,57 @@ +// -*- 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: Jason Smith + */ + +#ifndef UNITY_EDGEBARRIERCONTROLLER_H +#define UNITY_EDGEBARRIERCONTROLLER_H + +#include "PointerBarrier.h" +#include "LauncherOptions.h" + +namespace unity { +namespace ui { + +class EdgeBarrierSubscriber +{ +public: + virtual bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) { return false; }; +}; + +class EdgeBarrierController : public sigc::trackable +{ +public: + typedef std::shared_ptr Ptr; + + EdgeBarrierController(); + ~EdgeBarrierController(); + + nux::Property sticky_edges; + nux::Property options; + + void Subscribe(EdgeBarrierSubscriber* subscriber, int monitor); + void Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor); + +private: + struct Impl; + Impl* pimpl; +}; + +} +} + +#endif diff -Nru unity-5.8.0/plugins/unityshell/src/FavoriteStore.cpp unity-5.10.0/plugins/unityshell/src/FavoriteStore.cpp --- unity-5.8.0/plugins/unityshell/src/FavoriteStore.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FavoriteStore.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -17,20 +17,43 @@ * Authored by: Neil Jagdish Patel */ +#include #include "FavoriteStoreGSettings.h" namespace unity { +namespace +{ + nux::logging::Logger logger("unity.favouritestore"); + FavoriteStore* favoritestore_instance = nullptr; +} + +FavoriteStore::FavoriteStore() +{ + if (favoritestore_instance) + { + LOG_ERROR(logger) << "More than one FavoriteStore created!"; + } + else + { + favoritestore_instance = this; + } +} FavoriteStore::~FavoriteStore() { + if (favoritestore_instance == this) + favoritestore_instance = nullptr; } -FavoriteStore& FavoriteStore::GetDefault() +FavoriteStore& FavoriteStore::Instance() { - static internal::FavoriteStoreGSettings instance; - return instance; + if (! favoritestore_instance) + { + LOG_ERROR(logger) << "No FavoriteStore instance created yet!"; + } + return *favoritestore_instance; } } diff -Nru unity-5.8.0/plugins/unityshell/src/FavoriteStoreGSettings.cpp unity-5.10.0/plugins/unityshell/src/FavoriteStoreGSettings.cpp --- unity-5.8.0/plugins/unityshell/src/FavoriteStoreGSettings.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FavoriteStoreGSettings.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -17,10 +17,9 @@ * Authored by: Neil Jagdish Patel */ -#include - #include #include +#include #include "FavoriteStoreGSettings.h" #include "FavoriteStorePrivate.h" @@ -51,8 +50,6 @@ const gchar* key, FavoriteStoreGSettings* self); -std::string get_basename_or_path(std::string const& desktop_path); - } FavoriteStoreGSettings::FavoriteStoreGSettings() @@ -234,6 +231,7 @@ int index = 0; // Since we don't always save the full path, we store the values we are // actually going to save in a different list. + auto system_dirs = DesktopUtilities::GetDataDirectories(); FavoriteList values; for (FavoriteList::const_iterator i = favorites.begin(), end = favorites.end(); i != end; ++i, ++index) @@ -243,7 +241,8 @@ // the string that we are going to save. This way we know that the pointer // is valid for the lifetime of the favs array usage in the method call to // set the settings, and that we aren't referencing a temporary. - FavoriteList::iterator iter = values.insert(values.end(), get_basename_or_path(*i)); + std::string const& desktop_id = DesktopUtilities::GetDesktopID(system_dirs, *i); + FavoriteList::iterator iter = values.insert(values.end(), desktop_id); favs[index] = iter->c_str(); } @@ -259,7 +258,7 @@ { if (ignore_signals_ or key != "favorites") return; - + FavoriteList old(favorites_); FillList(favorites_); @@ -269,22 +268,22 @@ { if (std::find(newbies.begin(), newbies.end(), it) == newbies.end()) continue; - + std::string pos; bool before; - + impl::GetSignalAddedInfo(favorites_, newbies , it, pos, before); favorite_added.emit(it, pos, before); } - + for (auto it : impl::GetRemoved(old, favorites_)) { - favorite_removed.emit(it); + favorite_removed.emit(it); } - + if (impl::NeedToBeReordered(old, favorites_)) reordered.emit(); - + } namespace @@ -300,35 +299,6 @@ } } -std::string get_basename_or_path(std::string const& desktop_path) -{ - const gchar* const* dirs = g_get_system_data_dirs(); - - /* We check to see if the desktop file belongs to one of the system data - * directories. If so, then we store it's desktop id, otherwise we store - * it's full path. We're clever like that. - */ - for (int i = 0; dirs[i]; ++i) - { - std::string dir(dirs[i]); - if (dir.at(dir.length()-1) == G_DIR_SEPARATOR) - dir.append("applications/"); - else - dir.append("/applications/"); - - if (desktop_path.find(dir) == 0) - { - // if we are in a subdirectory of system patch, the store name should - // be subdir-filename.desktop - std::string desktop_suffix = desktop_path.substr(dir.size()); - std::replace(desktop_suffix.begin(), desktop_suffix.end(), G_DIR_SEPARATOR, '-'); - return desktop_suffix; - } - } - return desktop_path; -} - - } // anonymous namespace } // namespace internal diff -Nru unity-5.8.0/plugins/unityshell/src/FavoriteStore.h unity-5.10.0/plugins/unityshell/src/FavoriteStore.h --- unity-5.8.0/plugins/unityshell/src/FavoriteStore.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FavoriteStore.h 2012-04-12 13:21:21.000000000 +0000 @@ -37,9 +37,10 @@ class FavoriteStore : public sigc::trackable, boost::noncopyable { public: + FavoriteStore(); virtual ~FavoriteStore(); - static FavoriteStore& GetDefault(); + static FavoriteStore& Instance(); virtual FavoriteList const& GetFavorites() = 0; diff -Nru unity-5.8.0/plugins/unityshell/src/FavoriteStorePrivate.h unity-5.10.0/plugins/unityshell/src/FavoriteStorePrivate.h --- unity-5.8.0/plugins/unityshell/src/FavoriteStorePrivate.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FavoriteStorePrivate.h 2012-04-12 13:21:21.000000000 +0000 @@ -39,6 +39,7 @@ bool NeedToBeReordered(std::list const& old, std::list const& fresh); + } // namespace impl } // namespace internal } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/FilterBar.cpp unity-5.10.0/plugins/unityshell/src/FilterBar.cpp --- unity-5.8.0/plugins/unityshell/src/FilterBar.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FilterBar.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -60,7 +60,7 @@ dash::Style& style = dash::Style::Instance(); nux::LinearLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); - layout->SetTopAndBottomPadding(style.GetFilterBarTopPadding() - style.GetFilterHighlightPadding() - style.SEARCH_BAR_EXTRA_PADDING); + layout->SetTopAndBottomPadding(style.GetFilterBarTopPadding() - style.GetFilterHighlightPadding()); layout->SetSpaceBetweenChildren(style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding()); SetLayout(layout); } diff -Nru unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.cpp unity-5.10.0/plugins/unityshell/src/FilterExpanderLabel.cpp --- unity-5.8.0/plugins/unityshell/src/FilterExpanderLabel.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/FilterExpanderLabel.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -116,7 +116,7 @@ } else if (!value and separator_->IsChildOf(layout_)) { - layout_->AddLayout(space_, 0); + layout_->RemoveChildObject(space_); layout_->RemoveChildObject(separator_); } QueueDraw(); diff -Nru unity-5.8.0/plugins/unityshell/src/GeisAdapter.cpp unity-5.10.0/plugins/unityshell/src/GeisAdapter.cpp --- unity-5.8.0/plugins/unityshell/src/GeisAdapter.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/GeisAdapter.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -19,21 +19,36 @@ #include #include +#include #include "GeisAdapter.h" -GeisAdapter* GeisAdapter::_default = 0; +namespace +{ + GeisAdapter* adaptor_instance = nullptr; + nux::logging::Logger logger("unity.geisadapter"); +} /* static */ -GeisAdapter* -GeisAdapter::Default() +GeisAdapter& GeisAdapter::Instance() { - if (!_default) - return _default = new GeisAdapter(); // should be using a dictionary - return _default; + if (!adaptor_instance) + { + LOG_ERROR(logger) << "No GeisAdapter created yet."; + } + + return *adaptor_instance; } GeisAdapter::GeisAdapter() : _root_instance(nullptr) { + if (adaptor_instance) + { + LOG_ERROR(logger) << "More than one GeisAdapter created."; + } + else + { + adaptor_instance = this; + } RegisterRootInstance(); } @@ -41,6 +56,10 @@ { if (_root_instance != nullptr) geis_finish(_root_instance); + if (adaptor_instance == this) + { + adaptor_instance = nullptr; + } } void @@ -237,9 +256,9 @@ else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) result->timestamp = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) - result->focus_x = attr.integer_val; + result->focus_x = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) - result->focus_y = attr.integer_val; + result->focus_y = attr.float_val; else if (g_str_equal (attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES)) result->touches = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_GESTURE_NAME)) @@ -289,9 +308,9 @@ else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) result->timestamp = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) - result->focus_x = attr.integer_val; + result->focus_x = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) - result->focus_y = attr.integer_val; + result->focus_y = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES)) result->touches = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1)) @@ -322,9 +341,9 @@ else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) result->timestamp = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) - result->focus_x = attr.integer_val; + result->focus_x = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) - result->focus_y = attr.integer_val; + result->focus_y = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES)) result->touches = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_POSITION_X)) @@ -367,9 +386,9 @@ else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) result->timestamp = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) - result->focus_x = attr.integer_val; + result->focus_x = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) - result->focus_y = attr.integer_val; + result->focus_y = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES)) result->touches = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_RADIUS)) @@ -406,9 +425,9 @@ else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) result->timestamp = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) - result->focus_x = attr.integer_val; + result->focus_x = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) - result->focus_y = attr.integer_val; + result->focus_y = attr.float_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES)) result->touches = attr.integer_val; else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_ANGLE)) diff -Nru unity-5.8.0/plugins/unityshell/src/GeisAdapter.h unity-5.10.0/plugins/unityshell/src/GeisAdapter.h --- unity-5.8.0/plugins/unityshell/src/GeisAdapter.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/GeisAdapter.h 2012-04-12 13:21:21.000000000 +0000 @@ -28,8 +28,9 @@ class GeisAdapter : public sigc::trackable { public: - static GeisAdapter* Default(); + static GeisAdapter& Instance(); + GeisAdapter(); ~GeisAdapter(); void Run(); @@ -41,8 +42,8 @@ Window window; int touches; int timestamp; - int focus_x; - int focus_y; + float focus_x; + float focus_y; int tap_length_ms; float position_x; float position_y; @@ -59,8 +60,8 @@ Window window; int touches; int timestamp; - int focus_x; - int focus_y; + float focus_x; + float focus_y; float delta_x; float delta_y; float velocity_x; @@ -80,8 +81,8 @@ Window window; int touches; int timestamp; - int focus_x; - int focus_y; + float focus_x; + float focus_y; float angle; float angle_delta; float angle_velocity; @@ -98,8 +99,8 @@ Window window; int touches; int timestamp; - int focus_x; - int focus_y; + float focus_x; + float focus_y; float radius; float radius_delta; float radius_velocity; @@ -116,8 +117,8 @@ Window window; int touches; int timestamp; - int focus_x; - int focus_y; + float focus_x; + float focus_y; float bound_x1; float bound_y1; float bound_x2; @@ -142,8 +143,6 @@ sigc::signal touch_update; sigc::signal touch_finish; protected: - GeisAdapter(); - static gboolean OnWatchIn(GIOChannel* source, GIOCondition condition, gpointer data); static void InputDeviceAdded(void* cookie, GeisInputDeviceId device_id, void* attrs); @@ -167,11 +166,7 @@ void RegisterRootInstance(); GeisInstance _root_instance; - guint _watch_id; - - static GeisAdapter* _default; - }; #endif diff -Nru unity-5.8.0/plugins/unityshell/src/GestureEngine.cpp unity-5.10.0/plugins/unityshell/src/GestureEngine.cpp --- unity-5.8.0/plugins/unityshell/src/GestureEngine.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/GestureEngine.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -38,25 +38,25 @@ _pinch_grab = 0; _fleur_cursor = XCreateFontCursor (screen->dpy (), XC_fleur); - GeisAdapter* adapter = GeisAdapter::Default(); + GeisAdapter& adapter = GeisAdapter::Instance(); - adapter->tap.connect(sigc::mem_fun(this, &GestureEngine::OnTap)); + adapter.tap.connect(sigc::mem_fun(this, &GestureEngine::OnTap)); - adapter->drag_start.connect(sigc::mem_fun(this, &GestureEngine::OnDragStart)); - adapter->drag_update.connect(sigc::mem_fun(this, &GestureEngine::OnDragUpdate)); - adapter->drag_finish.connect(sigc::mem_fun(this, &GestureEngine::OnDragFinish)); + adapter.drag_start.connect(sigc::mem_fun(this, &GestureEngine::OnDragStart)); + adapter.drag_update.connect(sigc::mem_fun(this, &GestureEngine::OnDragUpdate)); + adapter.drag_finish.connect(sigc::mem_fun(this, &GestureEngine::OnDragFinish)); - adapter->rotate_start.connect(sigc::mem_fun(this, &GestureEngine::OnRotateStart)); - adapter->rotate_update.connect(sigc::mem_fun(this, &GestureEngine::OnRotateUpdate)); - adapter->rotate_finish.connect(sigc::mem_fun(this, &GestureEngine::OnRotateFinish)); + adapter.rotate_start.connect(sigc::mem_fun(this, &GestureEngine::OnRotateStart)); + adapter.rotate_update.connect(sigc::mem_fun(this, &GestureEngine::OnRotateUpdate)); + adapter.rotate_finish.connect(sigc::mem_fun(this, &GestureEngine::OnRotateFinish)); - adapter->pinch_start.connect(sigc::mem_fun(this, &GestureEngine::OnPinchStart)); - adapter->pinch_update.connect(sigc::mem_fun(this, &GestureEngine::OnPinchUpdate)); - adapter->pinch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnPinchFinish)); + adapter.pinch_start.connect(sigc::mem_fun(this, &GestureEngine::OnPinchStart)); + adapter.pinch_update.connect(sigc::mem_fun(this, &GestureEngine::OnPinchUpdate)); + adapter.pinch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnPinchFinish)); - adapter->touch_start.connect(sigc::mem_fun(this, &GestureEngine::OnTouchStart)); - adapter->touch_update.connect(sigc::mem_fun(this, &GestureEngine::OnTouchUpdate)); - adapter->touch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnTouchFinish)); + adapter.touch_start.connect(sigc::mem_fun(this, &GestureEngine::OnTouchStart)); + adapter.touch_update.connect(sigc::mem_fun(this, &GestureEngine::OnTouchUpdate)); + adapter.touch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnTouchFinish)); } GestureEngine::~GestureEngine() @@ -75,44 +75,26 @@ } } -CompWindow* -GestureEngine::FindCompWindow(Window window) +CompWindow* GestureEngine::FindCompWindowAtPos(float fpos_x, float fpos_y) { - CompWindow* result = _screen->findTopLevelWindow(window); + const CompWindowVector& client_list_stacking = _screen->clientList(true); - while (!result) - { - Window parent, root; - Window* children = NULL; - unsigned int nchildren; - Status status; - - status = XQueryTree(_screen->dpy(), window, &root, &parent, &children, &nchildren); - if (status == 0) - break; - - if (children) - XFree(children); - - // parent will be zero when the window passed to this method is already the - // root one. - if (parent == root || parent == 0) - break; + int pos_x = fpos_x; + int pos_y = fpos_y; - window = parent; - result = _screen->findTopLevelWindow(window); - } - - if (result) + for (auto iter = client_list_stacking.rbegin(), + end = client_list_stacking.rend(); + iter != end; ++iter) { - if (!(result->type() & (CompWindowTypeUtilMask | - CompWindowTypeNormalMask | - CompWindowTypeDialogMask | - CompWindowTypeModalDialogMask))) - result = 0; + CompWindow* window = *iter; + + if (pos_x >= window->x() && pos_x <= (window->width() + window->x()) + && + pos_y >= window->y() && pos_y <= (window->height() + window->y())) + return window; } - return result; + return nullptr; } void @@ -120,7 +102,7 @@ { if (data->touches == 3) { - _drag_window = FindCompWindow(data->window); + _drag_window = FindCompWindowAtPos(data->focus_x, data->focus_y); if (!_drag_window) @@ -222,7 +204,7 @@ { if (data->touches == 3 && data->window != 0) { - CompWindow* result = FindCompWindow(data->window); + CompWindow* result = FindCompWindowAtPos(data->focus_x, data->focus_y); if (result) { @@ -256,13 +238,12 @@ { if (data->touches == 3) { - _pinch_window = FindCompWindow(data->window); + _pinch_window = FindCompWindowAtPos(data->focus_x, data->focus_y); if (!_pinch_window) return; _pinch_id = data->id; - _pinch_start_radius = data->radius; if (_pinch_grab) _screen->removeGrab(_pinch_grab, NULL); @@ -275,17 +256,14 @@ if (data->id != _pinch_id) return; - float delta_radius = data->radius - _pinch_start_radius; - if (delta_radius > 110.0f) + if (data->radius > 1.25) { _pinch_window->maximize(MAXIMIZE_STATE); - _pinch_start_radius = data->radius; EndDrag(); } - else if (delta_radius < -110.0f) + else if (data->radius < 0.8) { _pinch_window->maximize(0); - _pinch_start_radius = data->radius; EndDrag(); } } diff -Nru unity-5.8.0/plugins/unityshell/src/GestureEngine.h unity-5.10.0/plugins/unityshell/src/GestureEngine.h --- unity-5.8.0/plugins/unityshell/src/GestureEngine.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/GestureEngine.h 2012-04-12 13:21:21.000000000 +0000 @@ -23,7 +23,6 @@ #include #include -#include #include "GeisAdapter.h" class GestureEngine : public sigc::trackable @@ -52,7 +51,7 @@ void EndDrag(); private: - CompWindow* FindCompWindow(Window window); + CompWindow* FindCompWindowAtPos(float pos_x, float pos_y); CompScreen* _screen; CompWindow* _drag_window; @@ -65,6 +64,5 @@ int _pinch_id; int _touch_id; - float _pinch_start_radius; Cursor _fleur_cursor; }; diff -Nru unity-5.8.0/plugins/unityshell/src/HudController.cpp unity-5.10.0/plugins/unityshell/src/HudController.cpp --- unity-5.8.0/plugins/unityshell/src/HudController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -39,7 +39,9 @@ } Controller::Controller() - : launcher_width(65) + : launcher_width(64) + , launcher_locked_out(false) + , multiple_launchers(true) , hud_service_("com.canonical.hud", "/com/canonical/hud") , window_(nullptr) , visible_(false) @@ -47,12 +49,13 @@ , timeline_id_(0) , last_opacity_(0.0f) , start_time_(0) - , launcher_is_locked_out_(false) , view_(nullptr) , monitor_index_(0) + , type_wait_handle_(0) { LOG_DEBUG(logger) << "hud startup"; - SetupRelayoutCallbacks(); + SetupWindow(); + UScreen::GetDefault()->changed.connect([&] (int, std::vector&) { Relayout(); }); ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud)); @@ -65,13 +68,13 @@ gint32 overlay_monitor = 0; g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); - if (g_strcmp0(overlay_identity, "hud")) + if (overlay_identity.Str() != "hud") { HideHud(true); } }); - launcher_width.changed.connect([this] (int new_width) { Relayout(); }); + launcher_width.changed.connect([&] (int new_width) { Relayout(); }); PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed)); @@ -87,6 +90,7 @@ g_source_remove(timeline_id_); g_source_remove(ensure_id_); + g_source_remove(type_wait_handle_); } void Controller::SetupWindow() @@ -98,6 +102,12 @@ window_->ShowWindow(false); window_->SetOpacity(0.0f); window_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow)); + + /* FIXME - first time we load our windows there is a race that causes the input window not to actually get input, this side steps that by causing an input window show and hide before we really need it. */ + PluginAdapter::Default()->saveInputFocus (); + window_->EnableInputWindow(true, "Hud", true, false); + window_->EnableInputWindow(false, "Hud", true, false); + PluginAdapter::Default()->restoreInputFocus (); } void Controller::SetupHudView() @@ -120,27 +130,39 @@ AddChild(view_); } -void Controller::SetupRelayoutCallbacks() +int Controller::GetTargetMonitor() +{ + return UScreen::GetDefault()->GetMonitorWithMouse(); +} + +bool Controller::IsLockedToLauncher(int monitor) { - GdkScreen* screen = gdk_screen_get_default(); + if (launcher_locked_out) + { + int primary_monitor = UScreen::GetDefault()->GetPrimaryMonitor(); + + if (multiple_launchers || (!multiple_launchers && primary_monitor == monitor)) + { + return true; + } + } - sig_manager_.Add(new glib::Signal(screen, - "monitors-changed", sigc::mem_fun(this, &Controller::Relayout))); - sig_manager_.Add(new glib::Signal(screen, - "size-changed", sigc::mem_fun(this, &Controller::Relayout))); + return false; } void Controller::EnsureHud() { - if (window_) - return; - LOG_DEBUG(logger) << "Initializing Hud"; - SetupWindow(); - SetupHudView(); - Relayout(); - ensure_id_ = 0; + if (!window_) + SetupWindow(); + + if (!view_) + { + SetupHudView(); + Relayout(); + ensure_id_ = 0; + } } nux::BaseWindow* Controller::window() const @@ -158,30 +180,31 @@ nux::Geometry Controller::GetIdealWindowGeometry() { - UScreen *uscreen = UScreen::GetDefault(); - int primary_monitor = uscreen->GetMonitorWithMouse(); - auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); + int target_monitor = GetTargetMonitor(); + auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(target_monitor); - // We want to cover as much of the screen as possible to grab any mouse events outside - // of our window + // 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_) + monitor_geo.y + panel_style.panel_height, + monitor_geo.width, + monitor_geo.height - panel_style.panel_height); + + if (IsLockedToLauncher(target_monitor)) { geo.x += launcher_width; geo.width -= launcher_width; } + return geo; } -void Controller::Relayout(GdkScreen*screen) +void Controller::Relayout() { EnsureHud(); - nux::Geometry content_geo = view_->GetGeometry(); - nux::Geometry geo = GetIdealWindowGeometry(); + nux::Geometry const& content_geo = view_->GetGeometry(); + nux::Geometry const& geo = GetIdealWindowGeometry(); window_->SetGeometry(geo); layout_->SetMinMaxSize(content_geo.width, content_geo.height); @@ -190,7 +213,7 @@ } void Controller::OnMouseDownOutsideWindow(int x, int y, - unsigned long bflags, unsigned long kflags) + unsigned long bflags, unsigned long kflags) { LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called"; HideHud(); @@ -234,16 +257,6 @@ 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(); @@ -259,13 +272,62 @@ return; } + unsigned int target_monitor = GetTargetMonitor(); + + if (target_monitor != monitor_index_) + { + Relayout(); + monitor_index_ = target_monitor; + } + + view_->ShowEmbeddedIcon(!IsLockedToLauncher(monitor_index_)); view_->AboutToShow(); - // we first want to grab the currently active window, luckly we can just ask the jason interface(bamf) - BamfMatcher* matcher = bamf_matcher_get_default(); - glib::Object bamf_app((BamfView*)(bamf_matcher_get_active_application(matcher)), glib::AddRef()); - glib::String view_icon(bamf_view_get_icon(bamf_app)); - focused_app_icon_ = view_icon.Str(); + // We first want to grab the currently active window + glib::Object matcher(bamf_matcher_get_default()); + BamfWindow* active_win = bamf_matcher_get_active_window(matcher); + + Window active_xid = bamf_window_get_xid(active_win); + std::vector const& unity_xids = nux::XInputWindow::NativeHandleList(); + + // If the active window is an unity window, we must get the top-most valid window + if (std::find(unity_xids.begin(), unity_xids.end(), active_xid) != unity_xids.end()) + { + // Windows list stack for all the monitors + GList *windows = bamf_matcher_get_window_stack_for_monitor(matcher, -1); + + for (GList *l = windows; l; l = l->next) + { + if (!BAMF_IS_WINDOW(l->data)) + continue; + + auto win = static_cast(l->data); + auto view = static_cast(l->data); + Window xid = bamf_window_get_xid(win); + + if (bamf_view_user_visible(view) && bamf_window_get_window_type(win) != BAMF_WINDOW_DOCK && + std::find(unity_xids.begin(), unity_xids.end(), xid) == unity_xids.end()) + { + active_win = win; + active_xid = xid; + } + } + + g_list_free(windows); + } + + BamfApplication* active_app = bamf_matcher_get_application_for_window(matcher, active_win); + + if (BAMF_IS_VIEW(active_app)) + { + auto active_view = reinterpret_cast(active_app); + glib::String view_icon(bamf_view_get_icon(active_view)); + focused_app_icon_ = view_icon.Str(); + } + else + { + focused_app_icon_ = focused_app_icon_ = PKGDATADIR "/launcher_bfb.png"; + } LOG_DEBUG(logger) << "Taking application icon: " << focused_app_icon_; ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(focused_app_icon_.c_str())); @@ -289,7 +351,6 @@ // hide the launcher GVariant* message_data = g_variant_new("(b)", TRUE); ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); - monitor_index_ = UScreen::GetDefault()->GetMonitorWithMouse(); GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, monitor_index_); ubus.SendMessage(UBUS_OVERLAY_SHOWN, info); @@ -310,6 +371,8 @@ window_->EnableInputWindow(false, "Hud", true, false); visible_ = false; + nux::GetWindowCompositor().SetKeyFocusArea(NULL,nux::KEY_NAV_NONE); + StartShowHideTimeline(); restore = true; @@ -384,8 +447,22 @@ void Controller::OnSearchChanged(std::string search_string) { + //FIXME!! - when the service is smart enough to not fall over if you send many requests, this should be removed LOG_DEBUG(logger) << "Search Changed"; - hud_service_.RequestQuery(search_string); + auto on_search_changed_timeout_lambda = [] (gpointer data) -> gboolean { + Controller* self = static_cast(data); + self->hud_service_.RequestQuery(self->last_search_); + self->type_wait_handle_ = 0; + return FALSE; + }; + + last_search_ = search_string; + + if (type_wait_handle_) + { + g_source_remove(type_wait_handle_); + } + type_wait_handle_ = g_timeout_add(100, on_search_changed_timeout_lambda, this); } void Controller::OnSearchActivated(std::string search_string) @@ -410,7 +487,6 @@ ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(query->icon_name.c_str())); } - void Controller::OnQueriesFinished(Hud::Queries queries) { view_->SetQueries(queries); @@ -438,7 +514,10 @@ void Controller::AddProperties(GVariantBuilder* builder) { variant::BuilderWrapper(builder) - .add("visible", visible_); + .add(window_ ? window_->GetGeometry() : nux::Geometry()) + .add("visible", visible_) + .add("hud_monitor", monitor_index_) + .add("locked_to_launcher", IsLockedToLauncher(monitor_index_)); } diff -Nru unity-5.8.0/plugins/unityshell/src/HudController.h unity-5.10.0/plugins/unityshell/src/HudController.h --- unity-5.8.0/plugins/unityshell/src/HudController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudController.h 2012-04-12 13:21:21.000000000 +0000 @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -49,12 +48,13 @@ nux::BaseWindow* window() const; nux::Property launcher_width; + nux::Property launcher_locked_out; + nux::Property multiple_launchers; void ShowHideHud(); void ShowHud(); void HideHud(bool restore_focus = true); bool IsVisible(); - void SetLauncherIsLockedOut(bool launcher_is_locked_out); protected: std::string GetName() const; @@ -64,11 +64,13 @@ void EnsureHud(); void SetupWindow(); void SetupHudView(); - void SetupRelayoutCallbacks(); void RegisterUBusInterests(); + int GetTargetMonitor(); + bool IsLockedToLauncher(int monitor); + nux::Geometry GetIdealWindowGeometry(); - void Relayout(GdkScreen*screen=NULL); + void Relayout(); void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); void OnScreenUngrabbed(); @@ -81,8 +83,6 @@ void OnQueryActivated(Query::Ptr query); void OnQuerySelected(Query::Ptr query); - -private: void StartShowHideTimeline(); static gboolean OnViewShowHideFrame(Controller* self); @@ -93,7 +93,6 @@ private: UBusManager ubus; Hud hud_service_; - glib::SignalManager sig_manager_; nux::BaseWindow* window_; bool visible_; bool need_show_; @@ -101,14 +100,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_; + guint type_wait_handle_; + std::string last_search_; }; diff -Nru unity-5.8.0/plugins/unityshell/src/HudIcon.cpp unity-5.10.0/plugins/unityshell/src/HudIcon.cpp --- unity-5.8.0/plugins/unityshell/src/HudIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -19,42 +19,32 @@ #include "HudIcon.h" #include "NuxCore/Logger.h" +#include "config.h" + namespace { nux::logging::Logger logger("unity.hud.icon"); + const unsigned int tile_margin = 4; + const unsigned int minimum_width = 64; } - + namespace unity { namespace hud { -Icon::Icon(nux::BaseTexture* texture, guint width, guint height) - : unity::IconTexture(texture, width, height) -{ - Init(); - icon_renderer_.SetTargetSize(54, 46, 0); -} - -Icon::Icon(const char* icon_name, unsigned int size, bool defer_icon_loading) - : unity::IconTexture(icon_name, size, defer_icon_loading) +Icon::Icon(std::string const& icon_name, unsigned int size) + : IconTexture(icon_name, size, true) { - Init(); -} - -Icon::~Icon() -{ -} - -void Icon::Init() -{ - SetMinimumWidth(66); - SetMinimumHeight(66); + int tile_size = size + tile_margin * 2; + SetMinimumWidth(minimum_width); + SetMinimumHeight(tile_size); + icon_renderer_.SetTargetSize(tile_size, size, 0); background_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_back_54.png", -1, true)); gloss_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_shine_54.png", -1, true)); edge_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_edge_54.png", -1, true)); - - texture_updated.connect([&] (nux::BaseTexture* texture) + + texture_updated.connect([&] (nux::BaseTexture* texture) { icon_texture_source_ = new HudIconTextureSource(nux::ObjectPtr(texture)); icon_texture_source_->ColorForIcon(_pixbuf_cached); @@ -78,18 +68,20 @@ arg.window_indicators = true; arg.backlight_intensity = 1.0f; arg.alpha = 1.0f; - + std::list args; args.push_front(arg); - - auto toplevel = GetToplevel(); - icon_renderer_.SetTargetSize(54, 46, 0); + + auto toplevel = GetToplevel(); icon_renderer_.PreprocessIcons(args, toplevel->GetGeometry()); icon_renderer_.RenderIcon(GfxContext, arg, toplevel->GetGeometry(), toplevel->GetGeometry()); } +std::string Icon::GetName() const +{ + return "HudEmbeddedIcon"; +} } } - diff -Nru unity-5.8.0/plugins/unityshell/src/HudIcon.h unity-5.10.0/plugins/unityshell/src/HudIcon.h --- unity-5.8.0/plugins/unityshell/src/HudIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -21,22 +21,6 @@ #ifndef HUDICON_H #define HUDICON_H -#include -#include - -#include "config.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include - #include "IconTexture.h" #include "HudIconTextureSource.h" #include "IconRenderer.h" @@ -51,14 +35,14 @@ { public: typedef nux::ObjectPtr Ptr; - Icon(nux::BaseTexture* texture, guint width, guint height); - Icon(const char* icon_name, unsigned int size, bool defer_icon_loading = false); - ~Icon(); + Icon(std::string const& icon_name, unsigned int size); protected: void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); - void Init(); + std::string GetName() const; + +private: nux::ObjectPtr background_; nux::ObjectPtr gloss_; nux::ObjectPtr edge_; diff -Nru unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/HudLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -39,7 +39,7 @@ UBusManager HudLauncherIcon::ubus_manager_; HudLauncherIcon::HudLauncherIcon(LauncherHideMode hide_mode) - : SimpleLauncherIcon() + : SingleMonitorLauncherIcon(0) , launcher_hide_mode_(hide_mode) { tooltip_text = _("HUD"); @@ -47,7 +47,7 @@ SetQuirk(QUIRK_VISIBLE, false); SetQuirk(QUIRK_RUNNING, false); SetQuirk(QUIRK_ACTIVE, true); - SetIconType(TYPE_HOME); + SetIconType(TYPE_HUD); background_color_ = nux::color::White; @@ -58,10 +58,13 @@ 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()) + if (hud_icon_name != icon_name) { - icon_name = hud_icon_name; + if (hud_icon_name.empty()) + icon_name = PKGDATADIR"/launcher_bfb.png"; + else + icon_name = hud_icon_name; + EmitNeedsRedraw(); } }); @@ -74,7 +77,13 @@ void HudLauncherIcon::SetHideMode(LauncherHideMode hide_mode) { - launcher_hide_mode_ = hide_mode; + if (launcher_hide_mode_ != hide_mode) + { + launcher_hide_mode_ = hide_mode; + + if (launcher_hide_mode_ == LAUNCHER_HIDE_AUTOHIDE) + SetQuirk(QUIRK_VISIBLE, false); + } } void HudLauncherIcon::OnOverlayShown(GVariant* data, bool visible) @@ -85,11 +94,13 @@ 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") && + // If the hud is open, we show the HUD button if we have a locked launcher + if (overlay_identity.Str() == "hud" && launcher_hide_mode_ == LAUNCHER_HIDE_NEVER) { + SetMonitor(overlay_monitor); SetQuirk(QUIRK_VISIBLE, visible); + SetQuirk(QUIRK_ACTIVE, visible); EmitNeedsRedraw(); } } diff -Nru unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.h unity-5.10.0/plugins/unityshell/src/HudLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/HudLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef UNITYSHELL_HUDLAUNCHERICON_H #define UNITYSHELL_HUDLAUNCHERICON_H -#include "SimpleLauncherIcon.h" +#include "SingleMonitorLauncherIcon.h" #include "LauncherOptions.h" #include "UBusWrapper.h" @@ -30,7 +30,7 @@ namespace launcher { -class HudLauncherIcon : public SimpleLauncherIcon +class HudLauncherIcon : public SingleMonitorLauncherIcon { public: diff -Nru unity-5.8.0/plugins/unityshell/src/HudView.cpp unity-5.10.0/plugins/unityshell/src/HudView.cpp --- unity-5.8.0/plugins/unityshell/src/HudView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudView.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -20,19 +20,11 @@ #include -#include #include -#include -#include -#include -#include - #include #include -#include #include #include -#include #include #include "HudButton.h" @@ -47,10 +39,18 @@ namespace { nux::logging::Logger logger("unity.hud.view"); -int icon_size = 42; -const std::string default_text = _("Type your command"); +const int icon_size = 46; const int grow_anim_length = 90 * 1000; const int pause_before_grow_length = 32 * 1000; + +const int default_width = 1024; +const int default_height = 276; +const int content_width = 941; + +const int top_padding = 11; +const int bottom_padding = 9; +const int left_padding = 11; +const int right_padding = 0; } NUX_IMPLEMENT_OBJECT_TYPE(View); @@ -64,8 +64,7 @@ , current_height_(0) , timeline_need_more_draw_(false) , selected_button_(0) - , icon_state_(IconHideState::SHOW) - , activated_signal_sent_(false) + , show_embedded_icon_(true) { renderer_.SetOwner(this); renderer_.need_redraw.connect([this] () { @@ -80,11 +79,7 @@ SetupViews(); search_bar_->key_down.connect (sigc::mem_fun (this, &View::OnKeyDown)); - search_bar_->activated.connect ([&]() - { - if (!activated_signal_sent_) - search_activated.emit(search_bar_->search_string); - }); + search_bar_->activated.connect (sigc::mem_fun (this, &View::OnSearchbarActivated)); search_bar_->text_entry()->SetLoseKeyFocusOnKeyNavDirectionUp(false); search_bar_->text_entry()->SetLoseKeyFocusOnKeyNavDirectionDown(false); @@ -127,7 +122,6 @@ View::~View() { - RemoveChild(search_bar_.GetPointer()); for (auto button = buttons_.begin(); button != buttons_.end(); button++) { RemoveChild((*button).GetPointer()); @@ -176,7 +170,7 @@ void View::ResetToDefault() { search_bar_->search_string = ""; - search_bar_->search_hint = default_text; + search_bar_->search_hint = _("Type your command"); } void View::Relayout() @@ -186,8 +180,7 @@ LOG_DEBUG(logger) << "content_geo: " << content_geo_.width << "x" << content_geo_.height; layout_->SetMinimumWidth(content_geo_.width); - layout_->SetMaximumWidth(content_geo_.width); - layout_->SetMaximumHeight(content_geo_.height); + layout_->SetMaximumSize(content_geo_.width, content_geo_.height); QueueDraw(); } @@ -220,6 +213,11 @@ void View::SetQueries(Hud::Queries queries) { + // early exit, if the user is key navigating on the hud, we don't want to set new + // queries under them, that is just rude + if (!buttons_.empty() && buttons_.back()->fake_focused == false) + return; + // remove the previous children for (auto button : buttons_) { @@ -259,7 +257,7 @@ button->is_rounded = (query == --(queries.end())) ? true : false; button->fake_focused = (query == (queries.begin())) ? true : false; - button->SetMinimumWidth(941); + button->SetMinimumWidth(content_width); found_items++; } if (found_items) @@ -272,22 +270,29 @@ void View::SetIcon(std::string icon_name) { LOG_DEBUG(logger) << "Setting icon to " << icon_name; - icon_->SetByIconName(icon_name.c_str(), icon_size); + icon_->SetByIconName(icon_name, icon_size); QueueDraw(); } -void View::SetHideIcon(IconHideState hide_icon) +void View::ShowEmbeddedIcon(bool show) { LOG_DEBUG(logger) << "Hide icon called"; - if (hide_icon == icon_state_) + if (show == show_embedded_icon_) return; - icon_state_ = hide_icon; + show_embedded_icon_ = show; - if (icon_state_ == IconHideState::HIDE) - layout_->RemoveChildObject(dynamic_cast(icon_layout_.GetPointer())); + if (show_embedded_icon_) + { + layout_->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, + nux::MINOR_SIZE_FULL, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN); + AddChild(icon_.GetPointer()); + } else - layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN); + { + layout_->RemoveChildObject(icon_.GetPointer()); + RemoveChild(icon_.GetPointer()); + } Relayout(); } @@ -299,13 +304,12 @@ { //FIXME - remove magic values, replace with scalable text depending on DPI // requires smarter font settings really... - int width, height = 0; - width = 1024; - height = 276; + int width = default_width; + int height = default_height; - if (icon_state_ == IconHideState::HIDE) + if (!show_embedded_icon_) { - width -= icon_layout_->GetGeometry().width; + width -= icon_->GetGeometry().width; } LOG_DEBUG (logger) << "best fit is, " << width << ", " << height; @@ -331,15 +335,6 @@ absolute_window_geometry_ = absolute_geo; } -namespace -{ - const int top_spacing = 9; - const int content_width = 941; - const int icon_vertical_margin = 5; - const int spacing_between_icon_and_content = 8; - const int bottom_padding = 10; -} - void View::SetupViews() { dash::Style& style = dash::Style::Instance(); @@ -347,33 +342,25 @@ nux::VLayout* super_layout = new nux::VLayout(); layout_ = new nux::HLayout(); { - // fill icon layout with icon - icon_ = new Icon("", icon_size, true); - 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_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT); + // fill layout with icon + icon_ = new Icon("", icon_size); + { + AddChild(icon_.GetPointer()); + layout_->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); } - // add padding to layout between icon and content - layout_->AddLayout(new nux::SpaceLayout(spacing_between_icon_and_content, - 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 - content_layout_->AddLayout(new nux::SpaceLayout(top_spacing,top_spacing,top_spacing,top_spacing), 0); + // Set the layout paddings + content_layout_->SetLeftAndRightPadding(left_padding, right_padding); + content_layout_->SetTopAndBottomPadding(top_padding, bottom_padding); // 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_ = new unity::SearchBar(true); + search_bar_->SetMinimumHeight(style.GetSearchBarHeight()); + search_bar_->SetMaximumHeight(style.GetSearchBarHeight()); + search_bar_->search_hint = _("Type your command"); search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged)); AddChild(search_bar_.GetPointer()); content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT); @@ -382,10 +369,6 @@ button_views_->SetMaximumWidth(content_width); content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT); - content_layout_->AddLayout(new nux::SpaceLayout(bottom_padding, - bottom_padding, - bottom_padding, - bottom_padding), 0); } layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP); @@ -401,12 +384,21 @@ search_changed.emit(search_string); if (search_string.empty()) { - search_bar_->search_hint = default_text; + search_bar_->search_hint = _("Type your command"); } else { search_bar_->search_hint = ""; } + + std::list::iterator it; + for(it = buttons_.begin(); it != buttons_.end(); ++it) + { + (*it)->fake_focused = false; + } + + if (!buttons_.empty()) + buttons_.back()->fake_focused = true; } @@ -491,6 +483,7 @@ { unsigned num_buttons = buttons_.size(); variant::BuilderWrapper(builder) + .add(GetGeometry()) .add("selected_button", selected_button_) .add("num_buttons", num_buttons); } @@ -508,13 +501,32 @@ else { search_bar_->search_string = ""; - search_bar_->search_hint = default_text; + search_bar_->search_hint = _("Type your command"); } return true; } return false; } +void View::OnSearchbarActivated() +{ + // 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()) + { + std::list::iterator it; + for(it = buttons_.begin(); it != buttons_.end(); ++it) + { + if ((*it)->fake_focused) + { + query_activated.emit((*it)->GetQuery()); + return; + } + } + } + search_activated.emit(search_bar_->search_string); +} + nux::Area* View::FindKeyFocusArea(unsigned int event_type, unsigned long x11_key_code, unsigned long special_keys_state) @@ -559,19 +571,19 @@ if (search_bar_->search_string == "") { - search_bar_->search_hint = default_text; + search_bar_->search_hint = _("Type your command"); ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST); } else { search_bar_->search_string = ""; - search_bar_->search_hint = default_text; + search_bar_->search_hint = _("Type your command"); return search_bar_->text_entry(); } return NULL; } - if (search_bar_->text_entry()->HasKeyFocus()) + if (search_bar_->text_entry()->HasKeyFocus() && !search_bar_->im_preedit) { if (direction == nux::KEY_NAV_NONE || direction == nux::KEY_NAV_UP || @@ -637,27 +649,11 @@ 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()) - { - std::list::iterator it; - for(it = buttons_.begin(); it != buttons_.end(); ++it) - { - if ((*it)->fake_focused) - { - query_activated.emit((*it)->GetQuery()); - activated_signal_sent_ = true; - } - } - } - // We still choose the text_entry as the receiver of the key focus. return search_bar_->text_entry(); } } - else if (direction == nux::KEY_NAV_NONE) + else if (direction == nux::KEY_NAV_NONE || search_bar_->im_preedit) { return search_bar_->text_entry(); } @@ -665,7 +661,7 @@ { return next_object_to_key_focus_area_->FindKeyFocusArea(event_type, x11_key_code, special_keys_state); } - return NULL; + return search_bar_->text_entry(); } } diff -Nru unity-5.8.0/plugins/unityshell/src/HudView.h unity-5.10.0/plugins/unityshell/src/HudView.h --- unity-5.8.0/plugins/unityshell/src/HudView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/HudView.h 2012-04-12 13:21:21.000000000 +0000 @@ -21,14 +21,9 @@ #include -#include #include -#include #include #include -#include - -#include #include #include "Introspectable.h" @@ -44,12 +39,6 @@ namespace hud { -enum IconHideState -{ - HIDE, - SHOW -}; - class View : public nux::View, public unity::debug::Introspectable { NUX_DECLARE_OBJECT_TYPE(HudView, nux::View); @@ -65,7 +54,7 @@ void SetQueries(Hud::Queries queries); void SetIcon(std::string icon_name); - void SetHideIcon(IconHideState hide_icon); + void ShowEmbeddedIcon(bool show); void AboutToShow(); void AboutToHide(); @@ -93,6 +82,7 @@ void Draw(nux::GraphicsEngine& gfx_context, bool force_draw); void DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw); bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character); + void OnSearchbarActivated(); bool AcceptKeyNavFocus(); nux::Geometry GetBestFitGeometry(nux::Geometry const& for_geo); @@ -111,7 +101,6 @@ //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_; @@ -126,7 +115,7 @@ int current_height_; bool timeline_need_more_draw_; int selected_button_; - IconHideState icon_state_; + bool show_embedded_icon_; bool activated_signal_sent_; }; diff -Nru unity-5.8.0/plugins/unityshell/src/IconRenderer.cpp unity-5.10.0/plugins/unityshell/src/IconRenderer.cpp --- unity-5.8.0/plugins/unityshell/src/IconRenderer.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/IconRenderer.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -510,7 +510,7 @@ edge->GetDeviceTexture(), edge_color, edge_tile_colorify, - arg.alpha, + arg.alpha * arg.alpha, // Dim edges of semi-transparent tiles force_filter, tile_transform); // end tile draw diff -Nru unity-5.8.0/plugins/unityshell/src/IconTexture.cpp unity-5.10.0/plugins/unityshell/src/IconTexture.cpp --- unity-5.8.0/plugins/unityshell/src/IconTexture.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/IconTexture.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -46,84 +46,88 @@ IconTexture::IconTexture(nux::BaseTexture* texture, guint width, guint height) : TextureArea(NUX_TRACKER_LOCATION), _accept_key_nav_focus(false), - _icon_name(NULL), _size(height), _texture_cached(texture), _texture_width(width), _texture_height(height), _loading(false), - _opacity(1.0f) + _opacity(1.0f), + _handle(0) { SetMinMaxSize(width, height); } -IconTexture::IconTexture(const char* icon_name, unsigned int size, bool defer_icon_loading) +IconTexture::IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading) : TextureArea(NUX_TRACKER_LOCATION), _accept_key_nav_focus(false), - _icon_name(NULL), + _icon_name(!icon_name.empty() ? icon_name : DEFAULT_ICON), _size(size), _texture_width(0), _texture_height(0), _loading(false), - _opacity(1.0f) + _opacity(1.0f), + _handle(0) { - _icon_name = g_strdup(icon_name ? icon_name : DEFAULT_ICON); - - if (g_strcmp0(_icon_name, "") != 0 && !defer_icon_loading) + if (!icon_name.empty () && !defer_icon_loading) LoadIcon(); } IconTexture::~IconTexture() { - g_free(_icon_name); + IconLoader::GetDefault().DisconnectHandle(_handle); } -void IconTexture::SetByIconName(const char* icon_name, unsigned int size) +void IconTexture::SetByIconName(std::string const& icon_name, unsigned int size) { - g_free(_icon_name); - _icon_name = g_strdup(icon_name); + if (_icon_name == icon_name && _size == size) + return; + + _icon_name = icon_name; _size = size; + + if (_size == 0) + { + _texture_cached = nullptr; + return; + } + LoadIcon(); } -void IconTexture::SetByFilePath(const char* file_path, unsigned int size) -{ - g_free(_icon_name); - _icon_name = g_strdup(file_path); - _size = size; - LoadIcon(); +void IconTexture::SetByFilePath(std::string const& file_path, unsigned int size) +{ + SetByIconName(file_path, size); } void IconTexture::LoadIcon() { LOG_DEBUG(logger) << "LoadIcon called (" << _icon_name << ") - loading: " << _loading; -static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview"; - if (!g_strcmp0(_icon_name, "")) - return; - - if (_loading) + static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview"; + + if (_loading || _size == 0 || _handle) return; + _loading = true; - glib::Object icon(::g_icon_new_for_string(_icon_name ? _icon_name : DEFAULT_GICON, NULL)); + glib::Object icon(::g_icon_new_for_string(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(), NULL)); if (icon) { - IconLoader::GetDefault().LoadFromGIconString(_icon_name ? _icon_name : DEFAULT_GICON, - _size, - sigc::mem_fun(this, &IconTexture::IconLoaded)); + _handle = IconLoader::GetDefault().LoadFromGIconString(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(), + _size, + sigc::mem_fun(this, &IconTexture::IconLoaded)); } - else if (g_str_has_prefix(_icon_name, "http://")) + else if (_icon_name.find("http://") == 0) { - IconLoader::GetDefault().LoadFromURI(_icon_name, - _size, sigc::mem_fun(this, &IconTexture::IconLoaded)); + _handle = IconLoader::GetDefault().LoadFromURI(_icon_name, + _size, sigc::mem_fun(this, &IconTexture::IconLoaded)); } else { - IconLoader::GetDefault().LoadFromIconName(_icon_name, - _size, - sigc::mem_fun(this, &IconTexture::IconLoaded)); + _handle = IconLoader::GetDefault().LoadFromIconName(_icon_name, + _size, + sigc::mem_fun(this, &IconTexture::IconLoaded)); } } @@ -143,7 +147,7 @@ // Try and get a texture from the texture cache std::string id("IconTexture."); - id += _icon_name ? _icon_name : DEFAULT_ICON; + id += _icon_name.empty() ? DEFAULT_ICON : _icon_name; _texture_cached = cache.FindTexture(id, _texture_width, _texture_height, @@ -155,6 +159,8 @@ void IconTexture::IconLoaded(std::string const& icon_name, unsigned size, GdkPixbuf* pixbuf) { + _handle = 0; + if (GDK_IS_PIXBUF(pixbuf)) { Refresh(pixbuf); @@ -240,7 +246,7 @@ { unity::variant::BuilderWrapper(builder) .add(GetGeometry()) - .add("iconname", _icon_name); + .add("icon_name", _icon_name); } // diff -Nru unity-5.8.0/plugins/unityshell/src/IconTexture.h unity-5.10.0/plugins/unityshell/src/IconTexture.h --- unity-5.8.0/plugins/unityshell/src/IconTexture.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/IconTexture.h 2012-04-12 13:21:21.000000000 +0000 @@ -37,11 +37,11 @@ { public: IconTexture(nux::BaseTexture* texture, guint width, guint height); - IconTexture(const char* icon_name, unsigned int size, bool defer_icon_loading = false); - ~IconTexture(); + IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading = false); + virtual ~IconTexture(); - void SetByIconName(const char* icon_name, unsigned int size); - void SetByFilePath(const char* file_path, unsigned int size); + void SetByIconName(std::string const& icon_name, unsigned int size); + void SetByFilePath(std::string const& file_path, unsigned int size); void GetTextureSize(int* width, int* height); void LoadIcon(); @@ -54,7 +54,7 @@ nux::BaseTexture* texture(); sigc::signal texture_updated; - + protected: // Key navigation virtual bool AcceptKeyNavFocus(); @@ -64,7 +64,7 @@ void AddProperties(GVariantBuilder* builder); virtual bool DoCanFocus(); GdkPixbuf* _pixbuf_cached; - + protected: void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); @@ -73,11 +73,9 @@ void Refresh(GdkPixbuf* pixbuf); void IconLoaded(std::string const& icon_name, unsigned size, GdkPixbuf* pixbuf); - // FIXME: make _icon_name a std::string. - char* _icon_name; + std::string _icon_name; unsigned int _size; - nux::ObjectPtr _texture_cached; // FIXME: make these two a nux::Size. int _texture_width; @@ -86,6 +84,7 @@ bool _loading; float _opacity; + int _handle; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/IMTextEntry.cpp unity-5.10.0/plugins/unityshell/src/IMTextEntry.cpp --- unity-5.8.0/plugins/unityshell/src/IMTextEntry.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/IMTextEntry.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -151,4 +151,9 @@ Paste(true); } } + +bool IMTextEntry::im_preedit() +{ + return !preedit_.empty(); +} } diff -Nru unity-5.8.0/plugins/unityshell/src/IMTextEntry.h unity-5.10.0/plugins/unityshell/src/IMTextEntry.h --- unity-5.8.0/plugins/unityshell/src/IMTextEntry.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/IMTextEntry.h 2012-04-12 13:21:21.000000000 +0000 @@ -39,6 +39,7 @@ NUX_DECLARE_OBJECT_TYPE(IMTextEntry, nux::TextEntry); public: IMTextEntry(); + bool im_preedit(); private: bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); diff -Nru unity-5.8.0/plugins/unityshell/src/inputremover.cpp unity-5.10.0/plugins/unityshell/src/inputremover.cpp --- unity-5.8.0/plugins/unityshell/src/inputremover.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/inputremover.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -24,6 +24,10 @@ #include #include +compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface () +{ +} + compiz::WindowInputRemover::WindowInputRemover (Display *dpy, Window xid) : mDpy (dpy), @@ -203,7 +207,7 @@ } bool -compiz::WindowInputRemover::save () +compiz::WindowInputRemover::saveInput () { XRectangle *rects; int count = 0, ordering; @@ -267,7 +271,7 @@ } bool -compiz::WindowInputRemover::remove () +compiz::WindowInputRemover::removeInput () { if (!mNInputRects) if (!save ()) @@ -290,7 +294,7 @@ } bool -compiz::WindowInputRemover::restore () +compiz::WindowInputRemover::restoreInput () { XShapeSelectInput (mDpy, mShapeWindow, NoEventMask); diff -Nru unity-5.8.0/plugins/unityshell/src/inputremover.h unity-5.10.0/plugins/unityshell/src/inputremover.h --- unity-5.8.0/plugins/unityshell/src/inputremover.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/inputremover.h 2012-04-12 13:21:21.000000000 +0000 @@ -22,6 +22,8 @@ #ifndef _COMPIZ_INPUTREMOVER_H #define _COMPIZ_INPUTREMOVER_H +#include + #include #include #include @@ -29,19 +31,39 @@ // Will be merged back into compiz namespace compiz { -class WindowInputRemover +class WindowInputRemoverInterface +{ + public: + + typedef std::shared_ptr Ptr; + + bool save () { return saveInput (); } + bool remove () { return removeInput (); } + bool restore () { return restoreInput (); } + + virtual ~WindowInputRemoverInterface (); + + protected: + + virtual bool saveInput () = 0; + virtual bool removeInput () = 0; + virtual bool restoreInput () = 0; +}; + +class WindowInputRemover : + public WindowInputRemoverInterface { public: WindowInputRemover (Display *, Window xid); ~WindowInputRemover (); - bool save (); - bool remove (); - bool restore (); - private: + bool saveInput (); + bool removeInput (); + bool restoreInput (); + void sendShapeNotify (); Display *mDpy; diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherController.cpp unity-5.10.0/plugins/unityshell/src/LauncherController.cpp --- unity-5.8.0/plugins/unityshell/src/LauncherController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -18,6 +18,7 @@ * Tim Penhey */ +#include #include #include @@ -31,6 +32,7 @@ #include "DesktopLauncherIcon.h" #include "DeviceLauncherIcon.h" #include "DeviceLauncherSection.h" +#include "EdgeBarrierController.h" #include "FavoriteStore.h" #include "HudLauncherIcon.h" #include "Launcher.h" @@ -87,11 +89,13 @@ void OnIconRemoved(AbstractLauncherIcon::Ptr icon); void OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before); - void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path); + void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path, + int icon_x, int icon_y, int icon_size); void OnLauncherRemoveRequest(AbstractLauncherIcon::Ptr icon); + void OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon); - void OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry); - void OnLauncherEntryRemoteRemoved(LauncherEntryRemote* entry); + void OnLauncherEntryRemoteAdded(LauncherEntryRemote::Ptr const& entry); + void OnLauncherEntryRemoteRemoved(LauncherEntryRemote::Ptr const& entry); void OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before); void OnFavoriteStoreFavoriteRemoved(std::string const& entry); @@ -114,7 +118,7 @@ AbstractLauncherIcon::Ptr CreateFavorite(const char* file_path); - AbstractLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path); + SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path); void SetupBamf(); @@ -170,6 +174,8 @@ int launcher_key_press_time_; + ui::EdgeBarrierController::Ptr edge_barriers_; + LauncherList launchers; sigc::connection on_expoicon_activate_connection_; @@ -185,7 +191,13 @@ , sort_priority_(0) , show_desktop_icon_(false) , display_(display) + , launcher_key_press_handler_id_(0) + , launcher_label_show_handler_id_(0) + , launcher_hide_handler_id_(0) + , edge_barriers_(new ui::EdgeBarrierController()) { + edge_barriers_->options = parent_->options(); + UScreen* uscreen = UScreen::GetDefault(); auto monitors = uscreen->GetMonitors(); int primary = uscreen->GetPrimaryMonitor(); @@ -226,9 +238,9 @@ remote_model_.entry_added.connect(sigc::mem_fun(this, &Impl::OnLauncherEntryRemoteAdded)); remote_model_.entry_removed.connect(sigc::mem_fun(this, &Impl::OnLauncherEntryRemoteRemoved)); - FavoriteStore::GetDefault().favorite_added.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteAdded)); - FavoriteStore::GetDefault().favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved)); - FavoriteStore::GetDefault().reordered.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreReordered)); + FavoriteStore::Instance().favorite_added.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteAdded)); + FavoriteStore::Instance().favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved)); + FavoriteStore::Instance().reordered.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreReordered)); LauncherHideMode hide_mode = parent_->options()->hide_mode; BFBLauncherIcon* bfb = new BFBLauncherIcon(hide_mode); @@ -258,6 +270,11 @@ }); parent_->AddChild(model_.get()); + + uscreen->resuming.connect([&]() -> void { + for (auto launcher : launchers) + launcher->QueueDraw(); + }); } Controller::Impl::~Impl() @@ -323,10 +340,16 @@ { parent_->RemoveChild(launcher.GetPointer()); launcher->GetParent()->UnReference(); + edge_barriers_->Unsubscribe(launcher.GetPointer(), launcher->monitor); } } launchers.resize(num_launchers); + + for (size_t i = 0; i < launchers.size(); ++i) + { + edge_barriers_->Subscribe(launchers[i].GetPointer(), launchers[i]->monitor); + } } void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector& monitors) @@ -377,6 +400,8 @@ launcher->launcher_addrequest_special.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequestSpecial)); launcher->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest)); + launcher->icon_animation_complete.connect(sigc::mem_fun(this, &Impl::OnSCIconAnimationComplete)); + parent_->AddChild(launcher); return launcher; @@ -423,31 +448,42 @@ desktop_paths.push_back(desktop_file); } - unity::FavoriteStore::GetDefault().SetFavorites(desktop_paths); + unity::FavoriteStore::Instance().SetFavorites(desktop_paths); } void Controller::Impl::OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, - std::string const& icon_path) + std::string const& icon_path, + int icon_x, + int icon_y, + int icon_size) { - auto launchers = model_->GetSublist(); - for (auto icon : launchers) + auto bamf_icons = model_->GetSublist(); + for (auto icon : bamf_icons) { if (icon->DesktopFile() == path) return; } - AbstractLauncherIcon::Ptr result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path); + SoftwareCenterLauncherIcon::Ptr result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path); + + launcher_->ForceReveal(true); + if (result) { + result->SetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE, false); + result->Animate(launcher_, icon_x, icon_y, icon_size); RegisterIcon(result); - - if (before) - model_->ReorderBefore(result, before, false); + Save(); } - Save(); +} + +void Controller::Impl::OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon) +{ + icon->SetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE, true); + launcher_->ForceReveal(false); } void Controller::Impl::SortAndUpdate() @@ -512,21 +548,21 @@ } } -void Controller::Impl::OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry) +void Controller::Impl::OnLauncherEntryRemoteAdded(LauncherEntryRemote::Ptr const& entry) { for (auto icon : *model_) { - if (!icon || !icon->RemoteUri()) + if (!icon || icon->RemoteUri().empty()) continue; - if (!g_strcmp0(entry->AppUri(), icon->RemoteUri())) + if (entry->AppUri() == icon->RemoteUri()) { icon->InsertEntryRemote(entry); } } } -void Controller::Impl::OnLauncherEntryRemoteRemoved(LauncherEntryRemote* entry) +void Controller::Impl::OnLauncherEntryRemoteRemoved(LauncherEntryRemote::Ptr const& entry) { for (auto icon : *model_) { @@ -588,7 +624,7 @@ void Controller::Impl::OnFavoriteStoreReordered() { - FavoriteList const& favs = FavoriteStore::GetDefault().GetFavorites(); + FavoriteList const& favs = FavoriteStore::Instance().GetFavorites(); auto bamf_list = model_->GetSublist(); int i = 0; @@ -676,13 +712,15 @@ void Controller::Impl::RegisterIcon(AbstractLauncherIcon::Ptr icon) { model_->AddIcon(icon); - - LauncherEntryRemote* entry = NULL; std::string const& path = icon->DesktopFile(); + if (!path.empty()) - entry = remote_model_.LookupByDesktopFile(path.c_str()); - if (entry) - icon->InsertEntryRemote(entry); + { + LauncherEntryRemote::Ptr const& entry = remote_model_.LookupByDesktopFile(path); + + if (entry) + icon->InsertEntryRemote(entry); + } } /* static private */ @@ -733,13 +771,12 @@ return result; } -AbstractLauncherIcon::Ptr -Controller::Impl::CreateSCLauncherIcon(std::string const& file_path, - std::string const& aptdaemon_trans_id, - std::string const& icon_path) +SoftwareCenterLauncherIcon::Ptr Controller::Impl::CreateSCLauncherIcon(std::string const& file_path, + std::string const& aptdaemon_trans_id, + std::string const& icon_path) { BamfApplication* app; - AbstractLauncherIcon::Ptr result; + SoftwareCenterLauncherIcon::Ptr result; app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path.c_str(), true); if (!BAMF_IS_APPLICATION(app)) @@ -751,13 +788,10 @@ return result; } - g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1)); - bamf_view_set_sticky(BAMF_VIEW(app), true); - AbstractLauncherIcon::Ptr icon(new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path)); - icon->SetSortPriority(sort_priority_++); + result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path); + result->SetSortPriority(sort_priority_++); - result = icon; return result; } @@ -772,7 +806,7 @@ matcher_ = bamf_matcher_get_default(); - FavoriteList const& favs = FavoriteStore::GetDefault().GetFavorites(); + FavoriteList const& favs = FavoriteStore::Instance().GetFavorites(); for (FavoriteList::const_iterator i = favs.begin(), end = favs.end(); i != end; ++i) @@ -802,6 +836,7 @@ icon->SetSortPriority(sort_priority_++); RegisterIcon(icon); } + g_list_free(apps); SortAndUpdate(); model_->order_changed.connect(sigc::mem_fun(this, &Impl::SortAndUpdate)); @@ -962,6 +997,13 @@ pimpl->launcher_label_show_handler_id_ = g_timeout_add(local::shortcuts_show_delay, show_shortcuts, pimpl); } +bool Controller::AboutToShowDash(int was_tap, int when) const +{ + if ((when - pimpl->launcher_key_press_time_) < local::super_tap_duration && was_tap) + return true; + return false; +} + void Controller::HandleLauncherKeyRelease(bool was_tap, int when) { int tap_duration = when - pimpl->launcher_key_press_time_; @@ -1063,9 +1105,9 @@ void Controller::KeyNavGrab() { pimpl->ubus.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); + pimpl->launcher_grabbed = true; KeyNavActivate(); pimpl->keyboard_launcher_->GrabKeyboard(); - pimpl->launcher_grabbed = true; pimpl->launcher_key_press_connection_ = pimpl->keyboard_launcher_->key_down.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveLauncherKeyPress)); @@ -1086,18 +1128,50 @@ pimpl->keyboard_launcher_->EnterKeyNavMode(); pimpl->model_->SetSelection(0); - pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER, g_variant_new_boolean(true)); - pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV, NULL); + if (pimpl->launcher_grabbed) + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV, + g_variant_new_int32(pimpl->keyboard_launcher_->monitor)); + } + else + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER, + g_variant_new_int32(pimpl->keyboard_launcher_->monitor)); + } + + AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection(); + + if (selected) + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED, + g_variant_new_string(selected->tooltip_text().c_str())); + } } void Controller::KeyNavNext() { pimpl->model_->SelectNext(); + + AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection(); + + if (selected) + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED, + g_variant_new_string(selected->tooltip_text().c_str())); + } } void Controller::KeyNavPrevious() { pimpl->model_->SelectPrevious(); + + AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection(); + + if (selected) + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED, + g_variant_new_string(selected->tooltip_text().c_str())); + } } void Controller::KeyNavTerminate(bool activate) @@ -1105,13 +1179,28 @@ if (!pimpl->launcher_keynav) return; + if (activate && pimpl->keynav_restore_window_) + { + /* If the selected icon is running, we must not restore the input to the old */ + AbstractLauncherIcon::Ptr const& icon = pimpl->model_->Selection(); + pimpl->keynav_restore_window_ = !icon->GetQuirk(AbstractLauncherIcon::QUIRK_RUNNING); + } + pimpl->keyboard_launcher_->ExitKeyNavMode(); + if (pimpl->launcher_grabbed) { pimpl->keyboard_launcher_->UnGrabKeyboard(); pimpl->launcher_key_press_connection_.disconnect(); pimpl->launcher_event_outside_connection_.disconnect(); pimpl->launcher_grabbed = false; + pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV, + g_variant_new_boolean(pimpl->keynav_restore_window_)); + } + else + { + pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER, + g_variant_new_boolean(pimpl->keynav_restore_window_)); } if (activate) @@ -1120,9 +1209,6 @@ pimpl->launcher_keynav = false; if (!pimpl->launcher_open) pimpl->keyboard_launcher_.Release(); - - pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER, g_variant_new_boolean(true)); - pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV, g_variant_new_boolean(pimpl->keynav_restore_window_)); } bool Controller::KeyNavIsActive() const @@ -1130,6 +1216,16 @@ return pimpl->launcher_keynav; } +bool Controller::IsOverlayOpen() const +{ + for (auto launcher_ptr : pimpl->launchers) + { + if (launcher_ptr->IsOverlayOpen()) + return true; + } + return false; +} + std::string Controller::GetName() const { @@ -1212,12 +1308,11 @@ // (start/activate currently selected icon) case NUX_VK_ENTER: case NUX_KP_ENTER: - model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0)); - parent_->KeyNavTerminate(false); + parent_->KeyNavTerminate(true); break; default: - // ALT + ; treat it as a shortcut and exit keynav + // ALT + ; treat it as a shortcut and exit keynav if (state & nux::NUX_STATE_ALT) { parent_->KeyNavTerminate(false); diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherController.h unity-5.10.0/plugins/unityshell/src/LauncherController.h --- unity-5.8.0/plugins/unityshell/src/LauncherController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherController.h 2012-04-12 13:21:21.000000000 +0000 @@ -60,6 +60,8 @@ void SetShowDesktopIcon(bool show_desktop_icon); + bool AboutToShowDash(int was_tap, int when) const; + void HandleLauncherKeyPress(int when); void HandleLauncherKeyRelease(bool was_tap, int when); bool HandleLauncherKeyEvent(Display *display, @@ -75,6 +77,8 @@ void KeyNavPrevious(); bool KeyNavIsActive() const; + bool IsOverlayOpen() const; + protected: // Introspectable methods std::string GetName() const; diff -Nru unity-5.8.0/plugins/unityshell/src/Launcher.cpp unity-5.10.0/plugins/unityshell/src/Launcher.cpp --- unity-5.8.0/plugins/unityshell/src/Launcher.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/Launcher.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -74,7 +74,6 @@ namespace unity { using ui::RenderArg; -using ui::PointerBarrierWrapper; using ui::Decaymulator; namespace launcher @@ -189,7 +188,7 @@ plugin_adapter.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); plugin_adapter.compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::EnsureAnimation)); - GeisAdapter& adapter = *(GeisAdapter::Default()); + GeisAdapter& adapter = GeisAdapter::Instance(); adapter.drag_start.connect(sigc::mem_fun(this, &Launcher::OnDragStart)); adapter.drag_update.connect(sigc::mem_fun(this, &Launcher::OnDragUpdate)); adapter.drag_finish.connect(sigc::mem_fun(this, &Launcher::OnDragFinish)); @@ -294,11 +293,6 @@ launcher_sheen_ = cache.FindTexture("dash_sheen", 0, 0, cb); launcher_pressure_effect_ = cache.FindTexture("launcher_pressure_effect", 0, 0, cb); - _pointer_barrier = PointerBarrierWrapper::Ptr(new PointerBarrierWrapper()); - _pointer_barrier->barrier_event.connect(sigc::mem_fun(this, &Launcher::OnPointerBarrierEvent)); - - decaymulator_ = Decaymulator::Ptr(new Decaymulator()); - options.changed.connect (sigc::mem_fun (this, &Launcher::OnOptionsChanged)); } @@ -625,6 +619,14 @@ float Launcher::IconVisibleProgress(AbstractLauncherIcon::Ptr icon, struct timespec const& current) const { + if (!icon->IsVisibleOnMonitor(monitor)) + return 0.0f; + + if (icon->GetIconType() == AbstractLauncherIcon::TYPE_HUD) + { + return (icon->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE)) ? 1.0f : 0.0f; + } + if (icon->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE)) { struct timespec icon_visible_time = icon->GetQuirkTime(AbstractLauncherIcon::QUIRK_VISIBLE); @@ -707,6 +709,9 @@ float Launcher::IconDesatValue(AbstractLauncherIcon::Ptr icon, struct timespec const& current) const { + if (!IsOverlayOpen()) + return 1.0f; + struct timespec dim_time = icon->GetQuirkTime(AbstractLauncherIcon::QUIRK_DESAT); int ms = unity::TimeUtil::TimeDelta(¤t, &dim_time); float result = CLAMP((float) ms / (float) ANIM_DURATION_SHORT_SHORT, 0.0f, 1.0f); @@ -879,7 +884,7 @@ { float desat_value = IconDesatValue(icon, current); arg.icon = icon.GetPointer(); - arg.alpha = 0.5f + 0.5f * desat_value; + arg.alpha = 0.2f + 0.8f * desat_value; arg.saturation = desat_value; arg.colorify = nux::color::White; arg.running_arrow = icon->GetQuirk(AbstractLauncherIcon::QUIRK_RUNNING); @@ -895,24 +900,32 @@ arg.progress_bias = IconProgressBias(icon, current); arg.progress = CLAMP(icon->GetProgress(), 0.0f, 1.0f); arg.draw_shortcut = _shortcuts_shown && !_hide_machine->GetQuirk(LauncherHideMachine::PLACES_VISIBLE); - arg.system_item = icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME; + arg.system_item = icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME || + icon->GetIconType() == AbstractLauncherIcon::TYPE_HUD; arg.colorify_background = icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME || + icon->GetIconType() == AbstractLauncherIcon::TYPE_HUD || icon->GetIconType() == AbstractLauncherIcon::TYPE_TRASH || icon->GetIconType() == AbstractLauncherIcon::TYPE_DESKTOP || icon->GetIconType() == AbstractLauncherIcon::TYPE_DEVICE || icon->GetIconType() == AbstractLauncherIcon::TYPE_EXPO; // trying to protect against flickering when icon is dragged from dash LP: #863230 - if (arg.alpha < 0.5) + if (arg.alpha < 0.2) { - arg.alpha = 0.5; + arg.alpha = 0.2; arg.saturation = 0.0; } - if (IsOverlayOpen()) - arg.active_arrow = icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME; - else - arg.active_arrow = icon->GetQuirk(AbstractLauncherIcon::QUIRK_ACTIVE); + arg.active_arrow = icon->GetQuirk(AbstractLauncherIcon::QUIRK_ACTIVE); + + /* BFB or HUD icons don't need the active arrow if the overaly is opened + * in another monitor */ + if (arg.active_arrow && !IsOverlayOpen() && + (icon->GetIconType() == AbstractLauncherIcon::TYPE_HOME || + icon->GetIconType() == AbstractLauncherIcon::TYPE_HUD)) + { + arg.active_arrow = false; + } if (options()->show_for_all) arg.running_on_viewport = icon->WindowVisibleOnViewport(); @@ -997,9 +1010,9 @@ arg.alpha *= drop_dim_value; // trying to protect against flickering when icon is dragged from dash LP: #863230 - if (arg.alpha < 0.5) + if (arg.alpha < 0.2) { - arg.alpha = 0.5; + arg.alpha = 0.2; arg.saturation = 0.0; } @@ -1269,6 +1282,7 @@ { _shortcuts_shown = show; _hover_machine->SetQuirk(LauncherHoverMachine::SHORTCUT_KEYS_VISIBLE, show); + EnsureAnimation(); } void Launcher::OnBGColorChanged(GVariant *data) @@ -1299,8 +1313,12 @@ { for (auto icon : *_model) { - if (icon->GetIconType () != AbstractLauncherIcon::TYPE_HOME) + if (icon->GetIconType () != AbstractLauncherIcon::TYPE_HOME && + icon->GetIconType () != AbstractLauncherIcon::TYPE_HUD) + { icon->SetQuirk(AbstractLauncherIcon::QUIRK_DESAT, true); + } + icon->HideTooltip(); } } @@ -1340,10 +1358,13 @@ { _hud_is_open = true; } - bg_effect_helper_.enabled = true; - LOG_DEBUG(logger) << "Desaturate on monitor " << monitor(); - DesaturateIcons(); + // Don't desaturate icons if the mouse is over the launcher: + if (!_hovered) + { + LOG_DEBUG(logger) << "Desaturate on monitor " << monitor(); + DesaturateIcons(); + } } EnsureAnimation(); } @@ -1572,30 +1593,12 @@ void Launcher::ConfigureBarrier() { nux::Geometry geo = GetAbsoluteGeometry(); - _pointer_barrier->DestroyBarrier(); - - 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 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(); - - _hide_machine->reveal_pressure = options()->edge_reveal_pressure() * reveal_responsiveness_mult; - _hide_machine->edge_decay_rate = options()->edge_decay_rate() * decay_responsiveness_mult; - } + _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) @@ -1769,6 +1772,11 @@ Resize(); } +int Launcher::GetIconSize() const +{ + return _icon_size; +} + void Launcher::Resize() { UScreen* uscreen = UScreen::GetDefault(); @@ -1814,6 +1822,9 @@ { _model = model; + for (auto icon : *_model) + icon->needs_redraw.connect(sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw)); + _model->icon_added.connect(sigc::mem_fun(this, &Launcher::OnIconAdded)); _model->icon_removed.connect(sigc::mem_fun(this, &Launcher::OnIconRemoved)); _model->order_changed.connect(sigc::mem_fun(this, &Launcher::OnOrderChanged)); @@ -1832,7 +1843,7 @@ int natural_y = 0; for (auto icon : *_model) { - if (!icon->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE)) + if (!icon->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE) || !icon->IsVisibleOnMonitor(monitor)) continue; if (icon == selection) @@ -1934,48 +1945,54 @@ if (IsOverlayOpen()) { + nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, base.width, base.height); + nux::ObjectPtr blur_texture; + if (BackgroundEffectHelper::blur_type != unity::BLUR_NONE && (bkg_box.x + bkg_box.width > 0)) { - nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, base.width, base.height); - auto blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo); + blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo); + } + else + { + blur_texture = bg_effect_helper_.GetRegion(blur_geo); + } - if (blur_texture.IsValid()) - { - nux::TexCoordXForm texxform_blur_bg; - texxform_blur_bg.flip_v_coord = true; - texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width; - texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height; + if (blur_texture.IsValid()) + { + nux::TexCoordXForm texxform_blur_bg; + texxform_blur_bg.flip_v_coord = true; + texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width; + texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height; - GfxContext.PushClippingRectangle(bkg_box); + GfxContext.PushClippingRectangle(bkg_box); #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); + 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); + gPainter.PushDrawCompositionLayer(GfxContext, base, + blur_texture, + texxform_blur_bg, + nux::color::White, + _background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, ROP); #endif - GfxContext.PopClippingRectangle(); + GfxContext.PopClippingRectangle(); - push_count++; - } + push_count++; } unsigned int alpha = 0, src = 0, dest = 0; @@ -2048,11 +2065,11 @@ nux::Geometry(bkg_box.x, bkg_box.y, bkg_box.width, - 20), - nux::Color(0x60000000), + 8), + nux::Color(0x70000000), nux::Color(0x00000000), nux::Color(0x00000000), - nux::Color(0x60000000)); + nux::Color(0x70000000)); } // FIXME: can be removed for a bgk_box->SetAlpha once implemented @@ -2382,7 +2399,7 @@ EnsureAnimation(); } -void Launcher::OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) +bool Launcher::HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) { nux::Geometry abs_geo = GetAbsoluteGeometry(); @@ -2416,19 +2433,11 @@ } } - if (apply_to_reveal) - { - _hide_machine->AddRevealPressure(event->velocity); - decaymulator_->value = 0; - } - else if (abs_geo.x > 0) - { - decaymulator_->value = decaymulator_->value + event->velocity; - if (decaymulator_->value > _edge_overcome_pressure) - { - _pointer_barrier->ReleaseBarrier(event->event_id); - } - } + if (!apply_to_reveal) + return false; + + _hide_machine->AddRevealPressure(event->velocity); + return true; } bool Launcher::IsInKeyNavMode() const @@ -2440,6 +2449,7 @@ { _hide_machine->SetQuirk(LauncherHideMachine::KEY_NAV_ACTIVE, true); _hover_machine->SetQuirk(LauncherHoverMachine::KEY_NAV_ACTIVE, true); + SaturateIcons(); } void Launcher::ExitKeyNavMode() @@ -2569,7 +2579,7 @@ for (it = _model->begin(); it != _model->end(); it++) { - if (!(*it)->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE)) + if (!(*it)->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE) || !(*it)->IsVisibleOnMonitor(monitor)) continue; nux::Point2 screen_coord [4]; @@ -2818,7 +2828,7 @@ _drag_action = nux::DNDACTION_COPY; if (!_dnd_hovered_icon && hovered_icon_is_appropriate) { - _dnd_hovered_icon = new SpacerLauncherIcon(); + _dnd_hovered_icon = new SpacerLauncherIcon(monitor()); _dnd_hovered_icon->SetSortPriority(G_MAXINT); _model->AddIcon(_dnd_hovered_icon); _model->ReorderBefore(_dnd_hovered_icon, hovered_icon, true); @@ -2952,7 +2962,8 @@ g_variant_get(parameters, "(ssiiiss)", &title, &icon, &icon_x, &icon_y, &icon_size, &desktop_file, &aptdaemon_task, NULL); Launcher* self = (Launcher*)user_data; - self->launcher_addrequest_special.emit(desktop_file, AbstractLauncherIcon::Ptr(), aptdaemon_task, icon); + self->launcher_addrequest_special.emit(desktop_file, AbstractLauncherIcon::Ptr(), aptdaemon_task, icon, + icon_x, icon_y, icon_size); g_dbus_method_invocation_return_value(invocation, nullptr); g_free(icon); diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherEntryRemote.cpp unity-5.10.0/plugins/unityshell/src/LauncherEntryRemote.cpp --- unity-5.8.0/plugins/unityshell/src/LauncherEntryRemote.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherEntryRemote.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-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 @@ -15,11 +15,20 @@ * along with this program. If not, see . * * Authored by: Mikkel Kamstrup Erlandsen + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include "LauncherEntryRemote.h" +#include +#include -NUX_IMPLEMENT_OBJECT_TYPE(LauncherEntryRemote); +namespace unity +{ + +namespace +{ +nux::logging::Logger logger("launcher.entry.remote"); +} /** * Create a new LauncherEntryRemote parsed from the raw DBus wire format @@ -30,63 +39,32 @@ * You don't normally need to use this constructor yourself. The * LauncherEntryRemoteModel will do that for you when needed. */ -LauncherEntryRemote::LauncherEntryRemote(const gchar* dbus_name, GVariant* val) +LauncherEntryRemote::LauncherEntryRemote(std::string const& dbus_name, GVariant* val) + : _dbus_name(dbus_name) + , _count(0) + , _progress(0.0f) + , _emblem_visible(false) + , _count_visible(false) + , _progress_visible(false) + , _urgent(false) { - gchar* app_uri; + glib::String app_uri; GVariantIter* prop_iter; - g_return_if_fail(dbus_name != NULL); - g_return_if_fail(val != NULL); - - _dbus_name = g_strdup(dbus_name); - - _emblem = NULL; - _count = G_GINT64_CONSTANT(0); - _progress = 0.0; - _quicklist = NULL; - - _emblem_visible = FALSE; - _count_visible = FALSE; - _progress_visible = FALSE; - - _urgent = FALSE; - - g_variant_ref_sink(val); - g_variant_get(val, "(sa{sv})", &app_uri, &prop_iter); - - _app_uri = app_uri; // steal ref - - Update(prop_iter); - - g_variant_iter_free(prop_iter); - g_variant_unref(val); -} - -LauncherEntryRemote::~LauncherEntryRemote() -{ - if (_dbus_name) + if (!val || dbus_name.empty()) { - g_free(_dbus_name); - _dbus_name = NULL; + LOG_ERROR(logger) << "Invalid launcher entry remote construction"; + return; } - if (_app_uri) - { - g_free(_app_uri); - _app_uri = NULL; - } + /* This will make sure that the values are properly ref_sink'ed and unreff'ed */ + glib::Variant values(val); + g_variant_get(values, "(sa{sv})", &app_uri, &prop_iter); - if (_emblem) - { - g_free(_emblem); - _emblem = NULL; - } + _app_uri = app_uri.Str(); - if (_quicklist) - { - g_object_unref(_quicklist); - _quicklist = NULL; - } + Update(prop_iter); + g_variant_iter_free(prop_iter); } /** @@ -98,8 +76,7 @@ * file including the extension. Eg. gedit.desktop. Thus a full appuri could be * application://gedit.desktop. */ -const gchar* -LauncherEntryRemote::AppUri() +std::string const& LauncherEntryRemote::AppUri() const { return _app_uri; } @@ -107,26 +84,22 @@ /** * Return the unique DBus name for the remote party owning this launcher entry. */ -const gchar* -LauncherEntryRemote::DBusName() +std::string const& LauncherEntryRemote::DBusName() const { return _dbus_name; } -const gchar* -LauncherEntryRemote::Emblem() +std::string const& LauncherEntryRemote::Emblem() const { return _emblem; } -gint64 -LauncherEntryRemote::Count() +long long LauncherEntryRemote::Count() const { return _count; } -gdouble -LauncherEntryRemote::Progress() +double LauncherEntryRemote::Progress() const { return _progress; } @@ -137,32 +110,27 @@ * * The returned object should not be freed. */ -DbusmenuClient* -LauncherEntryRemote::Quicklist() +glib::Object const& LauncherEntryRemote::Quicklist() const { return _quicklist; } -gboolean -LauncherEntryRemote::EmblemVisible() +bool LauncherEntryRemote::EmblemVisible() const { return _emblem_visible; } -gboolean -LauncherEntryRemote::CountVisible() +bool LauncherEntryRemote::CountVisible() const { return _count_visible; } -gboolean -LauncherEntryRemote::ProgressVisible() +bool LauncherEntryRemote::ProgressVisible() const { return _progress_visible; } -gboolean -LauncherEntryRemote::Urgent() +bool LauncherEntryRemote::Urgent() const { return _urgent; } @@ -172,41 +140,32 @@ * * If the entry has any exported quicklist it will be removed. */ -void -LauncherEntryRemote::SetDBusName(const gchar* dbus_name) +void LauncherEntryRemote::SetDBusName(std::string const& dbus_name) { - gchar* old_name; - - if (g_strcmp0(_dbus_name, dbus_name) == 0) + if (_dbus_name == dbus_name) return; - old_name = _dbus_name; - _dbus_name = g_strdup(dbus_name); + std::string old_name(_dbus_name); + _dbus_name = dbus_name; /* Remove the quicklist since we can't know if it it'll be valid on the * new name, and we certainly don't want the quicklist to operate on a * different name than the rest of the launcher API */ - SetQuicklist(NULL); + SetQuicklist(nullptr); dbus_name_changed.emit(this, old_name); - g_free(old_name); } -void -LauncherEntryRemote::SetEmblem(const gchar* emblem) +void LauncherEntryRemote::SetEmblem(std::string const& emblem) { - if (g_strcmp0(_emblem, emblem) == 0) + if (_emblem == emblem) return; - if (_emblem) - g_free(_emblem); - - _emblem = g_strdup(emblem); + _emblem = emblem; emblem_changed.emit(this); } -void -LauncherEntryRemote::SetCount(gint64 count) +void LauncherEntryRemote::SetCount(long long count) { if (_count == count) return; @@ -215,8 +174,7 @@ count_changed.emit(this); } -void -LauncherEntryRemote::SetProgress(gdouble progress) +void LauncherEntryRemote::SetProgress(double progress) { if (_progress == progress) return; @@ -231,38 +189,27 @@ * * To unset the quicklist pass in a NULL path or empty string. */ -void -LauncherEntryRemote::SetQuicklistPath(const gchar* dbus_path) +void LauncherEntryRemote::SetQuicklistPath(std::string const& dbus_path) { - /* Replace "" with NULL to simplify the logic below */ - if (g_strcmp0("", dbus_path) == 0) - { - dbus_path = NULL; - } - /* Check if existing quicklist have exact same path * and ignore the change in that case */ if (_quicklist) { - gchar* ql_path; + glib::String ql_path; g_object_get(_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL); - if (g_strcmp0(dbus_path, ql_path) == 0) + + if (ql_path.Str() == dbus_path) { - g_free(ql_path); return; } - - /* Prepare for a new quicklist */ - g_free(ql_path); - g_object_unref(_quicklist); } - else if (_quicklist == NULL && dbus_path == NULL) + else if (!_quicklist && dbus_path.empty()) return; - if (dbus_path != NULL) - _quicklist = dbusmenu_client_new(_dbus_name, dbus_path); + if (!dbus_path.empty()) + _quicklist = dbusmenu_client_new(_dbus_name.c_str(), dbus_path.c_str()); else - _quicklist = NULL; + _quicklist = nullptr; quicklist_changed.emit(this); } @@ -281,57 +228,40 @@ * uses the same name as the connection owning this launcher entry */ if (_quicklist) { - gchar* ql_path, *new_ql_path, *new_ql_name; + glib::String ql_path, new_ql_path, new_ql_name; + g_object_get(_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL); - if (quicklist == NULL) - { - new_ql_path = NULL; - new_ql_name = NULL; - } - else + if (quicklist) { g_object_get(quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &new_ql_path, NULL); g_object_get(quicklist, DBUSMENU_CLIENT_PROP_DBUS_NAME, &new_ql_name, NULL); } - if (quicklist != NULL && g_strcmp0(new_ql_name, _dbus_name) != 0) + if (quicklist && new_ql_name.Str() != _dbus_name) { - g_critical("Mismatch between quicklist- and launcher entry owner:" - "%s and %s respectively", new_ql_name, _dbus_name); - g_free(ql_path); - g_free(new_ql_path); - g_free(new_ql_name); + LOG_ERROR(logger) << "Mismatch between quicklist- and launcher entry owner:" + << new_ql_name << " and " << _dbus_name << " respectively"; return; } - if (g_strcmp0(new_ql_path, ql_path) == 0) + if (new_ql_path.Str() == ql_path.Str()) { - g_free(ql_path); - g_free(new_ql_path); - g_free(new_ql_name); return; } - - /* Prepare for a new quicklist */ - g_free(ql_path); - g_free(new_ql_path); - g_free(new_ql_name); - g_object_unref(_quicklist); } - else if (_quicklist == NULL && quicklist == NULL) + else if (!_quicklist && !quicklist) return; - if (quicklist == NULL) - _quicklist = NULL; + if (!quicklist) + _quicklist = nullptr; else - _quicklist = (DbusmenuClient*) g_object_ref(quicklist); + _quicklist = glib::Object(quicklist, glib::AddRef()); quicklist_changed.emit(this); } -void -LauncherEntryRemote::SetEmblemVisible(gboolean visible) +void LauncherEntryRemote::SetEmblemVisible(bool visible) { if (_emblem_visible == visible) return; @@ -340,8 +270,7 @@ emblem_visible_changed.emit(this); } -void -LauncherEntryRemote::SetCountVisible(gboolean visible) +void LauncherEntryRemote::SetCountVisible(bool visible) { if (_count_visible == visible) return; @@ -350,8 +279,7 @@ count_visible_changed.emit(this); } -void -LauncherEntryRemote::SetProgressVisible(gboolean visible) +void LauncherEntryRemote::SetProgressVisible(bool visible) { if (_progress_visible == visible) return; @@ -360,8 +288,7 @@ progress_visible_changed.emit(this); } -void -LauncherEntryRemote::SetUrgent(gboolean urgent) +void LauncherEntryRemote::SetUrgent(bool urgent) { if (_urgent == urgent) return; @@ -373,11 +300,14 @@ /** * Set all properties from 'other' on 'this'. */ -void -LauncherEntryRemote::Update(LauncherEntryRemote* other) +void LauncherEntryRemote::Update(LauncherEntryRemote::Ptr const& other) { /* It's important that we update the DBus name first since it might * unset the quicklist if it changes */ + + if (!other) + return; + SetDBusName(other->DBusName()); SetEmblem(other->Emblem()); @@ -395,22 +325,17 @@ * Iterate over a GVariantIter containing elements of type '{sv}' and apply * any properties to 'this'. */ -void -LauncherEntryRemote::Update(GVariantIter* prop_iter) +void LauncherEntryRemote::Update(GVariantIter* prop_iter) { - gchar* prop_key; - const gchar* prop_value_s; - GVariant* prop_value; + gchar* prop_key; + GVariant* prop_value; g_return_if_fail(prop_iter != NULL); while (g_variant_iter_loop(prop_iter, "{sv}", &prop_key, &prop_value)) { if (g_str_equal("emblem", prop_key)) - { - prop_value_s = g_variant_get_string(prop_value, NULL); - SetEmblem(prop_value_s); - } + SetEmblem(glib::String(g_variant_dup_string(prop_value, 0)).Str()); else if (g_str_equal("count", prop_key)) SetCount(g_variant_get_int64(prop_value)); else if (g_str_equal("progress", prop_key)) @@ -426,8 +351,9 @@ else if (g_str_equal("quicklist", prop_key)) { /* The value is the object path of the dbusmenu */ - prop_value_s = g_variant_get_string(prop_value, NULL); - SetQuicklistPath(prop_value_s); + SetQuicklistPath(glib::String(g_variant_dup_string(prop_value, 0)).Str()); } } } + +} // Namespace diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherEntryRemote.h unity-5.10.0/plugins/unityshell/src/LauncherEntryRemote.h --- unity-5.8.0/plugins/unityshell/src/LauncherEntryRemote.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherEntryRemote.h 2012-04-12 13:21:21.000000000 +0000 @@ -20,11 +20,15 @@ #ifndef LAUNCHER_ENTRY_REMOTE_H #define LAUNCHER_ENTRY_REMOTE_H -#include #include +#include #include #include #include +#include + +namespace unity +{ /** * Instances of this class mirrors the remote metadata for a laucnher entry @@ -33,33 +37,33 @@ * You do not create instances of LauncherEntryRemote yourself. Instead they * are created and managed dynamically by a LauncherEntryRemoteModel. */ -class LauncherEntryRemote : public nux::InitiallyUnownedObject +class LauncherEntryRemote : public sigc::trackable { - NUX_DECLARE_OBJECT_TYPE(LauncherEntryRemote, nux::InitiallyUnownedObject); public: + typedef std::shared_ptr Ptr; - LauncherEntryRemote(const gchar* dbus_name, GVariant* val); - ~LauncherEntryRemote(); + LauncherEntryRemote(std::string const& dbus_name, GVariant* val); + + std::string const& AppUri() const; + std::string const& DBusName() const; + std::string const& Emblem() const; + long long Count() const; + double Progress() const; + glib::Object const& Quicklist() const; + + bool EmblemVisible() const; + bool CountVisible() const; + bool ProgressVisible() const; + bool Urgent() const; - const gchar* AppUri(); - const gchar* DBusName(); - const gchar* Emblem(); - gint64 Count(); - gdouble Progress(); - DbusmenuClient* Quicklist(); - - gboolean EmblemVisible(); - gboolean CountVisible(); - gboolean ProgressVisible(); - gboolean Urgent(); /// Update this instance using details from another: - void Update(LauncherEntryRemote* other); + void Update(LauncherEntryRemote::Ptr const& other); /// Update this instance from a GVariant property iterator. void Update(GVariantIter* prop_iter); /// Set a new DBus name. This destroys the current quicklist. - void SetDBusName(const gchar* dbus_name); + void SetDBusName(std::string const& dbus_name); - sigc::signal dbus_name_changed; // gives the old name as arg + sigc::signal dbus_name_changed; // gives the old name as arg sigc::signal emblem_changed; sigc::signal count_changed; sigc::signal progress_changed; @@ -68,34 +72,34 @@ sigc::signal emblem_visible_changed; sigc::signal count_visible_changed; sigc::signal progress_visible_changed; - sigc::signal urgent_changed; private: + std::string _dbus_name; - gchar* _app_uri; - gchar* _emblem; - gint64 _count; - gdouble _progress; - - gchar* _dbus_name; - gchar* _quicklist_dbus_path; - DbusmenuClient* _quicklist; - - gboolean _emblem_visible; - gboolean _count_visible; - gboolean _progress_visible; - gboolean _urgent; - - void SetEmblem(const gchar* emblem); - void SetCount(gint64 count); - void SetProgress(gdouble progress); - void SetQuicklistPath(const gchar* dbus_path); + std::string _app_uri; + std::string _emblem; + long long _count; + double _progress; + + std::string _quicklist_dbus_path; + glib::Object _quicklist; + + bool _emblem_visible; + bool _count_visible; + bool _progress_visible; + bool _urgent; + + void SetEmblem(std::string const& emblem); + void SetCount(long long count); + void SetProgress(double progress); + void SetQuicklistPath(std::string const& dbus_path); void SetQuicklist(DbusmenuClient* quicklist); - void SetEmblemVisible(gboolean visible); - void SetCountVisible(gboolean visible); - void SetProgressVisible(gboolean visible); - void SetUrgent(gboolean urgent); + void SetEmblemVisible(bool visible); + void SetCountVisible(bool visible); + void SetProgressVisible(bool visible); + void SetUrgent(bool urgent); }; +} // namespace #endif // LAUNCHER_ENTRY_REMOTE_H diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherEntryRemoteModel.cpp unity-5.10.0/plugins/unityshell/src/LauncherEntryRemoteModel.cpp --- unity-5.8.0/plugins/unityshell/src/LauncherEntryRemoteModel.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherEntryRemoteModel.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-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 @@ -15,11 +15,21 @@ * along with this program. If not, see . * * Authored by: Mikkel Kamstrup Erlandsen + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ +#include +#include + #include "LauncherEntryRemoteModel.h" -static void nux_object_destroy_notify(nux::Object* obj); +namespace unity +{ + +namespace +{ +nux::logging::Logger logger("launcher.entry.remote.model"); +} /** * Helper class implementing the remote API to control the icons in the @@ -33,70 +43,60 @@ * with Unity. */ LauncherEntryRemoteModel::LauncherEntryRemoteModel() + : _launcher_entry_dbus_signal_id(0) + , _dbus_name_owner_changed_signal_id(0) { - GError* error; - - _launcher_entry_dbus_signal_id = 0; + glib::Error error; - error = NULL; - _conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + _conn = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error); if (error) { - g_warning("Unable to connect to session bus: %s", error->message); - g_error_free(error); + LOG_ERROR(logger) << "Unable to connect to session bus: " << error.Message(); return; } - _entries_by_uri = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify) nux_object_destroy_notify); - /* Listen for *all* signals on the "com.canonical.Unity.LauncherEntry" * interface, no matter who the sender is */ _launcher_entry_dbus_signal_id = g_dbus_connection_signal_subscribe(_conn, - NULL, // sender - "com.canonical.Unity.LauncherEntry", - NULL, // member - NULL, // path - NULL, // arg0 + nullptr, // sender + "com.canonical.Unity.LauncherEntry", // iface + nullptr, // member + nullptr, // path + nullptr, // arg0 G_DBUS_SIGNAL_FLAGS_NONE, - &on_launcher_entry_signal_received, + &OnEntrySignalReceived, this, - NULL); + nullptr); _dbus_name_owner_changed_signal_id = g_dbus_connection_signal_subscribe(_conn, - "org.freedesktop.DBus", // sender - "org.freedesktop.DBus", // interface - "NameOwnerChanged", // member - "/org/freedesktop/DBus", // path - NULL, // arg0 + "org.freedesktop.DBus", // sender + "org.freedesktop.DBus", // interface + "NameOwnerChanged", // member + "/org/freedesktop/DBus", // path + nullptr, // arg0 G_DBUS_SIGNAL_FLAGS_NONE, - &on_dbus_name_owner_changed_signal_received, + &OnDBusNameOwnerChanged, this, - NULL); + nullptr); } LauncherEntryRemoteModel::~LauncherEntryRemoteModel() { - g_hash_table_destroy(_entries_by_uri); - _entries_by_uri = NULL; - - if (_launcher_entry_dbus_signal_id && _conn) - { - g_dbus_connection_signal_unsubscribe(_conn, - _launcher_entry_dbus_signal_id); - } - if (_dbus_name_owner_changed_signal_id && _conn) - { - g_dbus_connection_signal_unsubscribe(_conn, - _dbus_name_owner_changed_signal_id); - } - if (_conn) { - g_object_unref(_conn); - _conn = NULL; + if (_launcher_entry_dbus_signal_id) + { + g_dbus_connection_signal_unsubscribe(_conn, + _launcher_entry_dbus_signal_id); + } + + if (_dbus_name_owner_changed_signal_id) + { + g_dbus_connection_signal_unsubscribe(_conn, + _dbus_name_owner_changed_signal_id); + } } } @@ -104,163 +104,117 @@ * Return the number of unique LauncherEntryRemote objects managed by the model. * The entries are identified by their LauncherEntryRemote::AppUri property. */ -guint -LauncherEntryRemoteModel::Size() +unsigned int LauncherEntryRemoteModel::Size() const { - return g_hash_table_size(_entries_by_uri); + return _entries_by_uri.size(); } /** - * Return a pointer to a LauncherEntryRemote if there is one for app_uri, - * otherwise NULL. The returned object should not be freed. + * Return a smart pointer to a LauncherEntryRemote if there is one for app_uri, + * otherwise nullptr. * * App Uris look like application://$desktop_file_id, where desktop_file_id * is the base name of the .desktop file for the application including the * .desktop extension. Eg. application://firefox.desktop. */ -LauncherEntryRemote* -LauncherEntryRemoteModel::LookupByUri(const gchar* app_uri) +LauncherEntryRemote::Ptr LauncherEntryRemoteModel::LookupByUri(std::string const& app_uri) { - gpointer entry; + auto target_en = _entries_by_uri.find(app_uri); - g_return_val_if_fail(app_uri != NULL, NULL); - - entry = g_hash_table_lookup(_entries_by_uri, app_uri); - return static_cast(entry); + return (target_en != _entries_by_uri.end()) ? target_en->second : nullptr; } /** - * Return a pointer to a LauncherEntryRemote if there is one for desktop_id, - * otherwise NULL. The returned object should not be freed. + * Return a smart pointer to a LauncherEntryRemote if there is one for desktop_id, + * otherwise nullptr. * * The desktop id is the base name of the .desktop file for the application * including the .desktop extension. Eg. firefox.desktop. */ -LauncherEntryRemote* -LauncherEntryRemoteModel::LookupByDesktopId(const gchar* desktop_id) +LauncherEntryRemote::Ptr LauncherEntryRemoteModel::LookupByDesktopId(std::string const& desktop_id) { - LauncherEntryRemote* entry; - gchar* app_uri; - - g_return_val_if_fail(desktop_id != NULL, NULL); - - app_uri = g_strconcat("application://", desktop_id, NULL); - entry = LookupByUri(app_uri); - g_free(app_uri); - - return entry; + std::string prefix = "application://"; + return LookupByUri(prefix + desktop_id); } /** - * Return a pointer to a LauncherEntryRemote if there is one for - * desktop_file_path, otherwise NULL. The returned object should not be freed. + * Return a smart pointer to a LauncherEntryRemote if there is one for + * desktop_file_path, otherwise nullptr. */ -LauncherEntryRemote* -LauncherEntryRemoteModel::LookupByDesktopFile(const gchar* desktop_file_path) +LauncherEntryRemote::Ptr LauncherEntryRemoteModel::LookupByDesktopFile(std::string const& desktop_file_path) { - LauncherEntryRemote* entry; - gchar* desktop_id, *app_uri; - - g_return_val_if_fail(desktop_file_path != NULL, NULL); + std::string const& desktop_id = DesktopUtilities::GetDesktopID(desktop_file_path); - desktop_id = g_path_get_basename(desktop_file_path); - app_uri = g_strconcat("application://", desktop_id, NULL); - entry = LookupByUri(app_uri); - g_free(app_uri); - g_free(desktop_id); + if (desktop_id.empty()) + return nullptr; - return entry; + return LookupByDesktopId(desktop_id); } /** * Get a list of all application URIs which have registered with the launcher - * API. The returned GList should be freed with g_list_free(), but the URIs - * should not be changed or freed. + * API. */ -GList* -LauncherEntryRemoteModel::GetUris() +std::list LauncherEntryRemoteModel::GetUris() const { - return (GList*) g_hash_table_get_keys(_entries_by_uri); + std::list uris; + + for (auto entry : _entries_by_uri) + uris.push_back(entry.first); + + return uris; } /** * Add or update a remote launcher entry. - * - * If 'entry' has a floating reference it will be consumed. */ -void -LauncherEntryRemoteModel::AddEntry(LauncherEntryRemote* entry) +void LauncherEntryRemoteModel::AddEntry(LauncherEntryRemote::Ptr const& entry) { - LauncherEntryRemote* existing_entry; + auto existing_entry = LookupByUri(entry->AppUri()); - g_return_if_fail(entry != NULL); - - entry->SinkReference(); - - existing_entry = LookupByUri(entry->AppUri()); - if (existing_entry != NULL) + if (existing_entry) { existing_entry->Update(entry); - entry->UnReference(); } else { - /* The ref on entry will be removed by the hash table itself */ - g_hash_table_insert(_entries_by_uri, g_strdup(entry->AppUri()), entry); + _entries_by_uri[entry->AppUri()] = entry; entry_added.emit(entry); } } /** * Add or update a remote launcher entry. - * - * If 'entry' has a floating reference it will be consumed. */ -void -LauncherEntryRemoteModel::RemoveEntry(LauncherEntryRemote* entry) +void LauncherEntryRemoteModel::RemoveEntry(LauncherEntryRemote::Ptr const& entry) { - g_return_if_fail(entry != NULL); - - entry->Reference(); - - if (g_hash_table_remove(_entries_by_uri, entry->AppUri())) - entry_removed.emit(entry); - - entry->UnReference(); + _entries_by_uri.erase(entry->AppUri()); + entry_removed.emit(entry); } /** * Handle an incoming Update() signal from DBus */ -void -LauncherEntryRemoteModel::HandleUpdateRequest(const gchar* sender_name, - GVariant* parameters) +void LauncherEntryRemoteModel::HandleUpdateRequest(std::string const& sender_name, + GVariant* parameters) { - LauncherEntryRemote* entry; - gchar* app_uri; - GVariantIter* prop_iter; - - g_return_if_fail(sender_name != NULL); - g_return_if_fail(parameters != NULL); - - if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv})"))) - { - g_warning("Received 'com.canonical.Unity.LauncherEntry.Update' with" - " illegal payload signature '%s'. Expected '(sa{sv})'.", - g_variant_get_type_string(parameters)); + if (!parameters) return; - } - if (sender_name == NULL) + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv})"))) { - g_critical("Received 'com.canonical.Unity.LauncherEntry.Update' from" - " an undefined sender. This may happen if you are trying " - "to run Unity on a p2p DBus connection."); + LOG_ERROR(logger) << "Received 'com.canonical.Unity.LauncherEntry.Update' with" + " illegal payload signature '" + << g_variant_get_type_string(parameters) + << "'. Expected '(sa{sv})'."; return; } + glib::String app_uri; + GVariantIter* prop_iter; g_variant_get(parameters, "(sa{sv})", &app_uri, &prop_iter); - entry = LookupByUri(app_uri); + + auto entry = LookupByUri(app_uri.Str()); if (entry) { @@ -271,90 +225,86 @@ } else { - entry = new LauncherEntryRemote(sender_name, parameters); - AddEntry(entry); // consumes floating ref on entry + LauncherEntryRemote::Ptr entry_ptr(new LauncherEntryRemote(sender_name, parameters)); + AddEntry(entry_ptr); } g_variant_iter_free(prop_iter); - g_free(app_uri); } -void -LauncherEntryRemoteModel::on_launcher_entry_signal_received(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data) +void LauncherEntryRemoteModel::OnEntrySignalReceived(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data) { - LauncherEntryRemoteModel* self; - - self = static_cast(user_data); + auto self = static_cast(user_data); - if (parameters == NULL) + if (!parameters || !signal_name) { - g_warning("Received DBus signal '%s.%s' with empty payload from %s", - interface_name, signal_name, sender_name); + LOG_ERROR(logger) << "Received DBus signal '" << interface_name << "." + << signal_name << "' with empty payload from " << sender_name; return; } - if (g_strcmp0(signal_name, "Update") == 0) + if (std::string(signal_name) == "Update") { + if (!sender_name) + { + LOG_ERROR(logger) << "Received 'com.canonical.Unity.LauncherEntry.Update' from" + " an undefined sender. This may happen if you are trying " + "to run Unity on a p2p DBus connection."; + return; + } + self->HandleUpdateRequest(sender_name, parameters); } else { - g_warning("Unknown signal '%s.%s' from %s", - interface_name, signal_name, sender_name); + LOG_ERROR(logger) << "Unknown signal '" << interface_name << "." + << signal_name << "' from " << sender_name; } } void -LauncherEntryRemoteModel::on_dbus_name_owner_changed_signal_received(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data) +LauncherEntryRemoteModel::OnDBusNameOwnerChanged(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data) { - LauncherEntryRemoteModel* self; - char* name, *before, *after; + auto self = static_cast(user_data); - self = static_cast(user_data); - - if (parameters == NULL || self->_entries_by_uri == NULL) + if (!parameters || self->_entries_by_uri.empty()) return; - g_variant_get(parameters, "(&s&s&s)", &name, &before, &after); + glib::String name, before, after; + g_variant_get(parameters, "(sss)", &name, &before, &after); - if (!after[0]) + if (!after || after.Str().empty()) { // Name gone, find and destroy LauncherEntryRemote - GHashTableIter iter; - GList* remove = NULL, *l; - gpointer key, value; + std::vector to_rm; - g_hash_table_iter_init(&iter, self->_entries_by_uri); - while (g_hash_table_iter_next(&iter, &key, &value)) + for (auto it = self->_entries_by_uri.begin(); it != self->_entries_by_uri.end(); ++it) { - /* do something with key and value */ - LauncherEntryRemote* entry = static_cast(value); - if (g_str_equal(entry->DBusName(), name)) - remove = g_list_prepend(remove, entry); - } + auto entry = it->second; - for (l = remove; l; l = l->next) - self->RemoveEntry(static_cast(l->data)); + if (entry->DBusName() == name.Str()) + { + to_rm.push_back(entry); + } + } - g_list_free(remove); + for (auto entry : to_rm) + { + self->RemoveEntry(entry); + } } } -static void -nux_object_destroy_notify(nux::Object* obj) -{ - if (G_LIKELY(obj != NULL)) - obj->UnReference(); } diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherEntryRemoteModel.h unity-5.10.0/plugins/unityshell/src/LauncherEntryRemoteModel.h --- unity-5.8.0/plugins/unityshell/src/LauncherEntryRemoteModel.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherEntryRemoteModel.h 2012-04-12 13:21:21.000000000 +0000 @@ -20,52 +20,56 @@ #ifndef LAUNCHER_ENTRY_REMOTE_MODEL_H #define LAUNCHER_ENTRY_REMOTE_MODEL_H -#include +#include #include +#include #include "LauncherEntryRemote.h" +namespace unity +{ + class LauncherEntryRemoteModel : public sigc::trackable { public: LauncherEntryRemoteModel(); ~LauncherEntryRemoteModel(); - guint Size(); - LauncherEntryRemote* LookupByUri(const gchar* app_uri); - LauncherEntryRemote* LookupByDesktopId(const gchar* desktop_id); - LauncherEntryRemote* LookupByDesktopFile(const gchar* desktop_file_path); - GList* GetUris(); - - void AddEntry(LauncherEntryRemote* entry); - void RemoveEntry(LauncherEntryRemote* entry); - void HandleUpdateRequest(const gchar* sender_name, - GVariant* paramaters); + unsigned int Size() const; + LauncherEntryRemote::Ptr LookupByUri(std::string const& app_uri); + LauncherEntryRemote::Ptr LookupByDesktopId(std::string const& desktop_id); + LauncherEntryRemote::Ptr LookupByDesktopFile(std::string const& desktop_file_path); + std::list GetUris() const; - sigc::signal entry_added; - sigc::signal entry_removed; + sigc::signal entry_added; + sigc::signal entry_removed; private: - static void on_launcher_entry_signal_received(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data); - - static void on_dbus_name_owner_changed_signal_received(GDBusConnection* connection, - const gchar* sender_name, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer user_data); - - GDBusConnection* _conn; - guint _launcher_entry_dbus_signal_id; - guint _dbus_name_owner_changed_signal_id; - GHashTable* _entries_by_uri; + void AddEntry(LauncherEntryRemote::Ptr const& entry); + void RemoveEntry(LauncherEntryRemote::Ptr const& entry); + void HandleUpdateRequest(std::string const& sender_name, GVariant* paramaters); + + static void OnEntrySignalReceived(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data); + + static void OnDBusNameOwnerChanged(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data); + + glib::Object _conn; + unsigned int _launcher_entry_dbus_signal_id; + unsigned int _dbus_name_owner_changed_signal_id; + std::map _entries_by_uri; }; +} // namespace #endif // LAUNCHER_ENTRY_REMOTE_MODEL_H diff -Nru unity-5.8.0/plugins/unityshell/src/Launcher.h unity-5.10.0/plugins/unityshell/src/Launcher.h --- unity-5.8.0/plugins/unityshell/src/Launcher.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/Launcher.h 2012-04-12 13:21:21.000000000 +0000 @@ -33,6 +33,7 @@ #include "BackgroundEffectHelper.h" #include "DNDCollectionWindow.h" #include "DndData.h" +#include "EdgeBarrierController.h" #include "GeisAdapter.h" #include "Introspectable.h" #include "LauncherOptions.h" @@ -40,6 +41,7 @@ #include "LauncherHideMachine.h" #include "LauncherHoverMachine.h" #include "UBusWrapper.h" +#include "SoftwareCenterLauncherIcon.h" namespace unity @@ -49,7 +51,7 @@ class AbstractLauncherIcon; class LauncherModel; -class Launcher : public unity::debug::Introspectable, public nux::View +class Launcher : public unity::debug::Introspectable, public nux::View, public ui::EdgeBarrierSubscriber { NUX_DECLARE_OBJECT_TYPE(Launcher, nux::View); public: @@ -68,6 +70,7 @@ AbstractLauncherIcon::Ptr GetSelectedMenuIcon() const; void SetIconSize(int tile_size, int icon_size); + int GetIconSize() const; LauncherHideMachine* HideMachine() { return _hide_machine; } @@ -113,8 +116,10 @@ void Resize(); sigc::signal launcher_addrequest; - sigc::signal launcher_addrequest_special; + sigc::signal launcher_addrequest_special; sigc::signal launcher_removerequest; + sigc::signal icon_animation_complete; sigc::signal selection_change; sigc::signal hidden_changed; @@ -126,8 +131,12 @@ void ExitKeyNavMode(); bool IsInKeyNavMode() const; + bool IsOverlayOpen() const; + static const int ANIM_DURATION_SHORT; + void RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr icon, nux::ObjectPtr texture); + protected: // Introspectable methods std::string GetName() const; @@ -179,7 +188,7 @@ void OnDragUpdate(GeisAdapter::GeisDragData* data); void OnDragFinish(GeisAdapter::GeisDragData* data); - void OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); + bool HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); void OnPluginStateChanged(); @@ -268,7 +277,6 @@ void OnOverlayHidden(GVariant* data); void OnOverlayShown(GVariant* data); - bool IsOverlayOpen() const; void DesaturateIcons(); void SaturateIcons(); @@ -279,8 +287,6 @@ void OnActionDone(GVariant* data); - void RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr icon, nux::ObjectPtr texture); - AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y); void EventLogic(); void MouseDownLogic(int x, int y, unsigned long button_flags, unsigned long key_flags); @@ -337,9 +343,6 @@ nux::ObjectPtr _offscreen_drag_texture; - ui::PointerBarrierWrapper::Ptr _pointer_barrier; - ui::Decaymulator::Ptr decaymulator_; - int _space_between_icons; int _icon_size; int _icon_image_size; diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/LauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/LauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -66,17 +66,17 @@ NUX_IMPLEMENT_OBJECT_TYPE(LauncherIcon); int LauncherIcon::_current_theme_is_mono = -1; -GtkIconTheme* LauncherIcon::_unity_theme = NULL; +glib::Object LauncherIcon::_unity_theme; LauncherIcon::LauncherIcon() - : _menuclient_dynamic_quicklist(nullptr) - , _remote_urgent(false) + : _remote_urgent(false) , _present_urgency(0) , _progress(0) , _center_stabilize_handle(0) , _present_time_handle(0) , _time_delay_handle(0) , _sort_priority(0) + , _last_monitor(0) , _background_color(nux::color::White) , _glow_color(nux::color::White) , _shortcut(0) @@ -94,6 +94,11 @@ _quirk_times[i].tv_nsec = 0; } + _is_visible_on_monitor.resize(max_num_monitors); + + for (int i = 0; i < max_num_monitors; ++i) + _is_visible_on_monitor[i] = true; + tooltip_text.SetSetterFunction(sigc::mem_fun(this, &LauncherIcon::SetTooltipText)); tooltip_text = "blank"; @@ -139,7 +144,6 @@ if (_unity_theme) { - g_object_unref(_unity_theme); _unity_theme = NULL; } } @@ -184,19 +188,28 @@ void LauncherIcon::AddProperties(GVariantBuilder* builder) { + GVariantBuilder monitors_builder; + g_variant_builder_init(&monitors_builder, G_VARIANT_TYPE ("ab")); + + for (int i = 0; i < max_num_monitors; ++i) + g_variant_builder_add(&monitors_builder, "b", IsVisibleOnMonitor(i)); + unity::variant::BuilderWrapper(builder) - .add("x", _center[0].x) - .add("y", _center[0].y) - .add("z", _center[0].z) - .add("related-windows", (int)Windows().size()) - .add("icon-type", _icon_type) - .add("tooltip-text", tooltip_text()) - .add("sort-priority", _sort_priority) - .add("quirk-active", GetQuirk(QUIRK_ACTIVE)) - .add("quirk-visible", GetQuirk(QUIRK_VISIBLE)) - .add("quirk-urgent", GetQuirk(QUIRK_URGENT)) - .add("quirk-running", GetQuirk(QUIRK_RUNNING)) - .add("quirk-presented", GetQuirk(QUIRK_PRESENTED)); + .add("center_x", _center[0].x) + .add("center_y", _center[0].y) + .add("center_z", _center[0].z) + .add("related_windows", static_cast(Windows().size())) + .add("icon_type", _icon_type) + .add("tooltip_text", tooltip_text()) + .add("sort_priority", _sort_priority) + .add("monitors_visibility", g_variant_builder_end(&monitors_builder)) + .add("active", GetQuirk(QUIRK_ACTIVE)) + .add("visible", GetQuirk(QUIRK_VISIBLE)) + .add("urgent", GetQuirk(QUIRK_URGENT)) + .add("running", GetQuirk(QUIRK_RUNNING)) + .add("starting", GetQuirk(QUIRK_STARTING)) + .add("desaturated", GetQuirk(QUIRK_DESAT)) + .add("presented", GetQuirk(QUIRK_PRESENTED)); } void @@ -323,32 +336,29 @@ { // The theme object is invalid as soon as you add a new icon to change the theme. // invalidate the cache then and rebuild the theme the first time after a icon theme update. - if (!GTK_IS_ICON_THEME(_unity_theme)) + if (!GTK_IS_ICON_THEME(_unity_theme.RawPtr())) { - g_object_unref(_unity_theme); _unity_theme = gtk_icon_theme_new(); gtk_icon_theme_set_custom_theme(_unity_theme, UNITY_THEME_NAME.c_str()); } return _unity_theme; } -nux::BaseTexture* LauncherIcon::TextureFromGtkTheme(const char* icon_name, int size, bool update_glow_colors) +nux::BaseTexture* LauncherIcon::TextureFromGtkTheme(std::string icon_name, int size, bool update_glow_colors) { GtkIconTheme* default_theme; nux::BaseTexture* result = NULL; - if (!icon_name) + if (icon_name.empty()) { - // This leaks, so log if we do this. - LOG_WARN(logger) << "Leaking... no icon_name passed in."; - icon_name = g_strdup(DEFAULT_ICON.c_str()); + icon_name = DEFAULT_ICON; } default_theme = gtk_icon_theme_get_default(); // FIXME: we need to create some kind of -unity postfix to see if we are looking to the unity-icon-theme // for dedicated unity icons, then remove the postfix and degrade to other icon themes if not found - if ((g_strcmp0(icon_name, "workspace-switcher") == 0) && IsMonoDefaultTheme()) + if (icon_name == "workspace-switcher" && IsMonoDefaultTheme()) result = TextureFromSpecificGtkTheme(GetUnityTheme(), icon_name, size, update_glow_colors); if (!result) @@ -356,7 +366,7 @@ if (!result) { - if (g_strcmp0(icon_name, "folder") == 0) + if (icon_name == "folder") result = NULL; else result = TextureFromSpecificGtkTheme(default_theme, "folder", size, update_glow_colors); @@ -367,7 +377,7 @@ } nux::BaseTexture* LauncherIcon::TextureFromSpecificGtkTheme(GtkIconTheme* theme, - const char* icon_name, + std::string const& icon_name, int size, bool update_glow_colors, bool is_default_theme) @@ -377,7 +387,7 @@ GIcon* icon; GtkIconLookupFlags flags = (GtkIconLookupFlags) 0; - icon = g_icon_new_for_string(icon_name, NULL); + icon = g_icon_new_for_string(icon_name.c_str(), NULL); if (G_IS_ICON(icon)) { @@ -386,7 +396,7 @@ } else { - info = gtk_icon_theme_lookup_icon(theme,icon_name, size, flags); + info = gtk_icon_theme_lookup_icon(theme, icon_name.c_str(), size, flags); } if (!info && !is_default_theme) @@ -423,15 +433,15 @@ return result; } -nux::BaseTexture* LauncherIcon::TextureFromPath(const char* icon_name, int size, bool update_glow_colors) +nux::BaseTexture* LauncherIcon::TextureFromPath(std::string const& icon_name, int size, bool update_glow_colors) { nux::BaseTexture* result; - if (!icon_name) - return TextureFromGtkTheme(DEFAULT_ICON.c_str(), size, update_glow_colors); + if (icon_name.empty()) + return TextureFromGtkTheme(DEFAULT_ICON, size, update_glow_colors); glib::Error error; - glib::Object pbuf(gdk_pixbuf_new_from_file_at_size(icon_name, size, size, &error)); + glib::Object pbuf(gdk_pixbuf_new_from_file_at_size(icon_name.c_str(), size, size, &error)); if (GDK_IS_PIXBUF(pbuf.RawPtr())) { @@ -445,7 +455,7 @@ LOG_WARN(logger) << "Unable to load '" << icon_name << "' icon: " << error; - result = TextureFromGtkTheme(DEFAULT_ICON.c_str(), size, update_glow_colors); + result = TextureFromGtkTheme(DEFAULT_ICON, size, update_glow_colors); } return result; @@ -717,6 +727,22 @@ EmitNeedsRedraw(); } +void +LauncherIcon::SetVisibleOnMonitor(int monitor, bool visible) +{ + if (_is_visible_on_monitor[monitor] == visible) + return; + + _is_visible_on_monitor[monitor] = visible; + EmitNeedsRedraw(); +} + +bool +LauncherIcon::IsVisibleOnMonitor(int monitor) const +{ + return _is_visible_on_monitor[monitor]; +} + gboolean LauncherIcon::OnPresentTimeout(gpointer data) { @@ -914,11 +940,11 @@ } void -LauncherIcon::SetEmblemIconName(const char* name) +LauncherIcon::SetEmblemIconName(std::string const& name) { BaseTexturePtr emblem; - if (g_str_has_prefix(name, "/")) + if (name.at(0) == '/') emblem = TextureFromPath(name, 22, false); else emblem = TextureFromGtkTheme(name, 22, false); @@ -929,11 +955,8 @@ } void -LauncherIcon::SetEmblemText(const char* text) +LauncherIcon::SetEmblemText(std::string const& text) { - if (text == NULL) - return; - PangoLayout* layout = NULL; PangoContext* pangoCtx = NULL; @@ -963,11 +986,12 @@ pango_font_description_set_absolute_size(desc, pango_units_from_double(font_height)); pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); pango_layout_set_width(layout, pango_units_from_double(width - 4.0f)); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); - pango_layout_set_markup_with_accel(layout, text, -1, '_', NULL); + pango_layout_set_markup_with_accel(layout, text.c_str(), -1, '_', NULL); pangoCtx = pango_layout_get_context(layout); // is not ref'ed pango_cairo_context_set_font_options(pangoCtx, @@ -1014,7 +1038,7 @@ } void -LauncherIcon::InsertEntryRemote(LauncherEntryRemote* remote) +LauncherIcon::InsertEntryRemote(LauncherEntryRemote::Ptr const& remote) { if (std::find(_entry_list.begin(), _entry_list.end(), remote) != _entry_list.end()) return; @@ -1034,22 +1058,22 @@ if (remote->EmblemVisible()) - OnRemoteEmblemVisibleChanged(remote); + OnRemoteEmblemVisibleChanged(remote.get()); if (remote->CountVisible()) - OnRemoteCountVisibleChanged(remote); + OnRemoteCountVisibleChanged(remote.get()); if (remote->ProgressVisible()) - OnRemoteProgressVisibleChanged(remote); + OnRemoteProgressVisibleChanged(remote.get()); if (remote->Urgent()) - OnRemoteUrgentChanged(remote); + OnRemoteUrgentChanged(remote.get()); - OnRemoteQuicklistChanged(remote); + OnRemoteQuicklistChanged(remote.get()); } void -LauncherIcon::RemoveEntryRemote(LauncherEntryRemote* remote) +LauncherIcon::RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote) { if (std::find(_entry_list.begin(), _entry_list.end(), remote) == _entry_list.end()) return; @@ -1061,6 +1085,8 @@ if (_remote_urgent) SetQuirk(QUIRK_URGENT, false); + + _menuclient_dynamic_quicklist = nullptr; } void @@ -1085,14 +1111,13 @@ if (!remote->CountVisible()) return; - gchar* text; + std::string text; if (remote->Count() > 9999) - text = g_strdup_printf("****"); + text = "****"; else - text = g_strdup_printf("%i", (int) remote->Count()); + text = std::to_string(remote->Count()); SetEmblemText(text); - g_free(text); } void @@ -1101,7 +1126,7 @@ if (!remote->ProgressVisible()) return; - SetProgress((float) remote->Progress()); + SetProgress(remote->Progress()); } void @@ -1124,9 +1149,7 @@ { if (remote->CountVisible()) { - gchar* text = g_strdup_printf("%i", (int) remote->Count()); - SetEmblemText(text); - g_free(text); + SetEmblemText(std::to_string(remote->Count())); } else { @@ -1140,7 +1163,7 @@ SetQuirk(QUIRK_PROGRESS, remote->ProgressVisible()); if (remote->ProgressVisible()) - SetProgress((float) remote->Progress()); + SetProgress(remote->Progress()); } void LauncherIcon::EmitNeedsRedraw() diff -Nru unity-5.8.0/plugins/unityshell/src/LauncherIcon.h unity-5.10.0/plugins/unityshell/src/LauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/LauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -123,9 +123,9 @@ float GetProgress(); - void SetEmblemIconName(const char* name); + void SetEmblemIconName(std::string const& name); - void SetEmblemText(const char* text); + void SetEmblemText(std::string const& text); void DeleteEmblem(); @@ -151,7 +151,7 @@ virtual nux::Color GlowColor(); - const gchar* RemoteUri() + std::string RemoteUri() { return GetRemoteUri(); } @@ -162,9 +162,9 @@ std::list Menus(); - void InsertEntryRemote(LauncherEntryRemote* remote); + void InsertEntryRemote(LauncherEntryRemote::Ptr const& remote); - void RemoveEntryRemote(LauncherEntryRemote* remote); + void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote); nux::DndAction QueryAcceptDrop(unity::DndData& dnd_data) { @@ -194,10 +194,14 @@ virtual bool IsVisible() const { return false; } + virtual bool IsVisibleOnMonitor(int monitor) const; + + virtual void SetVisibleOnMonitor(int monitor, bool visible); + virtual void AboutToRemove() {} - + virtual void Stick(bool save = true) {} - + virtual void UnStick() {} protected: @@ -231,9 +235,9 @@ virtual void OnCenterStabilized(std::vector center) {} - virtual const gchar* GetRemoteUri() + virtual std::string GetRemoteUri() { - return 0; + return ""; } virtual nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data) @@ -253,11 +257,11 @@ virtual bool HandlesSpread () { return false; } - nux::BaseTexture* TextureFromGtkTheme(const char* name, int size, bool update_glow_colors = true); + nux::BaseTexture* TextureFromGtkTheme(std::string name, int size, bool update_glow_colors = true); - nux::BaseTexture* TextureFromSpecificGtkTheme(GtkIconTheme* theme, const char* name, int size, bool update_glow_colors = true, bool is_default_theme = false); + nux::BaseTexture* TextureFromSpecificGtkTheme(GtkIconTheme* theme, std::string const& name, int size, bool update_glow_colors = true, bool is_default_theme = false); - nux::BaseTexture* TextureFromPath(const char* name, int size, bool update_glow_colors = true); + nux::BaseTexture* TextureFromPath(std::string const& name, int size, bool update_glow_colors = true); static bool IsMonoDefaultTheme(); @@ -286,7 +290,7 @@ // This looks like a case for boost::logical::tribool static int _current_theme_is_mono; - DbusmenuClient* _menuclient_dynamic_quicklist; + glib::Object _menuclient_dynamic_quicklist; private: typedef struct @@ -323,21 +327,22 @@ gint64 _shortcut; IconType _icon_type; - + std::vector _center; std::vector _has_visible_window; + std::vector _is_visible_on_monitor; std::vector _last_stable; std::vector _parent_geo; std::vector _saved_center; - static GtkIconTheme* _unity_theme; + static glib::Object _unity_theme; BaseTexturePtr _emblem; bool _quirks[QUIRK_LAST]; struct timespec _quirk_times[QUIRK_LAST]; - std::list _entry_list; + std::list _entry_list; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/LensBar.cpp unity-5.10.0/plugins/unityshell/src/LensBar.cpp --- unity-5.8.0/plugins/unityshell/src/LensBar.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensBar.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -20,8 +20,9 @@ #include "config.h" #include "CairoTexture.h" -#include "DashStyle.h" #include "LensBar.h" +#include "UBusMessages.h" +#include "UBusWrapper.h" namespace unity { @@ -32,8 +33,6 @@ nux::logging::Logger logger("unity.dash.lensbar"); -const int FOCUS_OVERLAY_WIDTH = 60; -const int FOCUS_OVERLAY_HEIGHT = 44; const int LENSBAR_HEIGHT = 44; } @@ -43,20 +42,11 @@ LensBar::LensBar() : nux::View(NUX_TRACKER_LOCATION) { - InitTheme(); SetupBackground(); SetupLayout(); SetupHomeLens(); } -void LensBar::InitTheme() -{ - if (!focus_layer_) - { - focus_layer_.reset(Style::Instance().FocusOverlay(FOCUS_OVERLAY_WIDTH, FOCUS_OVERLAY_HEIGHT)); - } -} - void LensBar::SetupBackground() { nux::ROPConfig rop; @@ -70,7 +60,6 @@ { layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); layout_->SetContentDistribution(nux::MAJOR_POSITION_CENTER); - layout_->SetSpaceBetweenChildren(40); SetLayout(layout_); SetMinimumHeight(LENSBAR_HEIGHT); @@ -84,6 +73,7 @@ icon->active = true; icons_.push_back(icon); layout_->AddView(icon, 0, nux::eCenter, nux::MINOR_SIZE_FULL); + AddChild(icon); icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); QueueDraw(); }); icon->mouse_down.connect([&] (int x, int y, unsigned long button, unsigned long keyboard) { QueueDraw(); }); @@ -98,6 +88,7 @@ lens->visible.changed.connect([icon](bool visible) { icon->SetVisible(visible); } ); icons_.push_back(icon); layout_->AddView(icon, 0, nux::eCenter, nux::eFix); + AddChild(icon); icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); QueueDraw(); }); icon->mouse_down.connect([&] (int x, int y, unsigned long button, unsigned long keyboard) { QueueDraw(); }); @@ -127,26 +118,13 @@ bg_layer_->SetGeometry(base); nux::GetPainter().RenderSinglePaintLayer(gfx_context, base, bg_layer_.get()); - for (auto icon : icons_) - { - if (icon->HasKeyFocus() && focus_layer_) - { - nux::Geometry geo(icon->GetGeometry()); - - // Center it - geo.x -= (FOCUS_OVERLAY_WIDTH - geo.width) / 2; - geo.y -= (FOCUS_OVERLAY_HEIGHT - geo.height) / 2; - geo.width = FOCUS_OVERLAY_WIDTH; - geo.height = FOCUS_OVERLAY_HEIGHT; - - nux::AbstractPaintLayer* layer = focus_layer_.get(); - - layer->SetGeometry(geo); - layer->Renderlayer(gfx_context); - } - } - gfx_context.PopClippingRectangle(); + + // trigger a redraw of the decoration, as the special masking of the + // decoration is usually destroyed by the clipping-rects/previous paints + ubus_server_send_message(ubus_server_get_default(), + UBUS_DASH_DECORATION_DAMAGED, + NULL); } void LensBar::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw) @@ -158,16 +136,6 @@ if (!IsFullRedraw()) nux::GetPainter().PushLayer(gfx_context, bg_layer_->GetGeometry(), bg_layer_.get()); - for (auto icon: icons_) - { - if (icon->HasKeyFocus() && !IsFullRedraw() && focus_layer_) - { - nux::AbstractPaintLayer* layer = focus_layer_.get(); - - nux::GetPainter().PushLayer(gfx_context, focus_layer_->GetGeometry(), layer); - } - } - layout_->ProcessDraw(gfx_context, force_draw); if (!IsFullRedraw()) @@ -218,6 +186,13 @@ void LensBar::ActivateNext() { + // Special case when switching from the command lens. + if (GetActiveLensId() == "commands.lens") + { + SetActive(icons_[0]); + return; + } + bool activate_next = false; for (auto it = icons_.begin(); it < icons_.end(); @@ -239,8 +214,14 @@ void LensBar::ActivatePrevious() { - bool activate_previous = false; + // Special case when switching from the command lens. + if (GetActiveLensId() == "commands.lens") + { + SetActive(icons_.back()); + return; + } + bool activate_previous = false; for (auto it = icons_.rbegin(); it < icons_.rend(); ++it) @@ -287,5 +268,15 @@ } } +std::string LensBar::GetActiveLensId() const +{ + for (auto icon : icons_) + { + if (icon->active) + return icon->id; + } + return ""; +} + } } diff -Nru unity-5.8.0/plugins/unityshell/src/LensBar.h unity-5.10.0/plugins/unityshell/src/LensBar.h --- unity-5.8.0/plugins/unityshell/src/LensBar.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensBar.h 2012-04-12 13:21:21.000000000 +0000 @@ -59,7 +59,6 @@ sigc::signal lens_activated; private: - void InitTheme(); void SetupBackground(); void SetupLayout(); void SetupHomeLens(); @@ -74,13 +73,13 @@ void AddProperties(GVariantBuilder* builder); private: + std::string GetActiveLensId() const; typedef std::unique_ptr LayerPtr; LensIcons icons_; nux::HLayout* layout_; LayerPtr bg_layer_; - LayerPtr focus_layer_; }; } // namespace dash diff -Nru unity-5.8.0/plugins/unityshell/src/LensBarIcon.cpp unity-5.10.0/plugins/unityshell/src/LensBarIcon.cpp --- unity-5.8.0/plugins/unityshell/src/LensBarIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensBarIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -16,6 +16,9 @@ * Authored by: Neil Jagdish Patel */ +#include + +#include "DashStyle.h" #include "LensBarIcon.h" #include "config.h" @@ -24,19 +27,29 @@ { namespace dash { +namespace +{ + +const int FOCUS_OVERLAY_HEIGHT = 44; +const int FOCUS_OVERLAY_WIDTH = 60; + +} NUX_IMPLEMENT_OBJECT_TYPE(LensBarIcon); LensBarIcon::LensBarIcon(std::string id_, std::string icon_hint) - : IconTexture(icon_hint.c_str(), 24) + : IconTexture(icon_hint, 24) , id(id_) , active(false) , inactive_opacity_(0.4f) { - SetMinimumWidth(24); - SetMaximumWidth(24); - SetMinimumHeight(24); - SetMaximumHeight(24); + SetMinimumWidth(FOCUS_OVERLAY_WIDTH); + SetMaximumWidth(FOCUS_OVERLAY_WIDTH); + SetMinimumHeight(FOCUS_OVERLAY_HEIGHT); + SetMaximumHeight(FOCUS_OVERLAY_HEIGHT); + + focus_layer_.reset(Style::Instance().FocusOverlay(FOCUS_OVERLAY_WIDTH, FOCUS_OVERLAY_HEIGHT)); + SetOpacity(inactive_opacity_); SetAcceptKeyNavFocus(true); @@ -54,7 +67,6 @@ nux::Geometry const& geo = GetGeometry(); gfx_context.PushClippingRectangle(geo); - nux::GetPainter().PaintBackground(gfx_context, geo); if (!texture()) @@ -63,6 +75,15 @@ return; } + if (HasKeyFocus() && focus_layer_) + { + nux::Geometry geo(GetGeometry()); + nux::AbstractPaintLayer* layer = focus_layer_.get(); + + layer->SetGeometry(geo); + layer->Renderlayer(gfx_context); + } + float opacity = active ? 1.0f : inactive_opacity_; int width = 0, height = 0; GetTextureSize(&width, &height); @@ -88,5 +109,19 @@ QueueDraw(); } +// Introspectable +std::string LensBarIcon::GetName() const +{ + return "LensBarIcon"; +} + +void LensBarIcon::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper wrapper(builder); + + wrapper.add(GetAbsoluteGeometry()); + wrapper.add("name", id); +} + } } diff -Nru unity-5.8.0/plugins/unityshell/src/LensBarIcon.h unity-5.10.0/plugins/unityshell/src/LensBarIcon.h --- unity-5.8.0/plugins/unityshell/src/LensBarIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensBarIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -47,8 +47,15 @@ void Draw(nux::GraphicsEngine& gfx_context, bool force_draw); void OnActiveChanged(bool is_active); + // Introspectable + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + private: + typedef std::unique_ptr LayerPtr; + const float inactive_opacity_; + LayerPtr focus_layer_; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/LensView.cpp unity-5.10.0/plugins/unityshell/src/LensView.cpp --- unity-5.8.0/plugins/unityshell/src/LensView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensView.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -40,6 +40,9 @@ namespace { nux::logging::Logger logger("unity.dash.lensview"); + +const int CARD_VIEW_GAP_VERT = 24; // pixels +const int CARD_VIEW_GAP_HORIZ = 25; // pixels } // This is so we can access some protected members in scrollview. @@ -117,7 +120,6 @@ LensView::LensView() : nux::View(NUX_TRACKER_LOCATION) - , search_string("") , filters_expanded(false) , can_refine_search(false) , no_results_active_(false) @@ -126,7 +128,6 @@ LensView::LensView(Lens::Ptr lens, nux::Area* show_filters) : nux::View(NUX_TRACKER_LOCATION) - , search_string("") , filters_expanded(false) , can_refine_search(false) , lens_(lens) @@ -142,7 +143,7 @@ dash::Style::Instance().columns_changed.connect(sigc::mem_fun(this, &LensView::OnColumnsChanged)); lens_->connected.changed.connect([&](bool is_connected) { if (is_connected) initial_activation_ = true; }); - search_string.changed.connect([&](std::string const& search) { lens_->Search(search); }); + search_string.SetGetterFunction(sigc::mem_fun(this, &LensView::get_search_string)); filters_expanded.changed.connect([&](bool expanded) { fscroll_view_->SetVisible(expanded); QueueRelayout(); OnColumnsChanged(); }); view_type.changed.connect(sigc::mem_fun(this, &LensView::OnViewTypeChanged)); @@ -201,6 +202,7 @@ no_results_ = new nux::StaticCairoText("", NUX_TRACKER_LOCATION); no_results_->SetTextColor(nux::color::White); + no_results_->SetVisible(false); 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); @@ -287,7 +289,11 @@ ResultViewGrid* grid = new ResultViewGrid(NUX_TRACKER_LOCATION); grid->expanded = false; if (renderer_name == "tile-horizontal") + { grid->SetModelRenderer(new ResultRendererHorizontalTile(NUX_TRACKER_LOCATION)); + grid->horizontal_spacing = CARD_VIEW_GAP_HORIZ; + grid->vertical_spacing = CARD_VIEW_GAP_VERT; + } else grid->SetModelRenderer(new ResultRendererTile(NUX_TRACKER_LOCATION)); @@ -313,6 +319,11 @@ grid->AddResult(const_cast(result)); counts_[group]++; UpdateCounts(group); + // make sure we don't display the no-results-hint if we do have results + if (G_UNLIKELY (no_results_active_)) + { + CheckNoResults(Lens::Hints()); + } } catch (std::out_of_range& oor) { LOG_WARN(logger) << "Result does not have a valid category index: " << boost::lexical_cast(result.category_index) @@ -380,7 +391,7 @@ { gint count = lens_->results()->count(); - if (!count && !no_results_active_) + if (count == 0 && !no_results_active_ && !search_string_.empty()) { std::stringstream markup; Lens::Hints::const_iterator it; @@ -404,6 +415,7 @@ no_results_active_ = true; no_results_->SetText(markup.str()); + no_results_->SetVisible(true); } else if (count && no_results_active_) { @@ -411,6 +423,7 @@ no_results_active_ = false; no_results_->SetText(""); + no_results_->SetVisible(false); } } @@ -421,9 +434,21 @@ scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START); no_results_active_ = false; no_results_->SetText(""); + no_results_->SetVisible(false); } } +void LensView::PerformSearch(std::string const& search_query) +{ + search_string_ = search_query; + lens_->Search(search_query); +} + +std::string LensView::get_search_string() const +{ + return search_string_; +} + void LensView::OnGroupExpanded(PlacesGroup* group) { ResultViewGrid* grid = static_cast(group->GetChildView()); @@ -458,7 +483,7 @@ if (view_type != HIDDEN && initial_activation_) { /* We reset the lens for ourselves, in case this is a restart or something */ - lens_->Search(search_string); + lens_->Search(search_string_); initial_activation_ = false; } diff -Nru unity-5.8.0/plugins/unityshell/src/LensView.h unity-5.10.0/plugins/unityshell/src/LensView.h --- unity-5.8.0/plugins/unityshell/src/LensView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/LensView.h 2012-04-12 13:21:21.000000000 +0000 @@ -63,13 +63,14 @@ virtual void ActivateFirst(); - nux::Property search_string; + nux::ROProperty search_string; nux::Property filters_expanded; nux::Property view_type; nux::Property can_refine_search; sigc::signal uri_activated; + void PerformSearch(std::string const& search_query); void CheckNoResults(Lens::Hints const& hints); void HideResultsMessage(); @@ -99,6 +100,8 @@ virtual std::string GetName() const; virtual void AddProperties(GVariantBuilder* builder); + std::string get_search_string() const; + private: UBusManager ubus_manager_; Lens::Ptr lens_; @@ -106,6 +109,7 @@ ResultCounts counts_; bool initial_activation_; bool no_results_active_; + std::string search_string_; nux::HLayout* layout_; LensScrollView* scroll_view_; diff -Nru unity-5.8.0/plugins/unityshell/src/MockLauncherIcon.h unity-5.10.0/plugins/unityshell/src/MockLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/MockLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/MockLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -163,6 +163,13 @@ return false; } + void SetVisibleOnMonitor(int monitor, bool visible) {} + + bool IsVisibleOnMonitor(int monitor) const + { + return true; + } + bool IsSpacer() { return false; @@ -183,9 +190,9 @@ return true; } - void InsertEntryRemote(LauncherEntryRemote* remote) {} + void InsertEntryRemote(LauncherEntryRemote::Ptr const& remote) {} - void RemoveEntryRemote(LauncherEntryRemote* remote) {} + void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote) {} unsigned long long SwitcherPriority() { @@ -222,7 +229,7 @@ return nux::Color(0xFFAAAAAA); } - const gchar* RemoteUri() + std::string RemoteUri() { return "fake"; } diff -Nru unity-5.8.0/plugins/unityshell/src/OverlayRenderer.cpp unity-5.10.0/plugins/unityshell/src/OverlayRenderer.cpp --- unity-5.8.0/plugins/unityshell/src/OverlayRenderer.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/OverlayRenderer.cpp 2012-04-13 16:25:31.000000000 +0000 @@ -38,6 +38,7 @@ nux::logging::Logger logger("unity.overlayrenderer"); const int INNER_CORNER_RADIUS = 5; +const int EXCESS_BORDER = 10; } // Impl class @@ -49,6 +50,7 @@ void Init(); void OnBackgroundColorChanged(GVariant* args); + void OnDashDecorationDamanged(GVariant* args); void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_draw); void DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry); @@ -70,6 +72,18 @@ UBusManager ubus_manager_; OverlayRenderer *parent; + + void InitASMInverseTextureMaskShader(); + void InitSlInverseTextureMaskShader(); + + nux::ObjectPtr inverse_texture_mask_asm_prog_; + nux::ObjectPtr inverse_texture_rect_mask_asm_prog_; + nux::ObjectPtr inverse_texture_mask_prog_; + + void RenderInverseMask_GLSL(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0); + void RenderInverseMask_ASM(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0); + void RenderInverseMask(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0); + }; OverlayRendererImpl::OverlayRendererImpl(OverlayRenderer *parent_) @@ -103,6 +117,9 @@ ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &OverlayRendererImpl::OnBackgroundColorChanged)); + ubus_manager_.RegisterInterest(UBUS_DASH_DECORATION_DAMAGED, + sigc::mem_fun(this, &OverlayRendererImpl::OnDashDecorationDamanged)); + ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT); } @@ -118,22 +135,410 @@ parent->need_redraw.emit(); } +void OverlayRendererImpl::OnDashDecorationDamanged(GVariant* args) +{ + parent->need_redraw.emit(); +} + +void OverlayRendererImpl::InitASMInverseTextureMaskShader() +{ + nux::NString AsmVtx = + "!!ARBvp1.0 \n\ + ATTRIB iPos = vertex.position; \n\ + ATTRIB iColor = vertex.attrib[3]; \n\ + PARAM mvp[4] = {state.matrix.mvp}; \n\ + OUTPUT oPos = result.position; \n\ + OUTPUT oColor = result.color; \n\ + OUTPUT oTexCoord0 = result.texcoord[0]; \n\ + # Transform the vertex to clip coordinates. \n\ + DP4 oPos.x, mvp[0], iPos; \n\ + DP4 oPos.y, mvp[1], iPos; \n\ + DP4 oPos.z, mvp[2], iPos; \n\ + DP4 oPos.w, mvp[3], iPos; \n\ + MOV oColor, iColor; \n\ + MOV oTexCoord0, vertex.attrib[8]; \n\ + END"; + + nux::NString AsmFrg = + "!!ARBfp1.0 \n\ + TEMP tex0; \n\ + TEMP temp0; \n\ + TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ + MUL temp0, fragment.color, tex0; \n\ + SUB result.color, {1.0, 1.0, 1.0, 1.0}, temp0.aaaa;\n\ + END"; + + nux::NString AsmFrgRect = + "!!ARBfp1.0 \n\ + TEMP tex0; \n\ + TEMP temp0; \n\ + TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ + MUL temp0, fragment.color, tex0; \n\ + SUB result.color, {1.0, 1.0, 1.0, 1.0}, temp0.aaaa; \n\ + END"; + + inverse_texture_mask_asm_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); + inverse_texture_mask_asm_prog_->LoadVertexShader(AsmVtx.GetTCharPtr()); + inverse_texture_mask_asm_prog_->LoadPixelShader(AsmFrg.GetTCharPtr()); + inverse_texture_mask_asm_prog_->Link(); + + inverse_texture_rect_mask_asm_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); + inverse_texture_rect_mask_asm_prog_->LoadVertexShader(AsmVtx.GetTCharPtr()); + inverse_texture_rect_mask_asm_prog_->LoadPixelShader(AsmFrgRect.GetTCharPtr()); + inverse_texture_rect_mask_asm_prog_->Link(); +} + +void OverlayRendererImpl::RenderInverseMask_ASM(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr device_texture, nux::TexCoordXForm &texxform, const nux::Color &color) +{ +#ifndef NUX_OPENGLES_20 + if (!inverse_texture_mask_asm_prog_.IsValid() || !inverse_texture_rect_mask_asm_prog_.IsValid()) + { + InitASMInverseTextureMaskShader(); + } + + QRP_Compute_Texture_Coord(width, height, device_texture, texxform); + float fx = x, fy = y; + float VtxBuffer[] = + { + fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, + fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, + fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, + fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, + }; + + CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); + CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); + + nux::ObjectPtr shader_program = inverse_texture_mask_asm_prog_; + if (device_texture->Type().IsDerivedFromType(nux::IOpenGLRectangleTexture::StaticObjectType)) + { + shader_program = inverse_texture_rect_mask_asm_prog_; + } + shader_program->Begin(); + + gfx_context.SetTexture(GL_TEXTURE0, device_texture); + + CHECKGL(glMatrixMode(GL_MODELVIEW)); + CHECKGL(glLoadIdentity()); + CHECKGL(glLoadMatrixf((FLOAT *) gfx_context.GetOpenGLModelViewMatrix().m)); + CHECKGL(glMatrixMode(GL_PROJECTION)); + CHECKGL(glLoadIdentity()); + CHECKGL(glLoadMatrixf((FLOAT *) gfx_context.GetOpenGLProjectionMatrix().m)); + + + int VertexLocation = nux::VTXATTRIB_POSITION; + int TextureCoord0Location = nux::VTXATTRIB_TEXCOORD0; + int VertexColorLocation = nux::VTXATTRIB_COLOR; + + CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); + CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); + + if (TextureCoord0Location != -1) + { + CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); + CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); + } + + if (VertexColorLocation != -1) + { + CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); + CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); + } + + CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); + + CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); + + if (TextureCoord0Location != -1) + CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); + + if (VertexColorLocation != -1) + CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); + + shader_program->End(); +#endif +} + +void OverlayRendererImpl::InitSlInverseTextureMaskShader() +{ + nux::ObjectPtr VS = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); + nux::ObjectPtr PS = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); + nux::NString VSString; + nux::NString PSString; + + VSString = + NUX_VERTEX_SHADER_HEADER + "attribute vec4 AVertex; \n\ + attribute vec4 MyTextureCoord0; \n\ + attribute vec4 VertexColor; \n\ + uniform mat4 ViewProjectionMatrix; \n\ + varying vec4 varyTexCoord0; \n\ + varying vec4 varyVertexColor; \n\ + void main() \n\ + { \n\ + gl_Position = ViewProjectionMatrix * (AVertex); \n\ + varyTexCoord0 = MyTextureCoord0; \n\ + varyVertexColor = VertexColor; \n\ + }"; + + PSString = + NUX_FRAGMENT_SHADER_HEADER + "varying vec4 varyTexCoord0; \n\ + varying vec4 varyVertexColor; \n\ + uniform sampler2D TextureObject0; \n\ + void main() \n\ + { \n\ + vec4 v = varyVertexColor*texture2D(TextureObject0, varyTexCoord0.xy); \n\ + gl_FragColor = vec4(1.0-v.a); \n\ + }"; + + // Textured 2D Primitive Shader + inverse_texture_mask_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); + VS->SetShaderCode(TCHAR_TO_ANSI(*VSString)); + PS->SetShaderCode(TCHAR_TO_ANSI(*PSString), "#define SAMPLERTEX2D"); + + inverse_texture_mask_prog_->ClearShaderObjects(); + inverse_texture_mask_prog_->AddShaderObject(VS); + inverse_texture_mask_prog_->AddShaderObject(PS); + CHECKGL(glBindAttribLocation(inverse_texture_mask_prog_->GetOpenGLID(), 0, "AVertex")); + inverse_texture_mask_prog_->Link(); +} + +void OverlayRendererImpl::RenderInverseMask_GLSL(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0) +{ + if (!inverse_texture_mask_prog_.IsValid()) + InitSlInverseTextureMaskShader(); + + QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0); + float fx = x, fy = y; + float VtxBuffer[] = + { + fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, + fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, + fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, + fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, + }; + + nux::ObjectPtr ShaderProg; + + if (DeviceTexture->Type().IsDerivedFromType(nux::IOpenGLTexture2D::StaticObjectType)) + { + ShaderProg = inverse_texture_mask_prog_; + } + + CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); + CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); + ShaderProg->Begin(); + + int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); + int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); + int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); + int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); + + gfx_context.SetTexture(GL_TEXTURE0, DeviceTexture); + CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); + + int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); + nux::Matrix4 MVPMatrix = gfx_context.GetOpenGLModelViewProjectionMatrix(); + ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); + + CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); + CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); + + if (TextureCoord0Location != -1) + { + CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); + CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); + } + + if (VertexColorLocation != -1) + { + CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); + CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); + } + + CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); + + CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); + + if (TextureCoord0Location != -1) + CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); + + if (VertexColorLocation != -1) + CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); + + ShaderProg->End(); +} + +void OverlayRendererImpl::RenderInverseMask(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0) +{ + if (nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath()) + { + RenderInverseMask_GLSL(gfx_context, x, y, width, height, DeviceTexture, texxform0, color0); + } + else + { + RenderInverseMask_ASM(gfx_context, x, y, width, height, DeviceTexture, texxform0, color0); + } +} + 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 larger_content_geo = content_geo; + larger_content_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER); + + nux::Geometry larger_geo(larger_content_geo); + + nux::Geometry larger_absolute_geo = absolute_geo; + larger_absolute_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER); + + 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) larger_content_geo.x) / larger_absolute_geo.width; + texxform_absolute_bg.voffset = ((float) larger_content_geo.y) / larger_absolute_geo.height; + texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); + + nux::Geometry blur_geo(larger_absolute_geo.x, larger_absolute_geo.y, larger_content_geo.width, larger_content_geo.height); + if (paint_blur) + { + bg_blur_texture_ = bg_effect_helper_.GetBlurRegion(blur_geo); + } + else + { + bg_blur_texture_ = bg_effect_helper_.GetRegion(blur_geo); + } + + if (bg_blur_texture_.IsValid()) + { + nux::Geometry bg_clip = larger_geo; + gfx_context.PushClippingRectangle(bg_clip); + + gfx_context.GetRenderStates().SetBlend(false); +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath()) + gfx_context.QRP_GLSL_ColorBlendOverTex (larger_content_geo.x, larger_content_geo.y, + larger_content_geo.width, larger_content_geo.height, + bg_blur_texture_, texxform_absolute_bg, nux::color::White, + bg_color_, nux::LAYER_BLEND_MODE_OVERLAY); + + else + gfx_context.QRP_1Tex (larger_content_geo.x, larger_content_geo.y, + larger_content_geo.width, larger_content_geo.height, + bg_blur_texture_, texxform_absolute_bg, nux::color::White); +#else + gfx_context.QRP_GLSL_ColorBlendOverTex (larger_content_geo.x, larger_content_geo.y, + larger_content_geo.width, larger_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.1f; + const int gradient_width = 130; + const int gradient_height = 50; + const int horizontal_padding = 40; + const int vertical_padding = 20; + + // Now that we mask the corners of the dash, + // draw longer lines to fill the minimal gaps + const int corner_overlap = 3; + + nux::Color line_color = nux::color::White * line_opacity; + + // Vertical lancher/dash separator + nux::GetPainter().Paint2DQuadColor(gfx_context, + nux::Geometry(geometry.x, + geometry.y + vertical_padding, + style.GetVSeparatorSize(), + gradient_height), + nux::color::Transparent, + line_color * 0.7f, // less opacity + line_color * 0.7f, // less opacity + nux::color::Transparent); + nux::GetPainter().Draw2DLine(gfx_context, + geometry.x, + geometry.y + vertical_padding + gradient_height, + style.GetVSeparatorSize(), + geometry.y + content_geo.height + INNER_CORNER_RADIUS + corner_overlap, + line_color * 0.7f); // less opacity + + // Horizontal panel/dash separator + nux::GetPainter().Paint2DQuadColor(gfx_context, + nux::Geometry(geometry.x + horizontal_padding, + geometry.y, + gradient_width, + style.GetHSeparatorSize()), + nux::color::Transparent, + nux::color::Transparent, + line_color, + line_color); + nux::GetPainter().Draw2DLine(gfx_context, + geometry.x + horizontal_padding + gradient_width, + geometry.y, + geometry.x + content_geo.width + INNER_CORNER_RADIUS + corner_overlap, + style.GetHSeparatorSize(), + line_color); + + // Draw the background + bg_darken_layer_->SetGeometry(larger_content_geo); + nux::GetPainter().RenderSinglePaintLayer(gfx_context, larger_content_geo, bg_darken_layer_); + +#ifndef NUX_OPENGLES_20 + if (gfx_context.UsingGLSLCodePath() == FALSE) + { + bg_layer_->SetGeometry(larger_content_geo); + nux::GetPainter().RenderSinglePaintLayer(gfx_context, larger_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 (larger_content_geo.x, larger_content_geo.y, + larger_content_geo.width, larger_content_geo.height, + bg_shine_texture_, texxform_absolute_bg, nux::color::White); + if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges) { // Paint the edges { + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + dash::Style& style = dash::Style::Instance(); nux::BaseTexture* bottom = style.GetDashBottomTile(); + nux::BaseTexture* bottom_mask = style.GetDashBottomTileMask(); nux::BaseTexture* right = style.GetDashRightTile(); + nux::BaseTexture* right_mask = style.GetDashRightTileMask(); nux::BaseTexture* corner = style.GetDashCorner(); + nux::BaseTexture* corner_mask = style.GetDashCornerMask(); nux::BaseTexture* left_corner = style.GetDashLeftCorner(); + nux::BaseTexture* left_corner_mask = style.GetDashLeftCornerMask(); nux::BaseTexture* left_tile = style.GetDashLeftTile(); nux::BaseTexture* top_corner = style.GetDashTopCorner(); + nux::BaseTexture* top_corner_mask = style.GetDashTopCornerMask(); nux::BaseTexture* top_tile = style.GetDashTopTile(); nux::TexCoordXForm texxform; @@ -147,6 +552,30 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER); + // Selectively erase blur region in the curbe + gfx_context.QRP_ColorModTexAlpha(geo.x + (geo.width - corner->GetWidth()), + geo.y + (geo.height - corner->GetHeight()), + corner->GetWidth(), + corner->GetHeight(), + corner_mask->GetDeviceTexture(), + texxform, + nux::color::Black); + + // Write correct alpha + gfx_context.GetRenderStates().SetBlend(false); + gfx_context.GetRenderStates().SetColorMask(false, false, false, true); + RenderInverseMask(gfx_context, geo.x + (geo.width - corner->GetWidth()), + geo.y + (geo.height - corner->GetHeight()), + corner->GetWidth(), + corner->GetHeight(), + corner_mask->GetDeviceTexture(), + texxform, + nux::color::White); + + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.QRP_1Tex(geo.x + (geo.width - corner->GetWidth()), geo.y + (geo.height - corner->GetHeight()), corner->GetWidth(), @@ -163,6 +592,30 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + // Selectively erase blur region in the curbe + gfx_context.QRP_ColorModTexAlpha(left_corner->GetWidth() - left_corner_offset - offset, + geo.y + (geo.height - bottom->GetHeight()), + real_width + offset, + bottom->GetHeight(), + bottom_mask->GetDeviceTexture(), + texxform, + nux::color::Black); + + // Write correct alpha + gfx_context.GetRenderStates().SetBlend(false); + gfx_context.GetRenderStates().SetColorMask(false, false, false, true); + RenderInverseMask(gfx_context, left_corner->GetWidth() - left_corner_offset - offset, + geo.y + (geo.height - bottom->GetHeight()), + real_width + offset, + bottom->GetHeight(), + bottom_mask->GetDeviceTexture(), + texxform, + nux::color::White); + + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.QRP_1Tex(left_corner->GetWidth() - left_corner_offset - offset, geo.y + (geo.height - bottom->GetHeight()), real_width + offset, @@ -176,6 +629,30 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER); + // Selectively erase blur region in the curbe + gfx_context.QRP_ColorModTexAlpha(geo.x - left_corner_offset, + geo.y + (geo.height - left_corner->GetHeight()), + left_corner->GetWidth(), + left_corner->GetHeight(), + left_corner_mask->GetDeviceTexture(), + texxform, + nux::color::Black); + + // Write correct alpha + gfx_context.GetRenderStates().SetBlend(false); + gfx_context.GetRenderStates().SetColorMask(false, false, false, true); + RenderInverseMask(gfx_context, geo.x - left_corner_offset, + geo.y + (geo.height - left_corner->GetHeight()), + left_corner->GetWidth(), + left_corner->GetHeight(), + left_corner_mask->GetDeviceTexture(), + texxform, + nux::color::White); + + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.QRP_1Tex(geo.x - left_corner_offset, geo.y + (geo.height - left_corner->GetHeight()), left_corner->GetWidth(), @@ -194,7 +671,7 @@ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); gfx_context.QRP_1Tex(geo.x - 10, - geo.y + geo.height - offset, + geo.y + geo.height, left_tile->GetWidth(), real_height + offset, left_tile->GetDeviceTexture(), @@ -206,6 +683,30 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + // Selectively erase blur region in the curbe + gfx_context.QRP_ColorModTexAlpha(geo.x + geo.width - right->GetWidth(), + geo.y + top_corner->GetHeight() - top_corner_offset, + right->GetWidth(), + geo.height - corner->GetHeight() - (top_corner->GetHeight() - top_corner_offset), + right_mask->GetDeviceTexture(), + texxform, + nux::color::Black); + + // Write correct alpha + gfx_context.GetRenderStates().SetBlend(false); + gfx_context.GetRenderStates().SetColorMask(false, false, false, true); + RenderInverseMask(gfx_context, geo.x + geo.width - right->GetWidth(), + geo.y + top_corner->GetHeight() - top_corner_offset, + right->GetWidth(), + geo.height - corner->GetHeight() - (top_corner->GetHeight() - top_corner_offset), + right_mask->GetDeviceTexture(), + texxform, + nux::color::White); + + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.QRP_1Tex(geo.x + geo.width - right->GetWidth(), geo.y + top_corner->GetHeight() - top_corner_offset, right->GetWidth(), @@ -219,6 +720,29 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER); + // Selectively erase blur region in the curbe + gfx_context.QRP_ColorModTexAlpha(geo.x + geo.width - right->GetWidth(), + geo.y - top_corner_offset, + top_corner->GetWidth(), + top_corner->GetHeight(), + top_corner_mask->GetDeviceTexture(), + texxform, + nux::color::Black); + + // Write correct alpha + gfx_context.GetRenderStates().SetBlend(false); + gfx_context.GetRenderStates().SetColorMask(false, false, false, true); + RenderInverseMask(gfx_context, geo.x + geo.width - right->GetWidth(), + geo.y - top_corner_offset, + top_corner->GetWidth(), + top_corner->GetHeight(), + top_corner_mask->GetDeviceTexture(), + texxform, + nux::color::White); + + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); gfx_context.QRP_1Tex(geo.x + geo.width - right->GetWidth(), geo.y - top_corner_offset, top_corner->GetWidth(), @@ -232,6 +756,7 @@ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); gfx_context.QRP_1Tex(geo.x + geo.width, geo.y - 10, geometry.width - (geo.x + geo.width), @@ -240,147 +765,27 @@ texxform, nux::color::White); } - } - } - - - 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); -#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.22f; - nux::Color line_color = nux::color::White * line_opacity; - nux::GetPainter().Paint2DQuadColor(gfx_context, - nux::Geometry(geometry.x, - geometry.y, - style.GetVSeparatorSize(), - content_geo.height + INNER_CORNER_RADIUS), - nux::color::Transparent, - line_color, - line_color, - nux::color::Transparent); - - nux::GetPainter().Paint2DQuadColor(gfx_context, - nux::Geometry(geometry.x, - geometry.y, - content_geo.width + INNER_CORNER_RADIUS, - 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_); - -#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 - nux::ROPConfig rop; - rop.Blend = true; - rop.SrcBlend = GL_ZERO; - rop.DstBlend = GL_SRC_ALPHA; - nux::GetPainter().PaintShapeCornerROP(gfx_context, - content_geo, - nux::color::White, - nux::eSHAPE_CORNER_ROUND4, - nux::eCornerBottomRight, - true, - rop); - - geo = content_geo; - - gfx_context.GetRenderStates().SetColorMask(true, true, true, true); - gfx_context.GetRenderStates().SetBlend(true); - gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - - // Fill in corners (meh) - for (int i = 0; i < INNER_CORNER_RADIUS; ++i) - { - 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); - nux::GetPainter().Paint2DQuadColor(gfx_context, fill_geo, dark); } } } void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry) { - bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE; nux::Geometry geo = geometry; bgs = 0; - gfx_context.PushClippingRectangle(geo); + nux::Geometry larger_content_geo = content_geo; + larger_content_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER); + + nux::Geometry larger_geo(larger_content_geo); + + nux::Geometry larger_absolute_geo = absolute_geo; + larger_absolute_geo.OffsetSize(EXCESS_BORDER, EXCESS_BORDER); + + + gfx_context.PushClippingRectangle(larger_geo); gfx_context.GetRenderStates().SetBlend(true); gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); @@ -388,8 +793,8 @@ 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.uoffset = ((float) larger_content_geo.x) / absolute_geo.width; + texxform_absolute_bg.voffset = ((float) larger_content_geo.y) / absolute_geo.height; texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); nux::ROPConfig rop; @@ -397,25 +802,25 @@ rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - if (bg_blur_texture_.IsValid() && paint_blur) + if (bg_blur_texture_.IsValid()) { #ifndef NUX_OPENGLES_20 if (gfx_context.UsingGLSLCodePath()) - gPainter.PushCompositionLayer(gfx_context, content_geo, + gPainter.PushCompositionLayer(gfx_context, larger_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, + gPainter.PushTextureLayer(gfx_context, larger_content_geo, bg_blur_texture_, texxform_absolute_bg, nux::color::White, true, // write alpha? rop); #else - gPainter.PushCompositionLayer(gfx_context, content_geo, + gPainter.PushCompositionLayer(gfx_context, larger_content_geo, bg_blur_texture_, texxform_absolute_bg, nux::color::White, @@ -445,7 +850,7 @@ 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, content_geo, + nux::GetPainter().PushTextureLayer(gfx_context, larger_content_geo, bg_shine_texture_, texxform_absolute_bg, nux::color::White, @@ -461,22 +866,6 @@ gfx_context.GetRenderStates().SetBlend(false); gfx_context.PopClippingRectangle(); - if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) - { - // Make bottom-right corner rounded - nux::ROPConfig rop; - rop.Blend = true; - rop.SrcBlend = GL_ZERO; - rop.DstBlend = GL_SRC_ALPHA; - nux::GetPainter().PaintShapeCornerROP(gfx_context, - content_geo, - nux::color::White, - nux::eSHAPE_CORNER_ROUND4, - nux::eCornerBottomRight, - true, - rop); - } - bgs = 0; } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelController.cpp unity-5.10.0/plugins/unityshell/src/PanelController.cpp --- unity-5.8.0/plugins/unityshell/src/PanelController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -26,6 +26,7 @@ #include "UScreen.h" #include "PanelView.h" +#include "PanelStyle.h" namespace unity { @@ -46,8 +47,8 @@ void FirstMenuShow(); void QueueRedraw(); - unsigned int GetTrayXid(); - std::list GetGeometries(); + std::vector GetTrayXids() const; + std::vector GetGeometries() const; // NOTE: nux::Property maybe? void SetOpacity(float opacity); @@ -60,7 +61,7 @@ void OnScreenChanged(int primary_monitor, std::vector& monitors, Introspectable *iobj); private: - unity::PanelView* ViewForWindow(nux::BaseWindow* window); + unity::PanelView* ViewForWindow(nux::BaseWindow* window) const; static void WindowConfigureCallback(int window_width, int window_height, @@ -98,17 +99,21 @@ } } -unsigned int Controller::Impl::GetTrayXid() +std::vector Controller::Impl::GetTrayXids() const { - if (!windows_.empty()) - return ViewForWindow(windows_.front())->GetTrayXid(); - else - return 0; + std::vector xids; + + for (auto window: windows_) + { + xids.push_back(ViewForWindow(window)->GetTrayXid()); + } + + return xids; } -std::list Controller::Impl::GetGeometries() +std::vector Controller::Impl::GetGeometries() const { - std::list geometries; + std::vector geometries; for (auto window : windows_) { @@ -171,7 +176,7 @@ } } -PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window) +PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window) const { nux::Layout* layout = window->GetLayout(); std::list::iterator it = layout->GetChildren().begin(); @@ -198,8 +203,9 @@ (*it)->InputWindowEnableStruts(false); nux::Geometry geo = monitors[i]; - geo.height = 24; + geo.height = panel::Style::Instance().panel_height; (*it)->SetGeometry(geo); + (*it)->SetMinMaxSize(geo.width, geo.height); view = ViewForWindow(*it); view->SetPrimary(i == primary_monitor); @@ -224,7 +230,7 @@ nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); PanelView* view = new PanelView(); - view->SetMaximumHeight(24); + view->SetMaximumHeight(panel::Style::Instance().panel_height); view->SetOpacity(opacity_); view->SetOpacityMaximizedToggle(opacity_maximized_toggle_); view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_, @@ -238,17 +244,18 @@ layout->SetHorizontalExternalMargin(0); nux::BaseWindow* window = new nux::BaseWindow(""); + nux::Geometry geo = monitors[i]; + geo.height = panel::Style::Instance().panel_height; + window->SinkReference(); window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window); - window->SetLayout(layout); window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); window->ShowWindow(true); window->EnableInputWindow(true, "panel", false, false); window->InputWindowEnableStruts(true); - - nux::Geometry geo = monitors[i]; - geo.height = 24; window->SetGeometry(geo); + window->SetMinMaxSize(geo.width, geo.height); + window->SetLayout(layout); windows_.push_back(window); @@ -325,12 +332,12 @@ pimpl->QueueRedraw(); } -unsigned int Controller::GetTrayXid() +std::vector Controller::GetTrayXids() const { - return pimpl->GetTrayXid(); + return pimpl->GetTrayXids(); } -std::list Controller::GetGeometries() +std::vector Controller::GetGeometries() const { return pimpl->GetGeometries(); } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelController.h unity-5.10.0/plugins/unityshell/src/PanelController.h --- unity-5.8.0/plugins/unityshell/src/PanelController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelController.h 2012-04-12 13:21:21.000000000 +0000 @@ -20,9 +20,7 @@ #ifndef _PANEL_CONTROLLER_H_ #define _PANEL_CONTROLLER_H_ -#include #include - #include #include "Introspectable.h" @@ -42,8 +40,8 @@ void FirstMenuShow(); void QueueRedraw(); - unsigned int GetTrayXid (); - std::list GetGeometries (); + std::vector GetTrayXids() const; + std::vector GetGeometries() const; // NOTE: nux::Property maybe? void SetOpacity(float opacity); diff -Nru unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp unity-5.10.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp --- unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-04-12 13:21:21.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 @@ -15,6 +15,7 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include @@ -24,22 +25,18 @@ #include #include #include - -#include +#include #include -#include #include #include #include +#include #include "CairoTexture.h" -// TODO: this include should be at the top, but it fails :( #include "PanelIndicatorEntryView.h" - #include "PanelStyle.h" -#include -#include +#include "WindowManager.h" namespace unity @@ -47,52 +44,45 @@ namespace { -void draw_menu_bg(cairo_t* cr, int width, int height); -GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing); -const int PANEL_HEIGHT = 24; -const int SPACING = 3; +const int DEFAULT_SPACING = 3; } +using namespace indicator; -PanelIndicatorEntryView::PanelIndicatorEntryView( - indicator::Entry::Ptr const& proxy, - int padding, - IndicatorEntryType type) +PanelIndicatorEntryView::PanelIndicatorEntryView(Entry::Ptr const& proxy, int padding, + IndicatorEntryType type) : TextureArea(NUX_TRACKER_LOCATION) , proxy_(proxy) + , spacing_(DEFAULT_SPACING) + , left_padding_(padding < 0 ? 0 : padding) + , right_padding_(left_padding_) , type_(type) - , util_cg_(CAIRO_FORMAT_ARGB32, 1, 1) - , texture_layer_(NULL) - , padding_(padding < 0 ? 0 : padding) + , entry_texture_(nullptr) , opacity_(1.0f) , draw_active_(false) - , dash_showing_(false) + , overlay_showing_(false) , disabled_(false) + , focused_(true) { - on_indicator_activate_changed_connection_ = proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged)); - on_indicator_updated_connection_ = proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); - - on_font_changed_connection_ = g_signal_connect(gtk_settings_get_default(), "notify::gtk-font-name", (GCallback) &PanelIndicatorEntryView::OnFontChanged, this); + proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged)); + proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown)); InputArea::mouse_up.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseUp)); InputArea::SetAcceptMouseWheelEvent(true); + if (type_ != MENU) InputArea::mouse_wheel.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseWheel)); - on_panelstyle_changed_connection_ = panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); + panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); + Refresh(); } PanelIndicatorEntryView::~PanelIndicatorEntryView() { - on_indicator_activate_changed_connection_.disconnect(); - on_indicator_updated_connection_.disconnect(); - on_panelstyle_changed_connection_.disconnect(); - g_signal_handler_disconnect(gtk_settings_get_default(), on_font_changed_connection_); - if (texture_layer_) - delete texture_layer_; + // Nothing to do... } void PanelIndicatorEntryView::OnActiveChanged(bool is_active) @@ -108,10 +98,15 @@ void PanelIndicatorEntryView::ShowMenu(int button) { - proxy_->ShowMenu(GetAbsoluteX(), - GetAbsoluteY() + PANEL_HEIGHT, - button, - time(NULL)); + auto wm = WindowManager::Default(); + + if (!wm->IsExpoActive() && !wm->IsScaleActive()) + { + proxy_->ShowMenu(GetAbsoluteX(), + GetAbsoluteY() + panel::Style::Instance().panel_height, + button, + time(nullptr)); + } } void PanelIndicatorEntryView::OnMouseDown(int x, int y, long button_flags, long key_flags) @@ -119,8 +114,8 @@ if (proxy_->active() || IsDisabled()) return; - if (((proxy_->label_visible() && proxy_->label_sensitive()) || - (proxy_->image_visible() && proxy_->image_sensitive()))) + if (((IsLabelVisible() && IsLabelSensitive()) || + (IsIconVisible() && IsIconSensitive()))) { int button = nux::GetEventButton(button_flags); @@ -144,12 +139,12 @@ int px = geo.x + x; int py = geo.y + y; - if (((proxy_->label_visible() && proxy_->label_sensitive()) || - (proxy_->image_visible() && proxy_->image_sensitive())) && - button == 2 && type_ == INDICATOR) + if (((IsLabelVisible() && IsLabelSensitive()) || + (IsIconVisible() && IsIconSensitive())) && + button == 2 && type_ == INDICATOR) { if (geo.IsPointInside(px, py)) - proxy_->SecondaryActivate(time(NULL)); + proxy_->SecondaryActivate(time(nullptr)); SetOpacity(1.0f); } @@ -187,128 +182,83 @@ } } -// We need to do a couple of things here: -// 1. Figure out our width -// 2. Figure out if we're active -// 3. Paint something -void PanelIndicatorEntryView::Refresh() +glib::Object PanelIndicatorEntryView::MakePixbuf() { - if (!IsVisible()) + glib::Object pixbuf; + GtkIconTheme* theme = gtk_icon_theme_get_default(); + int image_type = proxy_->image_type(); + + if (image_type == GTK_IMAGE_PIXBUF) { - SetVisible(false); - return; - } + gsize len = 0; + guchar* decoded = g_base64_decode(proxy_->image_data().c_str(), &len); - SetVisible(true); + glib::Object stream(g_memory_input_stream_new_from_data(decoded, + len, + nullptr)); - PangoLayout* layout = NULL; - PangoFontDescription* desc = NULL; - PangoAttrList* attrs = NULL; - GtkSettings* settings = gtk_settings_get_default(); - cairo_t* cr; - char* font_description = NULL; - GdkScreen* screen = gdk_screen_get_default(); - int dpi = 0; - - std::string label = proxy_->label(); - glib::Object pixbuf(make_pixbuf(proxy_->image_type(), - proxy_->image_data(), - dash_showing_)); - - - int x = 0; - int width = 0; - int height = PANEL_HEIGHT; - int icon_width = 0; - int text_width = 0; - int text_height = 0; - - if (proxy_->show_now()) - { - if (!pango_parse_markup(label.c_str(), - -1, - '_', - &attrs, - NULL, - NULL, - NULL)) - { - g_debug("pango_parse_markup failed"); - } - } - boost::erase_all(label, "_"); + pixbuf = gdk_pixbuf_new_from_stream(stream, nullptr, nullptr); - // First lets figure out our size - if (pixbuf && proxy_->image_visible()) + g_free(decoded); + g_input_stream_close(stream, nullptr, nullptr); + } + else if (image_type == GTK_IMAGE_STOCK || + image_type == GTK_IMAGE_ICON_NAME) { - width = gdk_pixbuf_get_width(pixbuf); - icon_width = width; + pixbuf = gtk_icon_theme_load_icon(theme, proxy_->image_data().c_str(), 22, + (GtkIconLookupFlags)0, nullptr); } - - if (!label.empty() && proxy_->label_visible()) + else if (image_type == GTK_IMAGE_GICON) { - PangoContext* cxt; - PangoRectangle log_rect; + glib::Object icon(g_icon_new_for_string(proxy_->image_data().c_str(), nullptr)); - cr = util_cg_.GetContext(); - - g_object_get(settings, - "gtk-font-name", &font_description, - "gtk-xft-dpi", &dpi, - NULL); - desc = pango_font_description_from_string(font_description); - pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); - - layout = pango_cairo_create_layout(cr); - if (attrs) + GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22, + (GtkIconLookupFlags)0); + if (info) { - pango_layout_set_attributes(layout, attrs); - pango_attr_list_unref(attrs); + pixbuf = gtk_icon_info_load_icon(info, nullptr); + gtk_icon_info_free(info); } + } - pango_layout_set_font_description(layout, desc); - pango_layout_set_text(layout, label.c_str(), -1); - - cxt = pango_layout_get_context(layout); - pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen)); - pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE); - pango_layout_context_changed(layout); + return pixbuf; +} - pango_layout_get_extents(layout, NULL, &log_rect); - text_width = log_rect.width / PANGO_SCALE; - text_height = log_rect.height / PANGO_SCALE; +void PanelIndicatorEntryView::DrawEntryPrelight(cairo_t* cr, unsigned int width, unsigned int height) +{ + GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext(); - if (icon_width) - width += SPACING; - width += text_width; + gtk_style_context_save(style_context); - pango_font_description_free(desc); - g_free(font_description); - cairo_destroy(cr); - } + GtkWidgetPath* widget_path = gtk_widget_path_new(); + gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR); + gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM); + gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget"); - if (width) - width += padding_ * 2; + gtk_style_context_set_path(style_context, widget_path); + gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); + gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); + gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT); - SetMinimumWidth(width); + gtk_render_background(style_context, cr, 0, 0, width, height); + gtk_render_frame(style_context, cr, 0, 0, width, height); - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); - cr = cairo_graphics.GetContext(); - cairo_set_line_width(cr, 1); + gtk_widget_path_free(widget_path); - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - cairo_paint(cr); + gtk_style_context_restore(style_context); +} - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); +void PanelIndicatorEntryView::DrawEntryContent(cairo_t *cr, unsigned int width, unsigned int height, glib::Object const& pixbuf, glib::Object const& layout) +{ + int x = left_padding_; if (IsActive()) - draw_menu_bg(cr, width, height); + DrawEntryPrelight(cr, width, height); - x = padding_; - - if (pixbuf && proxy_->image_visible()) + if (pixbuf && IsIconVisible()) { GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext(); + unsigned int icon_width = gdk_pixbuf_get_width(pixbuf); gtk_style_context_save(style_context); @@ -321,14 +271,20 @@ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); - if (IsActive()) + if (!IsFocused()) + { + gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP); + } + else if (IsActive()) + { gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT); + } int y = (int)((height - gdk_pixbuf_get_height(pixbuf)) / 2); - if (dash_showing_ && !IsActive()) + if (overlay_showing_ && !IsActive()) { /* Most of the images we get are straight pixbufs (annoyingly), so when - * the Dash opens, we use the pixbuf as a mask to punch out an icon from + * the Overlay opens, we use the pixbuf as a mask to punch out an icon from * a white square. It works surprisingly well for most symbolic-type * icon themes/icons. */ @@ -336,7 +292,7 @@ cairo_push_group(cr); gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); - cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5); + cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5); cairo_pattern_t* pat = cairo_pop_group(cr); @@ -352,18 +308,23 @@ cairo_push_group(cr); gtk_render_icon(style_context, cr, pixbuf, x, y); cairo_pop_group_to_source(cr); - cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5); + cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5); } gtk_widget_path_free(widget_path); gtk_style_context_restore(style_context); - x += icon_width + SPACING; + x += icon_width + spacing_; } - if (!label.empty() && proxy_->label_visible()) + if (layout) { + PangoRectangle log_rect; + pango_layout_get_extents(layout, nullptr, &log_rect); + unsigned int text_height = log_rect.height / PANGO_SCALE; + unsigned int text_width = log_rect.width / PANGO_SCALE; + pango_cairo_update_layout(cr, layout); GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext(); @@ -379,86 +340,224 @@ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); - if (IsActive()) + if (!IsFocused()) + { + gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP); + } + else if (IsActive()) + { gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT); + } + + int y = (height - text_height) / 2; + + + unsigned int text_space = GetMaximumWidth() - x - right_padding_; - int y = (int)((height - text_height) / 2); - if (dash_showing_) + if (text_width > text_space) { - cairo_move_to(cr, x, y); - cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f); - pango_cairo_show_layout(cr, layout); + cairo_pattern_t* linpat; + int out_pixels = text_width - text_space; + const int fading_pixels = 15; + + int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels; + + cairo_push_group(cr); + if (overlay_showing_) + { + cairo_move_to(cr, x, y); + cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f); + pango_cairo_show_layout(cr, layout); + } + else + { + gtk_render_layout(style_context, cr, x, y, layout); + } + cairo_pop_group_to_source(cr); + + int right_margin = width - right_padding_; + linpat = cairo_pattern_create_linear(right_margin - fading_width, y, right_margin, y); + cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1); + cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0); + cairo_mask(cr, linpat); + cairo_pattern_destroy(linpat); } else { - gtk_render_layout(style_context, cr, x, y, layout); + if (overlay_showing_) + { + cairo_move_to(cr, x, y); + cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f); + pango_cairo_show_layout(cr, layout); + } + else + { + gtk_render_layout(style_context, cr, x, y, layout); + } } gtk_widget_path_free(widget_path); - gtk_style_context_restore(style_context); } +} - cairo_destroy(cr); - if (layout) - g_object_unref(layout); +// We need to do a couple of things here: +// 1. Figure out our width +// 2. Figure out if we're active +// 3. Paint something +void PanelIndicatorEntryView::Refresh() +{ + if (!proxy_->visible()) + { + SetVisible(false); + // This will destroy the object texture. No need to manually delete the pointer + entry_texture_ = nullptr; + SetColor(nux::color::Transparent); + + QueueDraw(); + refreshed.emit(this); + + return; + } + + glib::Object layout; + cairo_t* cr; + + std::string label = GetLabel(); + glib::Object const& pixbuf = MakePixbuf(); + + unsigned int width = 0; + unsigned int icon_width = 0; + unsigned int height = panel::Style::Instance().panel_height; + unsigned int text_width = 0; + + // First lets figure out our size + if (pixbuf && IsIconVisible()) + { + width = gdk_pixbuf_get_width(pixbuf); + icon_width = width; + } - nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics); + if (!label.empty() && IsLabelVisible()) + { + using namespace panel; + PangoContext* cxt; + PangoAttrList* attrs = nullptr; + PangoRectangle log_rect; + GdkScreen* screen = gdk_screen_get_default(); + PangoFontDescription* desc = nullptr; + PanelItem panel_item = (type_ == MENU) ? PanelItem::MENU : PanelItem::INDICATOR; + + Style& panel_style = Style::Instance(); + std::string const& font_description = panel_style.GetFontDescription(panel_item); + int dpi = panel_style.GetTextDPI(); - nux::TexCoordXForm texxform; - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + if (proxy_->show_now()) + { + if (!pango_parse_markup(label.c_str(), -1, '_', &attrs, nullptr, nullptr, nullptr)) + { + g_debug("pango_parse_markup failed"); + } + } - nux::ROPConfig rop; - rop.Blend = true; - rop.SrcBlend = GL_ONE; - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + desc = pango_font_description_from_string(font_description.c_str()); + pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); - if (texture_layer_) - delete texture_layer_; + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 1, 1); + cr = cairo_graphics.GetContext(); - texture_layer_ = new nux::TextureLayer(texture2D->GetDeviceTexture(), texxform, - nux::color::White, true, rop); - SetPaintLayer(texture_layer_); + layout = pango_cairo_create_layout(cr); + if (attrs) + { + pango_layout_set_attributes(layout, attrs); + pango_attr_list_unref(attrs); + } - texture2D->UnReference(); + pango_layout_set_font_description(layout, desc); - NeedRedraw(); + boost::erase_all(label, "_"); + pango_layout_set_text(layout, label.c_str(), -1); + cxt = pango_layout_get_context(layout); + pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen)); + pango_cairo_context_set_resolution(cxt, dpi / static_cast(PANGO_SCALE)); + pango_layout_context_changed(layout); + + pango_layout_get_extents(layout, nullptr, &log_rect); + text_width = log_rect.width / PANGO_SCALE; + + if (icon_width) + width += spacing_; + width += text_width; + + pango_font_description_free(desc); + cairo_destroy(cr); + } + + if (width) + width += left_padding_ + right_padding_; + + width = std::min(width, GetMaximumWidth()); + SetMinimumWidth(width); + + nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height); + cr = cg.GetContext(); + cairo_set_line_width(cr, 1); + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cr); + + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + DrawEntryContent(cr, width, height, pixbuf, layout); + + entry_texture_ = texture_ptr_from_cairo_graphics(cg); + SetTexture(entry_texture_.GetPointer()); + cairo_destroy(cr); + + SetVisible(true); refreshed.emit(this); + QueueDraw(); } void PanelIndicatorEntryView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { - if (opacity_ == 1.0f) + nux::Geometry const& geo = GetGeometry(); + GfxContext.PushClippingRectangle(geo); + + if (cached_geo_ != geo) { - TextureArea::Draw(GfxContext, force_draw); - return; + Refresh(); + cached_geo_ = geo; } - auto geo = GetGeometry(); - GfxContext.PushClippingRectangle(geo); - - if (texture_layer_) + if (entry_texture_ && opacity_ > 0.0f) { + /* "Clear" out the background */ + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + nux::ColorLayer layer(nux::color::Transparent, true, rop); + nux::GetPainter().PushDrawLayer(GfxContext, geo, &layer); + nux::TexCoordXForm texxform; GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height, - texture_layer_->GetDeviceTexture(), texxform, + entry_texture_->GetDeviceTexture(), texxform, nux::color::White * opacity_); } GfxContext.PopClippingRectangle(); } -void PanelIndicatorEntryView::DashShown() +void PanelIndicatorEntryView::OverlayShown() { - dash_showing_ = true; + overlay_showing_ = true; Refresh(); } -void PanelIndicatorEntryView::DashHidden() +void PanelIndicatorEntryView::OverlayHidden() { - dash_showing_ = false; + overlay_showing_ = false; Refresh(); } @@ -469,7 +568,8 @@ if (opacity_ != opacity) { opacity_ = opacity; - NeedRedraw(); + SetInputEventSensitivity(opacity_ != 0.0f); + QueueDraw(); } } @@ -478,167 +578,181 @@ return opacity_; } -std::string PanelIndicatorEntryView::GetName() const +PanelIndicatorEntryView::IndicatorEntryType PanelIndicatorEntryView::GetType() const { - return proxy_->id(); + return type_; } -void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder) +std::string PanelIndicatorEntryView::GetLabel() const { - variant::BuilderWrapper(builder) - .add(GetGeometry()) - .add("label", proxy_->label()) - .add("label_sensitive", proxy_->label_sensitive()) - .add("label_visible", proxy_->label_visible()) - .add("icon_sensitive", proxy_->image_sensitive()) - .add("icon_visible", proxy_->image_visible()) - .add("active", proxy_->active()) - .add("priority", proxy_->priority()); + if (proxy_.get()) + { + return proxy_->label(); + } + + return ""; } -bool PanelIndicatorEntryView::GetShowNow() +bool PanelIndicatorEntryView::IsLabelVisible() const { - return proxy_.get() ? proxy_->show_now() : false; + if (proxy_.get()) + { + return proxy_->label_visible(); + } + + return false; } -void PanelIndicatorEntryView::GetGeometryForSync(indicator::EntryLocationMap& locations) +bool PanelIndicatorEntryView::IsLabelSensitive() const { - if (!IsVisible()) - return; + if (proxy_.get()) + { + return proxy_->label_sensitive(); + } - locations[proxy_->id()] = GetAbsoluteGeometry(); + return false; } -bool PanelIndicatorEntryView::IsEntryValid() const +bool PanelIndicatorEntryView::IsIconVisible() const { if (proxy_.get()) { - return proxy_->image_visible() || proxy_->label_visible(); + return proxy_->image_visible(); } + return false; } -bool PanelIndicatorEntryView::IsSensitive() const +bool PanelIndicatorEntryView::IsIconSensitive() const { if (proxy_.get()) { - return proxy_->image_sensitive() || proxy_->label_sensitive(); + return proxy_->image_sensitive(); } + return false; } -bool PanelIndicatorEntryView::IsActive() const +std::string PanelIndicatorEntryView::GetName() const { - return draw_active_; + return "IndicatorEntry"; } -int PanelIndicatorEntryView::GetEntryPriority() const +void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder) { - if (proxy_.get()) + std::string type_name; + + switch (GetType()) { - return proxy_->priority(); + case INDICATOR: + type_name = "indicator"; + break; + case MENU: + type_name = "menu"; + break; + default: + type_name = "other"; } - return -1; + + variant::BuilderWrapper(builder) + .add(GetAbsoluteGeometry()) + .add("entry_id", GetEntryID()) + .add("name_hint", proxy_->name_hint()) + .add("type", type_name) + .add("priority", proxy_->priority()) + .add("label", GetLabel()) + .add("label_sensitive", IsLabelSensitive()) + .add("label_visible", IsLabelVisible()) + .add("icon_sensitive", IsIconSensitive()) + .add("icon_visible", IsIconVisible()) + .add("visible", IsVisible() && GetOpacity() != 0.0f) + .add("opacity", GetOpacity()) + .add("active", proxy_->active()) + .add("menu_x", proxy_->geometry().x) + .add("menu_y", proxy_->geometry().y) + .add("menu_width", proxy_->geometry().width) + .add("menu_height", proxy_->geometry().height) + .add("focused", IsFocused()); } -void PanelIndicatorEntryView::SetDisabled(bool disabled) +bool PanelIndicatorEntryView::GetShowNow() const { - disabled_ = disabled; + return proxy_.get() ? proxy_->show_now() : false; } -bool PanelIndicatorEntryView::IsDisabled() +void PanelIndicatorEntryView::GetGeometryForSync(EntryLocationMap& locations) { - return (disabled_ || !proxy_.get() || !IsSensitive()); + if (!IsVisible()) + return; + + locations[GetEntryID()] = GetAbsoluteGeometry(); } -bool PanelIndicatorEntryView::IsVisible() +bool PanelIndicatorEntryView::IsSensitive() const { if (proxy_.get()) { - return proxy_->visible(); + return IsIconSensitive() || IsLabelSensitive(); } return false; } -void PanelIndicatorEntryView::OnFontChanged(GObject* gobject, GParamSpec* pspec, - gpointer data) +bool PanelIndicatorEntryView::IsVisible() { - PanelIndicatorEntryView* self = reinterpret_cast(data); - self->Refresh(); + if (proxy_.get()) + { + return TextureArea::IsVisible() && proxy_->visible(); + } + + return TextureArea::IsVisible(); } -namespace +bool PanelIndicatorEntryView::IsActive() const { + return draw_active_; +} -void draw_menu_bg(cairo_t* cr, int width, int height) +std::string PanelIndicatorEntryView::GetEntryID() const { - GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext(); - - gtk_style_context_save(style_context); - - GtkWidgetPath* widget_path = gtk_widget_path_new(); - gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget"); - gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR); - gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM); - - gtk_style_context_set_path(style_context, widget_path); - gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); - gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); - gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT); - - gtk_render_background(style_context, cr, 0, 0, width, height); - gtk_render_frame(style_context, cr, 0, 0, width, height); - - gtk_widget_path_free(widget_path); + if (proxy_.get()) + { + return proxy_->id(); + } - gtk_style_context_restore(style_context); + return ""; } -GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing) +int PanelIndicatorEntryView::GetEntryPriority() const { - GdkPixbuf* ret = NULL; - GtkIconTheme* theme = gtk_icon_theme_get_default(); - - if (image_type == GTK_IMAGE_PIXBUF) + if (proxy_.get()) { - gsize len = 0; - guchar* decoded = g_base64_decode(image_data.c_str(), &len); + return proxy_->priority(); + } + return -1; +} - GInputStream* stream = g_memory_input_stream_new_from_data(decoded, - len, NULL); +void PanelIndicatorEntryView::SetDisabled(bool disabled) +{ + disabled_ = disabled; +} - ret = gdk_pixbuf_new_from_stream(stream, NULL, NULL); +bool PanelIndicatorEntryView::IsDisabled() +{ + return (disabled_ || !proxy_.get() || !IsSensitive()); +} - g_free(decoded); - g_input_stream_close(stream, NULL, NULL); - g_object_unref(stream); - } - else if (image_type == GTK_IMAGE_STOCK || - image_type == GTK_IMAGE_ICON_NAME) - { - ret = gtk_icon_theme_load_icon(theme, - image_data.c_str(), - 22, - (GtkIconLookupFlags)0, - NULL); - } - else if (image_type == GTK_IMAGE_GICON) +void PanelIndicatorEntryView::SetFocusedState(bool focused) +{ + if (focused_ != focused) { - glib::Object icon(g_icon_new_for_string(image_data.c_str(), NULL)); - - GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon( - theme, icon, 22, (GtkIconLookupFlags)0); - if (info) - { - ret = gtk_icon_info_load_icon(info, NULL); - gtk_icon_info_free(info); - } + focused_ = focused; + Refresh(); } - - return ret; } -} // anon namespace - +bool PanelIndicatorEntryView::IsFocused() const +{ + return focused_; +} } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.h unity-5.10.0/plugins/unityshell/src/PanelIndicatorEntryView.h --- unity-5.8.0/plugins/unityshell/src/PanelIndicatorEntryView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelIndicatorEntryView.h 2012-04-12 13:21:21.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 @@ -15,6 +15,7 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #ifndef PANEL_INDICATOR_OBJECT_ENTRY_VIEW_H @@ -26,78 +27,101 @@ #include #include +#include +#include + +#include #include "Introspectable.h" namespace unity { - -class PanelIndicatorEntryView : public nux::TextureArea, public unity::debug::Introspectable +class PanelIndicatorEntryView : public nux::TextureArea, public debug::Introspectable { public: - typedef enum { + enum IndicatorEntryType { INDICATOR, MENU, OTHER - } IndicatorEntryType; + }; PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5, IndicatorEntryType type = INDICATOR); - ~PanelIndicatorEntryView(); - void Refresh(); + virtual ~PanelIndicatorEntryView(); + + IndicatorEntryType GetType() const; + std::string GetEntryID() const; + int GetEntryPriority() const; + + virtual std::string GetLabel() const; + virtual bool IsLabelVisible() const; + virtual bool IsLabelSensitive() const; + + virtual bool IsIconVisible() const; + virtual bool IsIconSensitive() const; + + virtual void Activate(int button = 1); + virtual void Unactivate(); + + virtual void GetGeometryForSync(indicator::EntryLocationMap& locations); + + bool GetShowNow() const; + bool IsSensitive() const; + bool IsActive() const; + bool IsVisible(); - void Activate(int button = 1); - void Unactivate(); - bool GetShowNow(); void SetDisabled(bool disabled); bool IsDisabled(); + void SetOpacity(double alpha); double GetOpacity(); - void GetGeometryForSync(indicator::EntryLocationMap& locations); - bool IsEntryValid() const; - bool IsSensitive() const; - bool IsActive() const; - bool IsVisible(); - int GetEntryPriority() const; + void SetFocusedState(bool focused); + bool IsFocused() const; + + void OverlayShown(); + void OverlayHidden(); - void DashShown(); - void DashHidden(); + sigc::signal active_changed; + sigc::signal refreshed; +protected: std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void AddProperties(GVariantBuilder* builder); virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + virtual void DrawEntryPrelight(cairo_t* cr, unsigned int w, unsigned int h); + virtual void DrawEntryContent(cairo_t* cr, unsigned int width, unsigned int height, + glib::Object const& pixbuf, + glib::Object const& layout); - sigc::signal active_changed; - sigc::signal refreshed; + void Refresh(); + void SetActiveState(bool active, int button); + virtual void ShowMenu(int button = 1); -private: - unity::indicator::Entry::Ptr proxy_; - IndicatorEntryType type_; - nux::CairoGraphics util_cg_; - nux::TextureLayer* texture_layer_; - int padding_; - double opacity_; - bool draw_active_; - bool dash_showing_; - bool disabled_; - gulong on_font_changed_connection_; + indicator::Entry::Ptr proxy_; + unsigned int spacing_; + unsigned int left_padding_; + unsigned int right_padding_; - static void OnFontChanged(GObject* gobject, GParamSpec* pspec, gpointer data); +private: void OnMouseDown(int x, int y, long button_flags, long key_flags); void OnMouseUp(int x, int y, long button_flags, long key_flags); void OnMouseWheel(int x, int y, int delta, unsigned long mouse_state, unsigned long key_state); void OnActiveChanged(bool is_active); - void SetActiveState(bool active, int button); - void ShowMenu(int button); + glib::Object MakePixbuf(); - sigc::connection on_indicator_activate_changed_connection_; - sigc::connection on_indicator_updated_connection_; - sigc::connection on_panelstyle_changed_connection_; + IndicatorEntryType type_; + nux::ObjectPtr entry_texture_; + nux::Geometry cached_geo_; + double opacity_; + bool draw_active_; + bool overlay_showing_; + bool disabled_; + bool focused_; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.cpp unity-5.10.0/plugins/unityshell/src/PanelIndicatorsView.cpp --- unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelIndicatorsView.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as @@ -14,7 +14,7 @@ * 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) + * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com> * Neil Jagdish Patel */ @@ -36,6 +36,8 @@ namespace unity { +using namespace indicator; + NUX_IMPLEMENT_OBJECT_TYPE(PanelIndicatorsView); PanelIndicatorsView::PanelIndicatorsView() @@ -45,8 +47,9 @@ { LOG_DEBUG(logger) << "Indicators View Added: "; layout_ = new nux::HLayout("", NUX_TRACKER_LOCATION); + layout_->SetContentDistribution(nux::eStackRight); - SetCompositionLayout(layout_); + SetLayout(layout_); } PanelIndicatorsView::~PanelIndicatorsView() @@ -59,7 +62,7 @@ } void -PanelIndicatorsView::AddIndicator(indicator::Indicator::Ptr const& indicator) +PanelIndicatorsView::AddIndicator(Indicator::Ptr const& indicator) { LOG_DEBUG(logger) << "IndicatorAdded: " << indicator->name(); indicators_.push_back(indicator); @@ -76,7 +79,7 @@ } void -PanelIndicatorsView::RemoveIndicator(indicator::Indicator::Ptr const& indicator) +PanelIndicatorsView::RemoveIndicator(Indicator::Ptr const& indicator) { auto connections = indicators_connections_.find(indicator); @@ -88,7 +91,7 @@ } for (auto entry : indicator->GetEntries()) - OnEntryRemoved (entry->id()); + OnEntryRemoved(entry->id()); for (auto i = indicators_.begin(); i != indicators_.end(); i++) { @@ -102,6 +105,12 @@ LOG_DEBUG(logger) << "IndicatorRemoved: " << indicator->name(); } +PanelIndicatorsView::Indicators +PanelIndicatorsView::GetIndicators() +{ + return indicators_; +} + void PanelIndicatorsView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { @@ -121,16 +130,45 @@ entry.second->QueueDraw(); } +void +PanelIndicatorsView::SetMaximumEntriesWidth(int max_width) +{ + unsigned int n_entries = 0; + + for (auto entry : entries_) + if (entry.second->IsVisible()) + n_entries++; + + if (n_entries > 0) + { + for (auto entry : entries_) + { + if (entry.second->IsVisible() && n_entries > 0) + { + int max_entry_width = max_width / n_entries; + + if (entry.second->GetBaseWidth() > max_entry_width) + entry.second->SetMaximumWidth(max_entry_width); + + max_width -= entry.second->GetBaseWidth(); + --n_entries; + } + } + } +} + PanelIndicatorEntryView* -PanelIndicatorsView::ActivateEntry(std::string const& entry_id) +PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button) { auto entry = entries_.find(entry_id); - if (entry != entries_.end() && entry->second->IsEntryValid()) + if (entry != entries_.end()) { PanelIndicatorEntryView* view = entry->second; - LOG_DEBUG(logger) << "Activating: " << entry_id; - view->Activate(); + + if (view->IsSensitive() && view->IsVisible()) + view->Activate(button); + return view; } @@ -148,24 +186,27 @@ for (auto entry : sorted_entries) { PanelIndicatorEntryView* view = entry.second; - if (view->IsSensitive()) + + if (view->IsSensitive() && view->IsVisible() && view->IsFocused()) { - view->Activate(); + /* Use the 0 button, it means it's a keyboard activation */ + view->Activate(0); return true; } } + return false; } void -PanelIndicatorsView::GetGeometryForSync(indicator::EntryLocationMap& locations) +PanelIndicatorsView::GetGeometryForSync(EntryLocationMap& locations) { for (auto entry : entries_) entry.second->GetGeometryForSync(locations); } PanelIndicatorEntryView* -PanelIndicatorsView::ActivateEntryAt(int x, int y) +PanelIndicatorsView::ActivateEntryAt(int x, int y, int button) { PanelIndicatorEntryView* target = nullptr; bool found_old_active = false; @@ -180,9 +221,10 @@ { PanelIndicatorEntryView* view = entry.second; - if (!target && view->IsVisible() && view->GetAbsoluteGeometry().IsPointInside(x, y)) + if (!target && view->IsVisible() && view->IsFocused() && + view->GetAbsoluteGeometry().IsPointInside(x, y)) { - view->Activate(0); + view->Activate(button); target = view; break; } @@ -219,11 +261,13 @@ GfxContext.PopClippingRectangle(); } -PanelIndicatorEntryView * -PanelIndicatorsView::AddEntry(indicator::Entry::Ptr const& entry, int padding, - IndicatorEntryPosition pos, IndicatorEntryType type) +void +PanelIndicatorsView::AddEntryView(PanelIndicatorEntryView* view, + IndicatorEntryPosition pos) { - auto view = new PanelIndicatorEntryView(entry, padding, type); + if (!view) + return; + int entry_pos = pos; view->SetOpacity(opacity_); @@ -233,7 +277,7 @@ { entry_pos = nux::NUX_LAYOUT_BEGIN; - if (entry->priority() > -1) + if (view->GetEntryPriority() > -1) { for (auto area : layout_->GetChildren()) { @@ -241,7 +285,7 @@ if (en) { - if (en && entry->priority() <= en->GetEntryPriority()) + if (en && view->GetEntryPriority() <= en->GetEntryPriority()) break; entry_pos++; @@ -251,20 +295,28 @@ } layout_->AddView(view, 0, nux::eCenter, nux::eFull, 1.0, (nux::LayoutPosition) entry_pos); - layout_->SetContentDistribution(nux::eStackRight); - entries_[entry->id()] = view; + + entries_[view->GetEntryID()] = view; AddChild(view); QueueRelayout(); QueueDraw(); on_indicator_updated.emit(view); +} + +PanelIndicatorEntryView * +PanelIndicatorsView::AddEntry(Entry::Ptr const& entry, int padding, + IndicatorEntryPosition pos, IndicatorEntryType type) +{ + auto view = new PanelIndicatorEntryView(entry, padding, type); + AddEntryView(view, pos); return view; } void -PanelIndicatorsView::OnEntryAdded(indicator::Entry::Ptr const& entry) +PanelIndicatorsView::OnEntryAdded(Entry::Ptr const& entry) { AddEntry(entry); } @@ -279,19 +331,25 @@ } void -PanelIndicatorsView::RemoveEntry(std::string const& entry_id) +PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view) { - PanelIndicatorEntryView* view = entries_[entry_id]; + if (!view) + return; - if (view) - { - layout_->RemoveChildObject(view); - entries_.erase(entry_id); - on_indicator_updated.emit(view); + std::string const& entry_id = view->GetEntryID(); + RemoveChild(view); + on_indicator_updated.emit(view); + entries_.erase(entry_id); + layout_->RemoveChildObject(view); - QueueRelayout(); - QueueDraw(); - } + QueueRelayout(); + QueueDraw(); +} + +void +PanelIndicatorsView::RemoveEntry(std::string const& entry_id) +{ + RemoveEntryView(entries_[entry_id]); } void @@ -301,17 +359,17 @@ } void -PanelIndicatorsView::DashShown() +PanelIndicatorsView::OverlayShown() { for (auto entry: entries_) - entry.second->DashShown(); + entry.second->OverlayShown(); } void -PanelIndicatorsView::DashHidden() +PanelIndicatorsView::OverlayHidden() { for (auto entry: entries_) - entry.second->DashHidden(); + entry.second->OverlayHidden(); } double @@ -337,13 +395,16 @@ std::string PanelIndicatorsView::GetName() const { - return "IndicatorsView"; + return "Indicators"; } void PanelIndicatorsView::AddProperties(GVariantBuilder* builder) { - variant::BuilderWrapper(builder).add(GetGeometry()); + variant::BuilderWrapper(builder) + .add(GetAbsoluteGeometry()) + .add("entries", entries_.size()) + .add("opacity", opacity_); } } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.h unity-5.10.0/plugins/unityshell/src/PanelIndicatorsView.h --- unity-5.8.0/plugins/unityshell/src/PanelIndicatorsView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelIndicatorsView.h 2012-04-12 13:21:21.000000000 +0000 @@ -42,11 +42,11 @@ void AddIndicator(indicator::Indicator::Ptr const& indicator); void RemoveIndicator(indicator::Indicator::Ptr const& indicator); - typedef enum { + enum IndicatorEntryPosition { AUTO = -1, START = nux::NUX_LAYOUT_BEGIN, END = nux::NUX_LAYOUT_END, - } IndicatorEntryPosition; + }; typedef PanelIndicatorEntryView::IndicatorEntryType IndicatorEntryType; @@ -56,37 +56,46 @@ IndicatorEntryType type = IndicatorEntryType::INDICATOR); void RemoveEntry(std::string const& entry_id); - PanelIndicatorEntryView* ActivateEntryAt(int x, int y); - PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id); + PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1); + PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1); bool ActivateIfSensitive(); + + virtual void OverlayShown(); + virtual void OverlayHidden(); + + void SetOpacity(double opacity); + double GetOpacity(); + + void SetMaximumEntriesWidth(int max_width); void GetGeometryForSync(indicator::EntryLocationMap& locations); + virtual void QueueDraw(); + + sigc::signal on_indicator_updated; + +protected: + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + + typedef std::vector Indicators; + Indicators GetIndicators(); + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); - virtual void QueueDraw(); virtual void OnEntryAdded(indicator::Entry::Ptr const& entry); virtual void OnEntryRefreshed(PanelIndicatorEntryView* view); virtual void OnEntryRemoved(std::string const& entry_id); - void DashShown(); - void DashHidden(); - - void SetOpacity(double opacity); - double GetOpacity(); - - sigc::signal on_indicator_updated; + virtual void AddEntryView(PanelIndicatorEntryView* view, + IndicatorEntryPosition pos = AUTO); + virtual void RemoveEntryView(PanelIndicatorEntryView* view); -protected: nux::HLayout* layout_; typedef std::map Entries; Entries entries_; - std::string GetName() const; - void AddProperties(GVariantBuilder* builder); - private: - typedef std::vector Indicators; Indicators indicators_; double opacity_; diff -Nru unity-5.8.0/plugins/unityshell/src/PanelMenuView.cpp unity-5.10.0/plugins/unityshell/src/PanelMenuView.cpp --- unity-5.8.0/plugins/unityshell/src/PanelMenuView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelMenuView.cpp 2012-04-12 13:21:21.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 @@ -15,61 +15,50 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel - * Marco Trevisan + * Marco Trevisan <3v1n0@ubuntu.com> */ -#include -#include -#include #include -#include -#include -#include - -#include -#include -#include +#include #include "CairoTexture.h" #include "PanelMenuView.h" #include "PanelStyle.h" -#include - -#include -#include - -#include -#include - #include "DashSettings.h" -#include "ubus-server.h" #include "UBusMessages.h" - #include "UScreen.h" +#include + +#include + namespace unity { namespace { - const std::string WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font"; + nux::logging::Logger logger("unity.panel.menu"); + const int MAIN_LEFT_PADDING = 4; + const int TITLE_PADDING = 2; + const int MENUBAR_PADDING = 4; + const int MENU_ENTRIES_PADDING = 6; + const int DEFAULT_MENUS_FADEIN = 100; + const int DEFAULT_MENUS_FADEOUT = 120; + const int DEFAULT_MENUS_DISCOVERY = 2; + const int DEFAULT_DISCOVERY_FADEIN = 200; + const int DEFAULT_DISCOVERY_FADEOUT = 300; } -PanelMenuView::PanelMenuView(int padding) +PanelMenuView::PanelMenuView() : _matcher(bamf_matcher_get_default()), - _title_layer(nullptr), - _util_cg(CAIRO_FORMAT_ARGB32, 1, 1), - _gradient_texture(nullptr), _is_inside(false), _is_grabbed(false), _is_maximized(false), - _is_own_window(false), _last_active_view(nullptr), _new_application(nullptr), - _last_width(0), - _last_height(0), - _places_showing(false), + _overlay_showing(false), _switcher_showing(false), + _launcher_keynav(false), _show_now_activated(false), _we_control_active(false), _new_app_menu_shown(false), @@ -79,26 +68,20 @@ _update_show_now_id(0), _new_app_show_id(0), _new_app_hide_id(0), - _menus_fadein(100), - _menus_fadeout(120), - _menus_discovery(2), - _menus_discovery_fadein(200), - _menus_discovery_fadeout(300), - _panel_title(nullptr), - _fade_in_animator(nullptr), - _fade_out_animator(nullptr) -{ - WindowManager* win_manager; - - // TODO: kill _menu_layout - should just use the _layout defined - // in the base class. - _menu_layout = new nux::HLayout("", NUX_TRACKER_LOCATION); - _menu_layout->SetParentObject(this); - - /* This is for our parent and for PanelView to read indicator entries, we - * shouldn't touch this again - */ - layout_ = _menu_layout; + _menus_fadein(DEFAULT_MENUS_FADEIN), + _menus_fadeout(DEFAULT_MENUS_FADEOUT), + _menus_discovery(DEFAULT_MENUS_DISCOVERY), + _menus_discovery_fadein(DEFAULT_DISCOVERY_FADEIN), + _menus_discovery_fadeout(DEFAULT_DISCOVERY_FADEOUT), + _fade_in_animator(_menus_fadein), + _fade_out_animator(_menus_fadeout), + _desktop_name(_("Ubuntu Desktop")) +{ + layout_->SetContentDistribution(nux::eStackLeft); + + BamfWindow* active_win = bamf_matcher_get_active_window(_matcher); + if (BAMF_IS_WINDOW(active_win)) + _active_xid = bamf_window_get_xid(active_win); _view_opened_signal.Connect(_matcher, "view-opened", sigc::mem_fun(this, &PanelMenuView::OnViewOpened)); @@ -109,35 +92,35 @@ _active_app_changed_signal.Connect(_matcher, "active-application-changed", sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged)); - _padding = padding; - _window_buttons = new WindowButtons(); + _window_buttons->SetMonitor(_monitor); + _window_buttons->SetControlledWindow(_active_xid); _window_buttons->SetParentObject(this); - _window_buttons->NeedRedraw(); + _window_buttons->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING); + _window_buttons->SetMaximumHeight(panel::Style::Instance().panel_height); + _window_buttons->ComputeContentSize(); - _window_buttons->close_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnCloseClicked)); - _window_buttons->minimize_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnMinimizeClicked)); - _window_buttons->restore_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnRestoreClicked)); _window_buttons->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); _window_buttons->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); //_window_buttons->mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove)); + AddChild(_window_buttons); - _panel_titlebar_grab_area = new PanelTitlebarGrabArea(); - _panel_titlebar_grab_area->SetParentObject(this); - _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)); - _panel_titlebar_grab_area->mouse_drag.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove)); - _panel_titlebar_grab_area->mouse_up.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd)); - _panel_titlebar_grab_area->mouse_double_click.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseDoubleClicked)); + layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0); + layout_->SetBaseHeight(panel::Style::Instance().panel_height); - win_manager = WindowManager::Default(); + _titlebar_grab_area = new PanelTitlebarGrabArea(); + _titlebar_grab_area->SetParentObject(this); + _titlebar_grab_area->activate_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedActivate)); + _titlebar_grab_area->restore_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedRestore)); + _titlebar_grab_area->lower_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedLower)); + _titlebar_grab_area->grab_started.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart)); + _titlebar_grab_area->grab_move.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove)); + _titlebar_grab_area->grab_end.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd)); + AddChild(_titlebar_grab_area); + WindowManager* win_manager = WindowManager::Default(); win_manager->window_minimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMinimized)); win_manager->window_unminimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnminimized)); - //win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate)); - //win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate)); - win_manager->window_maximized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMaximized)); win_manager->window_restored.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowRestored)); win_manager->window_unmapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnmapped)); @@ -146,39 +129,40 @@ win_manager->window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved)); win_manager->window_decorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowDecorated)); win_manager->window_undecorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUndecorated)); + win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate)); + win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate)); + win_manager->initiate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoInitiate)); + win_manager->terminate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate)); + win_manager->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate)); + + _style_changed_connection = panel::Style::Instance().changed.connect([&] { + _window_buttons->ComputeContentSize(); + layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0); - panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelMenuView::Refresh)); + Refresh(true); + FullRedraw(); + }); mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); //mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove)); - _panel_titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); - _panel_titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); + _titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); + _titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); + + _ubus_manager.RegisterInterest(UBUS_SWITCHER_SHOWN, sigc::mem_fun(this, &PanelMenuView::OnSwitcherShown)); + _ubus_manager.RegisterInterest(UBUS_SWITCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnSwitcherSelectionChanged)); - // Register for all the interesting events - UBusServer* ubus = ubus_server_get_default(); - _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN, - (UBusCallback)PanelMenuView::OnPlaceViewShown, - this)); - _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN, - (UBusCallback)PanelMenuView::OnPlaceViewHidden, - this)); - - _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SHOWN, - (UBusCallback)PanelMenuView::OnSwitcherShown, - this)); - _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SELECTION_CHANGED, - (UBusCallback)PanelMenuView::OnSwitcherSelectionChanged, - this)); - - _fade_in_animator = new Animator(_menus_fadein); - _fade_out_animator = new Animator(_menus_fadeout); - - _fade_in_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged)); - _fade_in_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw)); - _fade_out_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged)); - _fade_out_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw)); + _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted)); + _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded)); + _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted)); + _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded)); + _ubus_manager.RegisterInterest(UBUS_LAUNCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnLauncherSelectionChanged)); + + _fade_in_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged)); + _fade_in_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw)); + _fade_out_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged)); + _fade_out_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw)); SetOpacity(0.0f); _window_buttons->SetOpacity(0.0f); @@ -189,6 +173,15 @@ PanelMenuView::~PanelMenuView() { + // We need to disconnect these signals explicitly before we destroy the window buttons + // and titlebar grab area objects, otherwise there's a risk the signals will fire as the + // animator objects are destroyed (which happens after the destructor finishes). + _fade_in_animator.animation_updated.clear(); + _fade_in_animator.animation_ended.clear(); + _fade_out_animator.animation_updated.clear(); + _fade_out_animator.animation_ended.clear(); + _style_changed_connection.disconnect(); + if (_active_moved_id) g_source_remove(_active_moved_id); @@ -198,41 +191,46 @@ if (_new_app_hide_id) g_source_remove(_new_app_hide_id); - if (_title_layer) - delete _title_layer; - - if (_fade_in_animator) - delete _fade_in_animator; + _window_buttons->UnReference(); + _titlebar_grab_area->UnReference(); +} - if (_fade_out_animator) - delete _fade_out_animator; +void PanelMenuView::OverlayShown() +{ + _overlay_showing = true; + QueueDraw(); +} - _menu_layout->UnReference(); - _window_buttons->UnReference(); - _panel_titlebar_grab_area->UnReference(); +void PanelMenuView::OverlayHidden() +{ + _overlay_showing = false; + QueueDraw(); +} - UBusServer* ubus = ubus_server_get_default(); - for (auto interest : _ubus_interests) +void PanelMenuView::AddIndicator(indicator::Indicator::Ptr const& indicator) +{ + if (!GetIndicators().empty()) { - if (interest != 0) - ubus_server_unregister_interest(ubus, interest); + LOG_ERROR(logger) << "PanelMenuView has already an indicator!"; + return; } + + PanelIndicatorsView::AddIndicator(indicator); } -void -PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery, - int discovery_fadein, int discovery_fadeout) +void PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery, + int discovery_fadein, int discovery_fadeout) { if (fadein > -1) { _menus_fadein = fadein; - _fade_in_animator->SetDuration(_menus_fadein); + _fade_in_animator.SetDuration(_menus_fadein); } if (fadeout > -1) { _menus_fadeout = fadeout; - _fade_out_animator->SetDuration(_menus_fadeout); + _fade_out_animator.SetDuration(_menus_fadeout); } if (discovery > -1) @@ -245,16 +243,13 @@ _menus_discovery_fadeout = discovery_fadeout; } -void -PanelMenuView::FullRedraw() +void PanelMenuView::FullRedraw() { - _menu_layout->NeedRedraw(); - _window_buttons->NeedRedraw(); - NeedRedraw(); + QueueDraw(); + _window_buttons->QueueDraw(); } -nux::Area* -PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) +nux::Area* PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); @@ -262,77 +257,59 @@ return nullptr; Area* found_area = nullptr; + + if (_overlay_showing) + { + if (_window_buttons) + return _window_buttons->FindAreaUnderMouse(mouse_position, event_type); + } + if (!_we_control_active) { - found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type); - NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); + /* When the current panel is not active, it all behaves like a grab-area */ + if (GetAbsoluteGeometry().IsInside(mouse_position)) + return _titlebar_grab_area; } - if (_is_maximized || _places_showing) + if (_is_maximized) { if (_window_buttons) { found_area = _window_buttons->FindAreaUnderMouse(mouse_position, event_type); NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); } - - if (_panel_titlebar_grab_area) - { - found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type); - NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); - } - } - - if (_panel_titlebar_grab_area) - { - found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type); - NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); } - if (!_is_own_window) + if (_titlebar_grab_area && !_overlay_showing) { - found_area = _menu_layout->FindAreaUnderMouse(mouse_position, event_type); + found_area = _titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type); NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); } - return View::FindAreaUnderMouse(mouse_position, event_type); + return PanelIndicatorsView::FindAreaUnderMouse(mouse_position, event_type); } -long PanelMenuView::PostLayoutManagement(long LayoutResult) +void PanelMenuView::PreLayoutManagement() { - long res = View::PostLayoutManagement(LayoutResult); - int old_window_buttons_w, new_window_buttons_w; - int old_menu_area_w, new_menu_area_w; - - nux::Geometry geo = GetGeometry(); + PanelIndicatorsView::PreLayoutManagement(); + nux::Geometry const& geo = GetGeometry(); - old_window_buttons_w = _window_buttons->GetContentWidth(); - _window_buttons->SetGeometry(geo.x + _padding, geo.y, old_window_buttons_w, geo.height); _window_buttons->ComputeContentSize(); - new_window_buttons_w = _window_buttons->GetContentWidth(); + int buttons_diff = geo.height - _window_buttons->GetContentHeight(); + _window_buttons->SetBaseY(buttons_diff > 0 ? std::ceil(buttons_diff/2.0f) : 0); - /* Explicitly set the size and position of the widgets */ - geo.x += _padding + new_window_buttons_w + _padding; - geo.width -= _padding + new_window_buttons_w + _padding; + layout_->ComputeContentSize(); + int layout_width = layout_->GetContentWidth(); - old_menu_area_w = _menu_layout->GetContentWidth(); - _menu_layout->SetGeometry(geo.x, geo.y, old_menu_area_w, geo.height); - _menu_layout->ComputeContentSize(); - new_menu_area_w = _menu_layout->GetContentWidth(); + _titlebar_grab_area->SetBaseX(layout_width); + _titlebar_grab_area->SetBaseHeight(geo.height); + _titlebar_grab_area->SetMinimumWidth(geo.width - layout_width); + _titlebar_grab_area->SetMaximumWidth(geo.width - layout_width); - geo.x += new_menu_area_w; - geo.width -= new_menu_area_w; - - _panel_titlebar_grab_area->SetGeometry(geo.x, geo.y, geo.width, geo.height); - - if (_is_inside) - NeedRedraw(); - - return res; + SetMaximumEntriesWidth(geo.width - _window_buttons->GetContentWidth()); } -void -PanelMenuView::OnFadeInChanged(double opacity) +void PanelMenuView::OnFadeInChanged(double opacity) { if (DrawMenus() && GetOpacity() != 1.0f) SetOpacity(opacity); @@ -340,11 +317,10 @@ if (DrawWindowButtons() && _window_buttons->GetOpacity() != 1.0f) _window_buttons->SetOpacity(opacity); - NeedRedraw(); + QueueDraw(); } -void -PanelMenuView::OnFadeOutChanged(double progress) +void PanelMenuView::OnFadeOutChanged(double progress) { double opacity = CLAMP(1.0f - progress, 0.0f, 1.0f); @@ -354,13 +330,16 @@ if (!DrawWindowButtons() && _window_buttons->GetOpacity() != 0.0f) _window_buttons->SetOpacity(opacity); - NeedRedraw(); + QueueDraw(); } -bool -PanelMenuView::DrawMenus() +bool PanelMenuView::DrawMenus() const { - if (!_is_own_window && !_places_showing && _we_control_active && !_switcher_showing) + auto wm = WindowManager::Default(); + bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive()); + + if (_we_control_active && !_overlay_showing && !screen_grabbed && + !_switcher_showing && !_launcher_keynav) { if (_is_inside || _last_active_view || _show_now_activated || _new_application) { @@ -371,13 +350,16 @@ return false; } -bool -PanelMenuView::DrawWindowButtons() +bool PanelMenuView::DrawWindowButtons() const { - if (_places_showing) + auto wm = WindowManager::Default(); + bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive()); + + if (_overlay_showing) return true; - if (!_is_own_window && _we_control_active && _is_maximized && !_switcher_showing) + if (_we_control_active && _is_maximized && !screen_grabbed && + !_launcher_keynav && !_switcher_showing) { if (_is_inside || _show_now_activated || _new_application) { @@ -388,19 +370,18 @@ return false; } -void -PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +void PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::Geometry geo = GetGeometry(); - int button_width = _padding + _window_buttons->GetContentWidth() + _padding; - float factor = 4; + nux::Geometry const& geo = GetGeometry(); + int button_width = _window_buttons->GetContentWidth(); + const float factor = 4; button_width /= factor; - if (geo.width != _last_width || geo.height != _last_height) + if (geo != _last_geo) { - _last_width = geo.width; - _last_height = geo.height; - Refresh(); + _last_geo = geo; + QueueRelayout(); + Refresh(true); } GfxContext.PushClippingRectangle(geo); @@ -414,7 +395,7 @@ nux::ColorLayer layer(nux::Color(0x00000000), true, rop); nux::GetPainter().PushDrawLayer(GfxContext, GetGeometry(), &layer); - if (_title_layer && !_is_own_window) + if (_title_texture) { guint blend_alpha = 0, blend_src = 0, blend_dest = 0; bool draw_menus = DrawMenus(); @@ -426,7 +407,7 @@ for (auto entry : entries_) { - if (entry.second->IsEntryValid()) + if (entry.second->IsVisible()) { has_menu = true; break; @@ -539,20 +520,22 @@ geo.width, geo.height, _gradient_texture, texxform0, nux::color::White, - _title_layer->GetDeviceTexture(), + _title_texture->GetDeviceTexture(), texxform1, nux::color::White); } - else if (!_places_showing) + else if (!_overlay_showing) { + double title_opacity = 0.0f; + if (_we_control_active && _window_buttons->GetOpacity() == 0.0 && (!has_menu || (has_menu && GetOpacity() == 0.0))) { - nux::GetPainter().PushDrawLayer(GfxContext, geo, _title_layer); + title_opacity = 1.0f; } else { - double title_opacity = 1.0f; + title_opacity = 1.0f; if (has_menu) title_opacity -= MAX(GetOpacity(), _window_buttons->GetOpacity()); @@ -569,10 +552,13 @@ // If we're fading-in the buttons/menus, let's fade-out quickly the title title_opacity = CLAMP(title_opacity - 0.2f, 0.0f, 1.0f); } + } + if (title_opacity > 0.0f) + { nux::TexCoordXForm texxform; GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height, - _title_layer->GetDeviceTexture(), texxform, + _title_texture->GetDeviceTexture(), texxform, nux::color::White * title_opacity); } } @@ -585,10 +571,9 @@ GfxContext.PopClippingRectangle(); } -void -PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) +void PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::Geometry geo = GetGeometry(); + nux::Geometry const& geo = GetGeometry(); bool draw_menus = DrawMenus(); bool draw_buttons = DrawWindowButtons(); @@ -599,17 +584,17 @@ for (auto entry : entries_) entry.second->SetDisabled(false); - _menu_layout->ProcessDraw(GfxContext, true); + layout_->ProcessDraw(GfxContext, true); - _fade_out_animator->Stop(); + _fade_out_animator.Stop(); if (_new_application && !_is_inside) { - _fade_in_animator->Start(_menus_discovery_fadein, GetOpacity()); + _fade_in_animator.Start(_menus_discovery_fadein, GetOpacity()); } else { - _fade_in_animator->Start(GetOpacity()); + _fade_in_animator.Start(GetOpacity()); _new_app_menu_shown = false; } } @@ -619,19 +604,19 @@ entry.second->SetDisabled(true); } - if (GetOpacity() != 0.0f && !draw_menus) + if (GetOpacity() != 0.0f && !draw_menus && !_overlay_showing) { - _menu_layout->ProcessDraw(GfxContext, true); + layout_->ProcessDraw(GfxContext, true); - _fade_in_animator->Stop(); + _fade_in_animator.Stop(); if (!_new_app_menu_shown) { - _fade_out_animator->Start(1.0f - GetOpacity()); + _fade_out_animator.Start(1.0f - GetOpacity()); } else { - _fade_out_animator->Start(_menus_discovery_fadeout, 1.0f - GetOpacity()); + _fade_out_animator.Start(_menus_discovery_fadeout, 1.0f - GetOpacity()); } } @@ -639,298 +624,260 @@ { _window_buttons->ProcessDraw(GfxContext, true); - _fade_out_animator->Stop(); - _fade_in_animator->Start(_window_buttons->GetOpacity()); + if (_window_buttons->GetOpacity() != 1.0f) + { + _fade_out_animator.Stop(); + _fade_in_animator.Start(_window_buttons->GetOpacity()); + } } if (_window_buttons->GetOpacity() != 0.0f && !draw_buttons) { _window_buttons->ProcessDraw(GfxContext, true); - _fade_in_animator->Stop(); + _fade_in_animator.Stop(); /* If we try to hide only the buttons, then use a faster fadeout */ - if (!_fade_out_animator->IsRunning()) + if (!_fade_out_animator.IsRunning()) { - _fade_out_animator->Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity()); + _fade_out_animator.Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity()); } } GfxContext.PopClippingRectangle(); } -gchar* -PanelMenuView::GetActiveViewName() +std::string PanelMenuView::GetActiveViewName(bool use_appname) const { - gchar* label = nullptr; - BamfWindow* window; - - _is_own_window = false; + std::string label; + BamfWindow* window; window = bamf_matcher_get_active_window(_matcher); + if (BAMF_IS_WINDOW(window)) { + BamfView *view = reinterpret_cast(window); std::vector const& our_xids = nux::XInputWindow::NativeHandleList(); - guint32 window_xid = bamf_window_get_xid(BAMF_WINDOW(window)); + Window window_xid = bamf_window_get_xid(window); if (std::find(our_xids.begin(), our_xids.end(), window_xid) != our_xids.end()) { - _is_own_window = true; - return g_strdup(""); + /* If the active window is an unity window, we need to fallback to the + * top one, anyway we should always avoid to focus unity internal windows */ + BamfWindow* top_win = GetBamfWindowForXid(GetTopWindow()); + + if (top_win && top_win != window) + { + window = top_win; + } + else + { + return ""; + } } - if (BAMF_IS_WINDOW(window) && - bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) + if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) { - label = g_strdup(_("Ubuntu Desktop")); + label = _desktop_name; } - else if (!WindowManager::Default()->IsWindowOnCurrentDesktop(window_xid) || - WindowManager::Default()->IsWindowObscured(window_xid)) + else if (!IsValidWindow(window_xid)) { - return g_strdup(""); + return ""; } - if (_is_maximized) - label = bamf_view_get_name(BAMF_VIEW(window)); - } - - if (!label) - { - BamfApplication* app = bamf_matcher_get_active_application(_matcher); - if (BAMF_IS_APPLICATION(app)) + if (WindowManager::Default()->IsWindowMaximized(window_xid) && !use_appname) { - const gchar* filename; - - filename = bamf_application_get_desktop_file(app); - - if (filename && g_strcmp0(filename, "") != 0) - { - GDesktopAppInfo* info; - - info = g_desktop_app_info_new_from_filename(bamf_application_get_desktop_file(app)); + label = glib::String(bamf_view_get_name(view)).Str(); + } - if (info) - { - label = g_strdup(g_app_info_get_display_name(G_APP_INFO(info))); - g_object_unref(info); - } - else - { - g_warning("Unable to get GDesktopAppInfo for %s", - bamf_application_get_desktop_file(app)); - } - } + if (label.empty()) + { + BamfApplication* app; + app = bamf_matcher_get_application_for_window(_matcher, window); - if (label == nullptr) + if (BAMF_IS_APPLICATION(app)) { - BamfView* active_view; - - active_view = (BamfView*)bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_VIEW(active_view)) - label = bamf_view_get_name(active_view); - else - label = g_strdup(""); + view = reinterpret_cast(app); + label = glib::String(bamf_view_get_name(view)).Str(); } } - else + + if (label.empty()) { - label = g_strdup(" "); + view = reinterpret_cast(window); + label = glib::String(bamf_view_get_name(view)).Str(); } } - char *escaped = g_markup_escape_text(label, -1); - g_free(label); - label = g_strdup_printf("%s", escaped); - g_free(escaped); - return label; } -void PanelMenuView::DrawText(cairo_t *cr_real, - int &x, int y, int width, int height, - const char* font_desc, - const char* label, - int increase_size - ) +void PanelMenuView::DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const { - PangoLayout* layout = nullptr; - PangoFontDescription* desc = nullptr; - GtkSettings* settings = gtk_settings_get_default(); - cairo_t* cr; - cairo_pattern_t* linpat; - GdkScreen* screen = gdk_screen_get_default(); - int dpi = 0; - const int fading_pixels = 35; - char *font_description = g_strdup(font_desc); - - int text_width = 0; - int text_height = 0; - int text_space = 0; + using namespace panel; + cairo_t* cr; + cairo_pattern_t* linpat; + const int fading_pixels = 35; + int x = MAIN_LEFT_PADDING + TITLE_PADDING + geo.x; + int y = geo.y; + + int text_width = 0; + int text_height = 0; + int text_space = 0; + + // Find out dimensions first + GdkScreen* screen = gdk_screen_get_default(); + PangoContext* cxt; + PangoRectangle log_rect; + PangoFontDescription* desc; + + nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1); + cr = util_cg.GetContext(); + + int dpi = Style::Instance().GetTextDPI(); + + std::string font_description(Style::Instance().GetFontDescription(PanelItem::TITLE)); + desc = pango_font_description_from_string(font_description.c_str()); + + glib::Object layout(pango_cairo_create_layout(cr)); + pango_layout_set_font_description(layout, desc); + pango_layout_set_markup(layout, label.c_str(), -1); + + cxt = pango_layout_get_context(layout); + pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen)); + pango_cairo_context_set_resolution(cxt, dpi / static_cast(PANGO_SCALE)); + pango_layout_context_changed(layout); + + pango_layout_get_extents(layout, nullptr, &log_rect); + text_width = log_rect.width / PANGO_SCALE; + text_height = log_rect.height / PANGO_SCALE; - { // Find out dimensions first - GConfClient* client = gconf_client_get_default(); - PangoContext* cxt; - PangoRectangle log_rect; + pango_font_description_free(desc); + cairo_destroy(cr); - cr = _util_cg.GetContext(); + // Draw the text + GtkStyleContext* style_context = Style::Instance().GetStyleContext(); + text_space = geo.width - x; + cr = cr_real; + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - g_object_get(settings, "gtk-xft-dpi", &dpi, nullptr); + gtk_style_context_save(style_context); - font_description = gconf_client_get_string(client, WINDOW_TITLE_FONT_KEY.c_str(), nullptr); - desc = pango_font_description_from_string(font_description); + GtkWidgetPath* widget_path = gtk_widget_path_new(); + gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR); + gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM); + gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget"); - if (font_desc) - { - int size = pango_font_description_get_size(desc); - size /= pango_font_description_get_size_is_absolute(desc) ? 1 : PANGO_SCALE; + gtk_style_context_set_path(style_context, widget_path); + gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); + gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); - // Adjust y depending on size of the font - y -= ((unsigned int)(size - 9)) / 2; + y += (geo.height - text_height) / 2; - size += increase_size; + pango_cairo_update_layout(cr, layout); - char* description = g_strdup_printf("%s %d", font_desc, size); - pango_font_description_free(desc); - desc = pango_font_description_from_string(description); - g_free(description); - } - - layout = pango_cairo_create_layout(cr); - pango_layout_set_font_description(layout, desc); - pango_layout_set_markup(layout, label, -1); + if (text_width > text_space) + { + int out_pixels = text_width - text_space; + int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels; - cxt = pango_layout_get_context(layout); - pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen)); - pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE); - pango_layout_context_changed(layout); + cairo_push_group(cr); + gtk_render_layout(style_context, cr, x, y, layout); + cairo_pop_group_to_source(cr); - pango_layout_get_extents(layout, nullptr, &log_rect); - text_width = log_rect.width / PANGO_SCALE; - text_height = log_rect.height / PANGO_SCALE; + linpat = cairo_pattern_create_linear(geo.width - fading_width, y, geo.width, y); + cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1); + cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0); + cairo_mask(cr, linpat); - pango_font_description_free(desc); - g_free(font_description); - cairo_destroy(cr); - g_object_unref(client); + cairo_pattern_destroy(linpat); + } + else + { + gtk_render_layout(style_context, cr, x, y, layout); } - { // Draw the text - GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext(); - text_space = width - x; - cr = cr_real; + x += text_width; - gtk_style_context_save(style_context); + gtk_widget_path_free(widget_path); + gtk_style_context_restore(style_context); +} - GtkWidgetPath* widget_path = gtk_widget_path_new(); - gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget"); - gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR); - gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM); +void PanelMenuView::Refresh(bool force) +{ + nux::Geometry const& geo = GetGeometry(); - gtk_style_context_set_path(style_context, widget_path); - gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); - gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); + // We can get into a race that causes the geometry to be wrong as there hasn't been a + // layout cycle before the first callback. This is to protect from that. + if (geo.width > _monitor_geo.width) + return; - y += (height - text_height) / 2; + auto win_manager = WindowManager::Default(); + std::string new_title; - pango_cairo_update_layout(cr, layout); + if (win_manager->IsScaleActive()) + { + if (win_manager->IsScaleActiveForGroup()) + new_title = GetActiveViewName(true); + else if (_we_control_active) + new_title = _desktop_name; + } + else if (win_manager->IsExpoActive()) + { + new_title = _desktop_name; + } + else if (!_we_control_active) + { + new_title = ""; + } + else if (!_switcher_showing && !_launcher_keynav) + { + new_title = GetActiveViewName(); + _window_buttons->SetControlledWindow(_active_xid); + } - if (text_width > text_space) + if (!_switcher_showing && !_launcher_keynav) + { + if (_panel_title != new_title) { - int out_pixels = text_width - text_space; - int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels; - - cairo_push_group(cr); - gtk_render_layout(style_context, cr, x, y, layout); - cairo_pop_group_to_source(cr); - - linpat = cairo_pattern_create_linear(width - fading_width, y, width, y); - cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1); - cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0); - cairo_mask(cr, linpat); - - cairo_pattern_destroy(linpat); + _panel_title = new_title; } - else + else if (!force && _last_geo == geo && _title_texture) { - gtk_render_layout(style_context, cr, x, y, layout); + // No need to redraw the title, let's save some CPU time! + return; } - - x += text_width; - - gtk_widget_path_free(widget_path); - gtk_style_context_restore(style_context); } - if (layout) - g_object_unref(layout); -} - -void -PanelMenuView::Refresh() -{ - nux::Geometry geo = GetGeometry(); - - // We can get into a race that causes the geometry to be wrong as there hasn't been a - // layout cycle before the first callback. This is to protect from that. - if (geo.width > _monitor_geo.width) + if (_panel_title.empty()) + { + _title_texture = nullptr; return; + } - int x = 0; - int y = 0; - int width = geo.width; - int height = geo.height; - - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height); cairo_t* cr = cairo_graphics.GetContext(); - cairo_set_line_width(cr, 1); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + glib::String escaped(g_markup_escape_text(_panel_title.c_str(), -1)); - x = _padding; - y = 0; + std::ostringstream bold_label; + bold_label << "" << escaped.Str() << ""; - if (_panel_title) - { - DrawText(cr, x, y, width, height, nullptr, _panel_title); - } - else - { - char* title = GetActiveViewName(); - DrawText(cr, x, y, width, height, nullptr, title); - g_free(title); - } + DrawTitle(cr, geo, bold_label.str()); cairo_destroy(cr); - nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics); - - if (_title_layer) - delete _title_layer; - - nux::TexCoordXForm texxform; - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); - - nux::ROPConfig rop; - rop.Blend = true; - rop.SrcBlend = GL_ONE; - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - _title_layer = new nux::TextureLayer(texture2D->GetDeviceTexture(), - texxform, - nux::color::White, - true, - rop); - texture2D->UnReference(); + _title_texture = texture_ptr_from_cairo_graphics(cairo_graphics); } -void -PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view, - bool is_active) +void PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view, bool is_active) { if (is_active) + { _last_active_view = view; + } else { if (_last_active_view == view) @@ -943,37 +890,36 @@ FullRedraw(); } -void -PanelMenuView::OnEntryAdded(unity::indicator::Entry::Ptr const& entry) +void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry) { - auto view = AddEntry(entry, 6, IndicatorEntryPosition::END, IndicatorEntryType::MENU); + PanelIndicatorEntryView* view; - entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow)); - - view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged)); + view = new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU); view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter)); view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave)); + + entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow)); + view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged)); + + AddEntryView(view, IndicatorEntryPosition::END); } -void -PanelMenuView::AllMenusClosed() +void PanelMenuView::NotifyAllMenusClosed() { - auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); - _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y); _last_active_view = nullptr; + auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); + _is_inside = GetAbsoluteGeometry().IsInside(mouse); FullRedraw(); } -void -PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name) +void PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name) { Refresh(); FullRedraw(); } -gboolean -PanelMenuView::OnNewAppShow(PanelMenuView* self) +gboolean PanelMenuView::OnNewAppShow(PanelMenuView* self) { BamfApplication* active_app = bamf_matcher_get_active_application(self->_matcher); self->_new_application = glib::Object(active_app, glib::AddRef()); @@ -994,10 +940,9 @@ return FALSE; } -gboolean -PanelMenuView::OnNewAppHide(PanelMenuView* self) +gboolean PanelMenuView::OnNewAppHide(PanelMenuView* self) { - self->OnViewClosed(self->_matcher, BAMF_VIEW(self->_new_application.RawPtr())); + self->OnApplicationClosed(self->_new_application); self->_new_app_hide_id = 0; self->_new_app_menu_shown = true; self->QueueDraw(); @@ -1005,8 +950,7 @@ return FALSE; } -void -PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view) +void PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view) { /* FIXME: here we should also check for if the view is also user_visible * but it seems that BAMF doesn't handle this correctly after some @@ -1017,27 +961,48 @@ _new_apps.push_front(glib::Object(BAMF_APPLICATION(view), glib::AddRef())); } -void -PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view) +void PanelMenuView::OnApplicationClosed(BamfApplication* app) { - if (!BAMF_IS_APPLICATION(view)) - return; - - BamfApplication* app = BAMF_APPLICATION(view); + if (BAMF_IS_APPLICATION(app)) + { + if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end()) + { + _new_apps.remove(glib::Object(app, glib::AddRef())); + } + else if (_new_apps.empty()) + { + _new_application = nullptr; + } + } - if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end()) + if (app == _new_application) { - _new_apps.remove(glib::Object(app, glib::AddRef())); + _new_application = nullptr; + } +} - if (_new_application == app || _new_apps.empty()) - _new_application = nullptr; +void PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view) +{ + if (BAMF_IS_APPLICATION(view)) + { + OnApplicationClosed(reinterpret_cast(view)); + } + else if (reinterpret_cast(view) == _new_application) + { + _new_application = nullptr; + } + else if (BAMF_IS_WINDOW(view)) + { + /* FIXME, this can be removed when window_unmapped WindowManager signal + * will emit the proper xid */ + Window xid = bamf_window_get_xid(reinterpret_cast(view)); + OnWindowUnmapped(xid); } } -void -PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher, - BamfApplication* old_app, - BamfApplication* new_app) +void PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher, + BamfApplication* old_app, + BamfApplication* new_app) { if (BAMF_IS_APPLICATION(new_app)) { @@ -1074,15 +1039,14 @@ } if (_new_application) - OnViewClosed(matcher, BAMF_VIEW(_new_application.RawPtr())); + OnApplicationClosed(_new_application); } } } -void -PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher, - BamfView* old_view, - BamfView* new_view) +void PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher, + BamfView* old_view, + BamfView* new_view) { _show_now_activated = false; _is_maximized = false; @@ -1096,15 +1060,16 @@ if (BAMF_IS_WINDOW(new_view)) { - BamfWindow* window = BAMF_WINDOW(new_view); - guint32 xid = _active_xid = bamf_window_get_xid(window); - _is_maximized = WindowManager::Default()->IsWindowMaximized(xid); - nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid); + WindowManager *wm = WindowManager::Default(); + BamfWindow* window = reinterpret_cast(new_view); + guint32 xid = bamf_window_get_xid(window); + _active_xid = xid; + _is_maximized = wm->IsWindowMaximized(xid); if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP) _we_control_active = true; else - _we_control_active = UScreen::GetDefault()->GetMonitorGeometry(_monitor).IsPointInside(geo.x + (geo.width / 2), geo.y); + _we_control_active = IsWindowUnderOurControl(xid); if (_decor_map.find(xid) == _decor_map.end()) { @@ -1113,9 +1078,9 @@ // if we've just started tracking this window and it is maximized, let's // make sure it's undecorated just in case it slipped by us earlier // (I'm looking at you, Chromium!) - if (_is_maximized && WindowManager::Default ()->IsWindowDecorated(xid)) + if (_is_maximized && wm->IsWindowDecorated(xid)) { - WindowManager::Default()->Undecorate(xid); + wm->Undecorate(xid); _maximized_set.insert(xid); } } @@ -1126,103 +1091,128 @@ // register callback for new view _view_name_changed_signal.Connect(new_view, "name-changed", sigc::mem_fun(this, &PanelMenuView::OnNameChanged)); + + _window_buttons->SetControlledWindow(_is_maximized ? _active_xid : 0); } Refresh(); FullRedraw(); } -void -PanelMenuView::OnSpreadInitiate() +void PanelMenuView::OnSpreadInitiate() { /*foreach (guint32 &xid, windows) { - if (WindowManager::Default ()->IsWindowMaximized (xid)) - WindowManager::Default ()->Decorate (xid); + if (WindowManager::Default()->IsWindowMaximized(xid)) + WindowManager::Default()->Decorate(xid); }*/ + + Refresh(); + QueueDraw(); } -void -PanelMenuView::OnSpreadTerminate() +void PanelMenuView::OnSpreadTerminate() { /*foreach (guint32 &xid, windows) { - if (WindowManager::Default ()->IsWindowMaximized (xid)) - WindowManager::Default ()->Undecorate (xid); + if (WindowManager::Default()->IsWindowMaximized(xid)) + WindowManager::Default()->Undecorate(xid); }*/ + + Refresh(); + QueueDraw(); } -void -PanelMenuView::OnWindowMinimized(guint32 xid) +void PanelMenuView::OnExpoInitiate() +{ + Refresh(); + QueueDraw(); +} + +void PanelMenuView::OnExpoTerminate() +{ + Refresh(); + QueueDraw(); +} + +void PanelMenuView::OnWindowMinimized(guint32 xid) { if (WindowManager::Default()->IsWindowMaximized(xid)) { WindowManager::Default()->Decorate(xid); _maximized_set.erase(xid); + + Refresh(); + QueueDraw(); } } -void -PanelMenuView::OnWindowUnminimized(guint32 xid) +void PanelMenuView::OnWindowUnminimized(guint32 xid) { if (WindowManager::Default()->IsWindowMaximized(xid)) { WindowManager::Default()->Undecorate(xid); _maximized_set.insert(xid); + + Refresh(); + QueueDraw(); } } -void -PanelMenuView::OnWindowUnmapped(guint32 xid) +void PanelMenuView::OnWindowUnmapped(guint32 xid) { - if (WindowManager::Default()->IsWindowMaximized(xid)) + // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap) + // we need to do this again on BamfView closed signal. + if (_maximized_set.find(xid) != _maximized_set.end()) { WindowManager::Default()->Decorate(xid); _maximized_set.erase(xid); + _decor_map.erase(xid); + + Refresh(); + QueueDraw(); } } -void -PanelMenuView::OnWindowMapped(guint32 xid) +void PanelMenuView::OnWindowMapped(guint32 xid) { if (WindowManager::Default()->IsWindowMaximized(xid)) { WindowManager::Default()->Undecorate(xid); _maximized_set.insert(xid); + + Refresh(); + QueueDraw(); } } -void -PanelMenuView::OnWindowDecorated(guint32 xid) +void PanelMenuView::OnWindowDecorated(guint32 xid) { _decor_map[xid] = true; if (_maximized_set.find(xid) != _maximized_set.end ()) { - WindowManager::Default ()->Undecorate(xid); + WindowManager::Default()->Undecorate(xid); } } -void -PanelMenuView::OnWindowUndecorated(guint32 xid) +void PanelMenuView::OnWindowUndecorated(guint32 xid) { _decor_map[xid] = false; } -void -PanelMenuView::OnWindowMaximized(guint xid) +void PanelMenuView::OnWindowMaximized(guint xid) { - BamfWindow* window; bool updated = false; + bool is_active = (_active_xid == xid); - window = bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid) + if (is_active) { - _is_maximized = true; - // We need to update the _is_inside state in the case of maximization by grab auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); - _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y); + _is_inside = GetAbsoluteGeometry().IsInside(mouse); + + _is_maximized = true; updated = true; } @@ -1241,16 +1231,12 @@ } } -void -PanelMenuView::OnWindowRestored(guint xid) +void PanelMenuView::OnWindowRestored(guint xid) { - BamfWindow* window; - if (_maximized_set.find(xid) == _maximized_set.end()) return; - window = bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid) + if (_active_xid == xid) { _is_maximized = false; _is_grabbed = false; @@ -1265,311 +1251,389 @@ FullRedraw(); } -gboolean -PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self) +gboolean PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self) { - auto window_geo = WindowManager::Default()->GetWindowGeometry(self->_active_xid); - auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(self->_monitor); - auto intersect = monitor_geo.Intersect(window_geo); + bool we_control_window = self->IsWindowUnderOurControl(self->_active_xid); - self->_we_control_active = (intersect.width > window_geo.width/4 && - intersect.height > window_geo.height/4); + if (we_control_window != self->_we_control_active) + { + self->_we_control_active = we_control_window; + + self->Refresh(); + self->QueueDraw(); + } self->_active_moved_id = 0; - self->QueueDraw(); return FALSE; } -void -PanelMenuView::OnWindowMoved(guint xid) +void PanelMenuView::OnWindowMoved(guint xid) { if (_active_xid == xid) { - if (_active_moved_id) - g_source_remove(_active_moved_id); + /* When moving the active window, if the current panel is controlling + * the active window, then we postpone the timeout function every movement + * that we have, setting a longer timeout. + * Otherwise, if the moved window is not controlled by the current panel + * every few millisecond we check the new window position */ + + unsigned int timeout = 250; - if (!_we_control_active) - UpdateActiveWindowPosition(this); + if (_we_control_active) + { + if (_active_moved_id) + g_source_remove(_active_moved_id); + } else - _active_moved_id = g_timeout_add(250, (GSourceFunc)PanelMenuView::UpdateActiveWindowPosition, this); + { + timeout = 60; + + if (_active_moved_id) + return; + } + + _active_moved_id = g_timeout_add(timeout, (GSourceFunc)UpdateActiveWindowPosition, this); } } -void -PanelMenuView::OnCloseClicked() +bool PanelMenuView::IsWindowUnderOurControl(Window xid) const { - if (_places_showing) - { - ubus_server_send_message(ubus_server_get_default(), UBUS_PLACE_VIEW_CLOSE_REQUEST, nullptr); - } - else + if (UScreen::GetDefault()->GetMonitors().size() > 1) { - BamfWindow* window; + auto wm = WindowManager::Default(); + nux::Geometry const& window_geo = wm->GetWindowGeometry(xid); + nux::Geometry const& intersect = _monitor_geo.Intersect(window_geo); - window = bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_WINDOW(window)) - { - WindowManager::Default()->Close(bamf_window_get_xid(window)); - NeedRedraw(); - } + /* We only care of the horizontal window portion */ + return (intersect.width > window_geo.width/2 && intersect.height > 0); } + + return true; } -void -PanelMenuView::OnMinimizeClicked() +bool PanelMenuView::IsValidWindow(Window xid) const { - if (_places_showing) + auto wm = WindowManager::Default(); + std::vector const& our_xids = nux::XInputWindow::NativeHandleList(); + + if (wm->IsWindowOnCurrentDesktop(xid) && !wm->IsWindowObscured(xid) && + wm->IsWindowVisible(xid) && IsWindowUnderOurControl(xid) && + std::find(our_xids.begin(), our_xids.end(), xid) == our_xids.end()) { - // no action when dash is opened, LP bug #838875 - return; + return true; } - else - { - BamfWindow* window; - window = bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_WINDOW(window)) + return false; +} + +Window PanelMenuView::GetMaximizedWindow() const +{ + Window window_xid = 0; + + // Find the front-most of the maximized windows we are controlling + for (auto xid : _maximized_set) + { + // We can safely assume only the front-most is visible + if (IsValidWindow(xid)) { - WindowManager::Default()->Minimize(bamf_window_get_xid(window)); - NeedRedraw(); + window_xid = xid; + break; } } + + return window_xid; } -void -PanelMenuView::OnRestoreClicked() +Window PanelMenuView::GetTopWindow() const { - if (_places_showing) - { - if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP) - dash::Settings::Instance().SetFormFactor(dash::FormFactor::NETBOOK); - else - dash::Settings::Instance().SetFormFactor(dash::FormFactor::DESKTOP); - } - else + Window window_xid = 0; + GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor); + + for (GList* l = windows; l; l = l->next) { - BamfWindow* window; + if (!BAMF_IS_WINDOW(l->data)) + continue; + + Window xid = bamf_window_get_xid(static_cast(l->data)); + bool visible = bamf_view_user_visible(static_cast(l->data)); - window = bamf_matcher_get_active_window(_matcher); - if (BAMF_IS_WINDOW(window)) + if (visible && IsValidWindow(xid)) { - WindowManager::Default()->Restore(bamf_window_get_xid(window)); - NeedRedraw(); + window_xid = xid; } } + + g_list_free(windows); + + return window_xid; } -guint32 -PanelMenuView::GetMaximizedWindow() +BamfWindow* PanelMenuView::GetBamfWindowForXid(Window xid) const { - guint32 window_xid = 0; - nux::Geometry monitor = UScreen::GetDefault()->GetMonitorGeometry(_monitor); + BamfWindow* window = nullptr; - // Find the front-most of the maximized windows we are controlling - for (auto xid : _maximized_set) + if (xid != 0) { - // We can safely assume only the front-most is visible - if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid) - && !WindowManager::Default()->IsWindowObscured(xid)) + GList* windows = bamf_matcher_get_windows(_matcher); + + for (GList* l = windows; l; l = l->next) { - nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid); - if (monitor.IsPointInside(geo.x + (geo.width / 2), geo.y)) + if (!BAMF_IS_WINDOW(l->data)) + continue; + + auto win = static_cast(l->data); + + if (bamf_window_get_xid(win) == xid) { - window_xid = xid; + window = win; break; } } + + g_list_free(windows); } - return window_xid; + + return window; } -void -PanelMenuView::OnMaximizedGrabStart(int x, int y, unsigned long button_flags, unsigned long) +void PanelMenuView::OnMaximizedActivate(int x, int y) { - Window maximized_win; - if (nux::GetEventButton(button_flags) != 1 || _places_showing) - return; - - // When Start dragging the panelmenu of a maximized window, change cursor - // to simulate the dragging, waiting to go out of the panel area. - // - // This is a workaround to avoid that the grid plugin would be fired - // showing the window shape preview effect. See bug #838923 + Window maximized = GetMaximizedWindow(); - maximized_win = GetMaximizedWindow (); - - if (maximized_win != 0) + if (maximized != 0) { - /* Always activate the window in case it is on another monitor */ - WindowManager::Default ()->Activate (maximized_win); - _panel_titlebar_grab_area->SetGrabbed(true); + WindowManager::Default()->Activate(maximized); } } -void -PanelMenuView::OnMaximizedGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long) +void PanelMenuView::OnMaximizedRestore(int x, int y) { -// FIXME nux doesn't export it with drag event. -// if (nux::GetEventButton(button_flags) != 1) -// return; - - // We use this, due to the problem above - if (!_panel_titlebar_grab_area->IsGrabbed()) + if (_overlay_showing) return; - auto panel = static_cast(GetTopLevelViewWindow()); + Window maximized = GetMaximizedWindow(); - if (!panel) - return; - - x += _panel_titlebar_grab_area->GetAbsoluteX(); - y += _panel_titlebar_grab_area->GetAbsoluteY(); - - guint32 window_xid = GetMaximizedWindow(); - - // When the drag goes out from the Panel, start the real movement. - // - // This is a workaround to avoid that the grid plugin would be fired - // showing the window shape preview effect. See bug #838923 - if (window_xid != 0 && panel && !panel->GetAbsoluteGeometry().IsPointInside(x, y)) + if (maximized != 0) { - _panel_titlebar_grab_area->SetGrabbed(false); - - WindowManager::Default()->Activate(window_xid); + WindowManager::Default()->Restore(maximized); _is_inside = true; - _is_grabbed = true; - Refresh(); - FullRedraw(); - WindowManager::Default()->StartMove(window_xid, x, y); } } -void -PanelMenuView::OnMaximizedGrabEnd(int x, int y, unsigned long, unsigned long) +void PanelMenuView::OnMaximizedLower(int x, int y) { - _panel_titlebar_grab_area->SetGrabbed(false); - - x += _panel_titlebar_grab_area->GetAbsoluteX(); - y += _panel_titlebar_grab_area->GetAbsoluteY(); - _is_inside = GetAbsoluteGeometry().IsPointInside(x, y); + if (_overlay_showing) + return; - if (!_is_inside) - _is_grabbed = false; + Window maximized = GetMaximizedWindow(); - Refresh(); - FullRedraw(); + if (maximized != 0) + { + WindowManager::Default()->Lower(maximized); + } } -void -PanelMenuView::OnMouseDoubleClicked(int x, int y, unsigned long button_flags, unsigned long) +void PanelMenuView::OnMaximizedGrabStart(int x, int y) { - if (nux::GetEventButton(button_flags) != 1 || _places_showing) - return; + /* When Start dragging the panelmenu of a maximized window, change cursor + * to simulate the dragging, waiting to go out of the panel area. + * + * This is a workaround to avoid that the grid plugin would be fired + * showing the window shape preview effect. See bug #838923 */ - guint32 window_xid = GetMaximizedWindow(); + Window maximized = GetMaximizedWindow(); - if (window_xid != 0) + if (maximized != 0) { - WindowManager::Default()->Restore(window_xid); - _is_inside = true; + /* Always activate the window in case it is on another monitor */ + WindowManager::Default()->Activate(maximized); + _titlebar_grab_area->SetGrabbed(true); } } -void -PanelMenuView::OnMouseClicked(int x, int y, unsigned long button_flags, unsigned long) +void PanelMenuView::OnMaximizedGrabMove(int x, int y) { - if (nux::GetEventButton(button_flags) != 1 || _places_showing) + auto panel = static_cast(GetTopLevelViewWindow()); + + if (!panel) return; - guint32 window_xid = GetMaximizedWindow(); + /* Adjusting the x, y coordinates to get the absolute values */ + x += _titlebar_grab_area->GetAbsoluteX(); + y += _titlebar_grab_area->GetAbsoluteY(); + + Window maximized = GetMaximizedWindow(); + + /* When the drag goes out from the Panel, start the real movement. + * + * This is a workaround to avoid that the grid plugin would be fired + * showing the window shape preview effect. See bug #838923 */ + if (maximized != 0 && panel) + { + nux::Geometry const& panel_geo = panel->GetAbsoluteGeometry(); + + if (!panel_geo.IsPointInside(x, y)) + { + auto wm = WindowManager::Default(); + nux::Geometry const& restored_geo = wm->GetWindowSavedGeometry(maximized); + nux::Geometry const& workarea_geo = wm->GetWorkAreaGeometry(maximized); + + /* By default try to restore the window horizontally-centered respect to the + * pointer position, if it doesn't fit on that area try to keep it into the + * current workarea as much as possible, but giving priority to the left border + * that shouldn't be never put out of the workarea */ + int restore_x = x - (restored_geo.width * x / panel_geo.width); + int restore_y = y; - if (window_xid != 0) - { - WindowManager::Default()->Raise(window_xid); + if (restore_x + restored_geo.width > workarea_geo.x + workarea_geo.width) + { + restore_x = workarea_geo.x + workarea_geo.width - restored_geo.width; + } + + if (restore_x < workarea_geo.x) + { + restore_x = workarea_geo.x; + } + + wm->Activate(maximized); + wm->RestoreAt(maximized, restore_x, restore_y); + + _is_inside = true; + _is_grabbed = true; + Refresh(); + FullRedraw(); + + /* Ungrab the pointer and start the X move, to make the decorator handle it */ + _titlebar_grab_area->SetGrabbed(false); + wm->StartMove(maximized, x, y); + } } } -void -PanelMenuView::OnMouseMiddleClicked(int x, int y, unsigned long button_flags, unsigned long) +void PanelMenuView::OnMaximizedGrabEnd(int x, int y) { - if (nux::GetEventButton(button_flags) != 2 || _places_showing) - return; + _titlebar_grab_area->SetGrabbed(false); - guint32 window_xid = GetMaximizedWindow(); + x += _titlebar_grab_area->GetAbsoluteX(); + y += _titlebar_grab_area->GetAbsoluteY(); + _is_inside = GetAbsoluteGeometry().IsPointInside(x, y); - if (window_xid != 0) - { - WindowManager::Default()->Lower(window_xid); - } + if (!_is_inside) + _is_grabbed = false; + + Refresh(); + FullRedraw(); } // Introspectable std::string PanelMenuView::GetName() const { - return ""; + return "MenuView"; } void PanelMenuView::AddProperties(GVariantBuilder* builder) { -} + PanelIndicatorsView::AddProperties(builder); -void PanelMenuView::OnPlaceViewShown(GVariant* data, PanelMenuView* self) -{ - self->_places_showing = true; - self->QueueDraw(); + variant::BuilderWrapper(builder) + .add("mouse_inside", _is_inside) + .add("grabbed", _is_grabbed) + .add("active_win_maximized", _is_maximized) + .add("panel_title", _panel_title) + .add("desktop_active", (_panel_title == _desktop_name)) + .add("monitor", _monitor) + .add("active_window", _active_xid) + .add("draw_menus", DrawMenus()) + .add("draw_window_buttons", DrawWindowButtons()) + .add("controls_active_window", _we_control_active) + .add("fadein_duration", _menus_fadein) + .add("fadeout_duration", _menus_fadeout) + .add("discovery_duration", _menus_discovery) + .add("discovery_fadein_duration", _menus_discovery_fadein) + .add("discovery_fadeout_duration", _menus_discovery_fadeout); } -void PanelMenuView::OnPlaceViewHidden(GVariant* data, PanelMenuView* self) +void PanelMenuView::OnSwitcherShown(GVariant* data) { - self->_places_showing = false; - self->QueueDraw(); -} + if (!data) + return; -void PanelMenuView::OnSwitcherShown(GVariant* data, PanelMenuView* self) -{ - if (!self || !data) + gboolean switcher_shown; + gint monitor; + g_variant_get(data, "(bi)", &switcher_shown, &monitor); + + if (switcher_shown == _switcher_showing || monitor != _monitor) return; - self->_switcher_showing = g_variant_get_boolean(data); + _switcher_showing = switcher_shown; - if (!self->_switcher_showing) + if (!_switcher_showing) { auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); - self->_is_inside = self->GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y); - - if (self->_panel_title) - { - g_free(self->_panel_title); - self->_panel_title = nullptr; - } + _is_inside = GetAbsoluteGeometry().IsInside(mouse); } else { - self->_show_now_activated = false; + _show_now_activated = false; } - self->Refresh(); - self->QueueDraw(); + Refresh(); + QueueDraw(); +} + +void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data) +{ + if (!data || !_switcher_showing) + return; + + const gchar *title = g_variant_get_string(data, 0); + _panel_title = (title ? title : ""); + + Refresh(); + QueueDraw(); } -void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self) +void PanelMenuView::OnLauncherKeyNavStarted(GVariant* data) { - if (!self || !data) + if (_launcher_keynav) return; - if (self->_panel_title) - g_free(self->_panel_title); - self->_panel_title = g_strdup(g_variant_get_string(data, 0)); + if (!data || (data && g_variant_get_int32(data) == _monitor)) + { + _launcher_keynav = true; + } +} - self->Refresh(); - self->QueueDraw(); +void PanelMenuView::OnLauncherKeyNavEnded(GVariant* data) +{ + if (!_launcher_keynav) + return; + + _launcher_keynav = false; + + auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); + _is_inside = GetAbsoluteGeometry().IsInside(mouse); + + Refresh(); + QueueDraw(); +} + +void PanelMenuView::OnLauncherSelectionChanged(GVariant* data) +{ + if (!data || !_launcher_keynav) + return; + + const gchar *title = g_variant_get_string(data, 0); + _panel_title = (title ? title : ""); + + Refresh(); + QueueDraw(); } -gboolean -PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self) +gboolean PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self) { bool active = false; @@ -1593,8 +1657,7 @@ return FALSE; } -void -PanelMenuView::UpdateShowNow(bool status) +void PanelMenuView::UpdateShowNow(bool status) { /* When we get a show now event, if we are requested to show the menus, * we take the last incoming event and we wait for small delay (to avoid the @@ -1606,6 +1669,7 @@ { _show_now_activated = false; QueueDraw(); + return; } if (_update_show_now_id != 0) @@ -1622,27 +1686,55 @@ } } -void -PanelMenuView::SetMonitor(int monitor) +void PanelMenuView::SetMonitor(int monitor) { _monitor = monitor; _monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(_monitor); -} -bool -PanelMenuView::GetControlsActive() -{ - return _we_control_active; + _maximized_set.clear(); + GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor); + + for (GList* l = windows; l; l = l->next) + { + if (!BAMF_IS_WINDOW(l->data)) + continue; + + auto window = static_cast(l->data); + auto view = static_cast(l->data); + + if (bamf_view_is_active(view)) + { + _active_xid = bamf_window_get_xid(window); + } + + if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED) + { + Window xid = bamf_window_get_xid(window); + + _decor_map[xid] = WindowManager::Default()->IsWindowDecorated(xid); + + if (_decor_map[xid]) + WindowManager::Default()->Undecorate(xid); + + _maximized_set.insert(xid); + } + } + + Window maximized = GetMaximizedWindow(); + Window buttons_win = (maximized == _active_xid) ? maximized : 0; + + _window_buttons->SetMonitor(_monitor); + _window_buttons->SetControlledWindow(buttons_win); + + g_list_free(windows); } -bool -PanelMenuView::HasOurWindowFocused() +bool PanelMenuView::GetControlsActive() const { - return _is_own_window; + return _we_control_active; } -void -PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) +void PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { if (!_is_inside) { @@ -1655,8 +1747,7 @@ } } -void -PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) +void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { if (_is_inside) { diff -Nru unity-5.8.0/plugins/unityshell/src/PanelMenuView.h unity-5.10.0/plugins/unityshell/src/PanelMenuView.h --- unity-5.8.0/plugins/unityshell/src/PanelMenuView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelMenuView.h 2012-04-12 13:21:21.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 @@ -15,14 +15,15 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan <3v1n0@ubuntu.com> */ #ifndef PANEL_MENU_VIEW_H #define PANEL_MENU_VIEW_H -#include -#include -#include +#include +#include +#include #include "PanelIndicatorsView.h" #include "StaticCairoText.h" @@ -30,10 +31,7 @@ #include "PanelTitlebarGrabAreaView.h" #include "PluginAdapter.h" #include "Animator.h" - -#include -#include -#include +#include "UBusWrapper.h" namespace unity { @@ -41,41 +39,50 @@ class PanelMenuView : public PanelIndicatorsView { public: - // This contains all the menubar logic for the Panel. Mainly it contains - // the following states: - // 1. Unmaximized window + no mouse hover - // 2. Unmaximized window + mouse hover - // 3. Unmaximized window + active menu (Alt+F/arrow key nav) - // 4. Maximized window + no mouse hover - // 5. Maximized window + mouse hover - // 6. Maximized window + active menu - // - // It also deals with undecorating maximized windows (and redecorating them - // on unmaximize) - - PanelMenuView(int padding = 6); + PanelMenuView(); ~PanelMenuView(); void SetMenuShowTimings(int fadein, int fadeout, int discovery, int discovery_fadein, int discovery_fadeout); - void FullRedraw(); + void SetMousePosition(int x, int y); + void SetMonitor(int monitor); + + Window GetTopWindow() const; + Window GetMaximizedWindow() const; + bool GetControlsActive() const; + + void NotifyAllMenusClosed(); + + virtual void AddIndicator(indicator::Indicator::Ptr const& indicator); + + virtual void OverlayShown(); + virtual void OverlayHidden(); + +protected: + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); - virtual long PostLayoutManagement(long LayoutResult); - - void SetMousePosition(int x, int y); + virtual void PreLayoutManagement(); + virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, + nux::NuxEventType event_type); + virtual void OnEntryAdded(indicator::Entry::Ptr const& entry); +private: void OnActiveChanged(PanelIndicatorEntryView* view, bool is_active); void OnViewOpened(BamfMatcher* matcher, BamfView* view); void OnViewClosed(BamfMatcher* matcher, BamfView* view); + void OnApplicationClosed(BamfApplication* app); void OnActiveWindowChanged(BamfMatcher* matcher, BamfView* old_view, BamfView* new_view); void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app); void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name); void OnSpreadInitiate(); void OnSpreadTerminate(); + void OnExpoInitiate(); + void OnExpoTerminate(); void OnWindowMinimized(guint32 xid); void OnWindowUnminimized(guint32 xid); void OnWindowUnmapped(guint32 xid); @@ -86,42 +93,30 @@ void OnWindowDecorated(guint32 xid); void OnWindowUndecorated(guint32 xid); - guint32 GetMaximizedWindow(); - - void OnMaximizedGrabStart(int, int, unsigned long, unsigned long); - void OnMaximizedGrabMove(int, int, int, int, unsigned long, unsigned long); - void OnMaximizedGrabEnd(int, int, unsigned long, unsigned long); - void OnMouseDoubleClicked(int, int, unsigned long, unsigned long); - void OnMouseClicked(int, int, unsigned long, unsigned long); - void OnMouseMiddleClicked(int, int, unsigned long, unsigned long); - - void Refresh(); - void AllMenusClosed(); - - void OnCloseClicked(); - void OnMinimizeClicked(); - void OnRestoreClicked(); - void SetMonitor(int monitor); - bool GetControlsActive(); - - bool HasOurWindowFocused(); + void OnMaximizedActivate(int x, int y); + void OnMaximizedRestore(int x, int y); + void OnMaximizedLower(int x, int y); + void OnMaximizedGrabStart(int x, int y); + void OnMaximizedGrabMove(int x, int y); + void OnMaximizedGrabEnd(int x, int y); -protected: - std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void FullRedraw(); + void Refresh(bool force = false); + void DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const; - virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type); void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); void OnPanelViewMouseMove(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state); - virtual void OnEntryAdded(unity::indicator::Entry::Ptr const& entry); -private: - gchar* GetActiveViewName(); - static void OnPlaceViewShown(GVariant* data, PanelMenuView* self); - static void OnPlaceViewHidden(GVariant* data, PanelMenuView* self); - static void OnSwitcherShown(GVariant* data, PanelMenuView* self); - static void OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self); + BamfWindow* GetBamfWindowForXid(Window xid) const; + + std::string GetActiveViewName(bool use_appname = false) const; + + void OnSwitcherShown(GVariant* data); + void OnSwitcherSelectionChanged(GVariant* data); + void OnLauncherKeyNavStarted(GVariant* data); + void OnLauncherKeyNavEnded(GVariant* data); + void OnLauncherSelectionChanged(GVariant* data); void UpdateShowNow(bool ignore); @@ -130,53 +125,47 @@ static gboolean OnNewAppShow(PanelMenuView* self); static gboolean OnNewAppHide(PanelMenuView* self); - void DrawText(cairo_t *cr_real, - int &x, int y, int width, int height, - const char* font_desc, - const char* label, - int increase_size=0 - ); + bool IsValidWindow(Window xid) const; + bool IsWindowUnderOurControl(Window xid) const; - bool DrawMenus(); - bool DrawWindowButtons(); + bool DrawMenus() const; + bool DrawWindowButtons() const; void OnFadeInChanged(double); void OnFadeOutChanged(double); -private: glib::Object _matcher; - nux::TextureLayer* _title_layer; - nux::HLayout* _menu_layout; - nux::CairoGraphics _util_cg; + nux::TextureLayer* _title_layer; + nux::HLayout* _menu_layout; + nux::ObjectPtr _title_texture; nux::ObjectPtr _gradient_texture; bool _is_inside; bool _is_grabbed; bool _is_maximized; - bool _is_own_window; - PanelIndicatorEntryView* _last_active_view; - glib::Object _new_application; + PanelIndicatorEntryView* _last_active_view; WindowButtons* _window_buttons; - PanelTitlebarGrabArea* _panel_titlebar_grab_area; + PanelTitlebarGrabArea* _titlebar_grab_area; + glib::Object _new_application; - std::map _decor_map; - std::set _maximized_set; + std::map _decor_map; + std::set _maximized_set; std::list> _new_apps; + std::string _panel_title; + nux::Geometry _last_geo; - int _padding; - int _last_width; - int _last_height; - - bool _places_showing; + bool _overlay_showing; bool _switcher_showing; + bool _launcher_keynav; bool _show_now_activated; bool _we_control_active; bool _new_app_menu_shown; - int _monitor; - guint32 _active_xid; + int _monitor; + Window _active_xid; + guint32 _active_moved_id; guint32 _update_show_now_id; guint32 _new_app_show_id; @@ -188,8 +177,9 @@ glib::Signal _active_win_changed_signal; glib::Signal _active_app_changed_signal; glib::Signal _view_name_changed_signal; + sigc::connection _style_changed_connection; - std::vector _ubus_interests; + UBusManager _ubus_manager; int _menus_fadein; int _menus_fadeout; @@ -197,10 +187,10 @@ int _menus_discovery_fadein; int _menus_discovery_fadeout; - gchar* _panel_title; + Animator _fade_in_animator; + Animator _fade_out_animator; - Animator* _fade_in_animator; - Animator* _fade_out_animator; + const std::string _desktop_name; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelStyle.cpp unity-5.10.0/plugins/unityshell/src/PanelStyle.cpp --- unity-5.8.0/plugins/unityshell/src/PanelStyle.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelStyle.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -15,12 +15,15 @@ * * Authored by: Mirco Müller * Neil Jagdish Patel + * Marco Trevisan <3v1n0@ubuntu.com> */ #include "config.h" #include #include +#include +#include #include #include @@ -40,7 +43,11 @@ { Style* style_instance = nullptr; -nux::logging::Logger logger("unity.panel"); +nux::logging::Logger logger("unity.panel.style"); + +const std::string METACITY_SETTINGS_PATH("/apps/metacity/general/"); +const std::string PANEL_TITLE_FONT_KEY("/apps/metacity/general/titlebar_font"); +const std::string HIGH_CONTRAST_THEME_PREFIX("HighContrast"); nux::Color ColorFromGdkRGBA(GdkRGBA const& color) { @@ -54,7 +61,7 @@ Style::Style() : panel_height(24) - , _theme_name(NULL) + , _style_context(gtk_style_context_new()) { if (style_instance) { @@ -65,8 +72,6 @@ style_instance = this; } - _style_context = gtk_style_context_new(); - GtkWidgetPath* widget_path = gtk_widget_path_new(); gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_WINDOW); gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget"); @@ -77,23 +82,42 @@ gtk_widget_path_free(widget_path); - _gtk_theme_changed_id = g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", - G_CALLBACK(Style::OnGtkThemeChanged), this); + GtkSettings* settings = gtk_settings_get_default(); + + _style_changed_signal.Connect(settings, "notify::gtk-theme-name", + [&] (GtkSettings*, GParamSpec*) { + Refresh(); + }); + + _font_changed_signal.Connect(settings, "notify::gtk-font-name", + [&] (GtkSettings*, GParamSpec*) { + changed.emit(); + }); + + _dpi_changed_signal.Connect(settings, "notify::gtk-xft-dpi", + [&] (GtkSettings*, GParamSpec*) { + changed.emit(); + }); + + GConfClient* client = gconf_client_get_default(); + gconf_client_add_dir(client, METACITY_SETTINGS_PATH.c_str(), GCONF_CLIENT_PRELOAD_NONE, nullptr); + _gconf_notify_id = gconf_client_notify_add(client, PANEL_TITLE_FONT_KEY.c_str(), + [] (GConfClient*,guint,GConfEntry*, gpointer data) + { + auto self = static_cast(data); + self->changed.emit(); + }, this, nullptr, nullptr); Refresh(); } Style::~Style() { - if (_gtk_theme_changed_id) - g_signal_handler_disconnect(gtk_settings_get_default(), - _gtk_theme_changed_id); - - g_object_unref(_style_context); - g_free(_theme_name); - if (style_instance == this) style_instance = nullptr; + + if (_gconf_notify_id) + gconf_client_notify_remove(gconf_client_get_default(), _gconf_notify_id); } Style& Style::Instance() @@ -106,24 +130,33 @@ return *style_instance; } - void Style::Refresh() { - GdkRGBA rgba_text; + GdkRGBA rgba_text_color; + glib::String theme_name; + bool updated = false; + + GtkSettings* settings = gtk_settings_get_default(); + g_object_get(settings, "gtk-theme-name", &theme_name, nullptr); - if (_theme_name) - g_free(_theme_name); - - _theme_name = NULL; - g_object_get(gtk_settings_get_default(), "gtk-theme-name", &_theme_name, NULL); + if (_theme_name != theme_name.Str()) + { + _theme_name = theme_name.Str(); + updated = true; + } gtk_style_context_invalidate(_style_context); + gtk_style_context_get_color(_style_context, GTK_STATE_FLAG_NORMAL, &rgba_text_color); + nux::Color const& new_text_color = ColorFromGdkRGBA(rgba_text_color); - gtk_style_context_get_color(_style_context, GTK_STATE_FLAG_NORMAL, &rgba_text); - - _text = ColorFromGdkRGBA(rgba_text); + if (_text_color != new_text_color) + { + _text_color = new_text_color; + updated = true; + } - changed.emit(); + if (updated) + changed.emit(); } GtkStyleContext* Style::GetStyleContext() @@ -131,15 +164,6 @@ return _style_context; } -void Style::OnGtkThemeChanged(GObject* gobject, - GParamSpec* pspec, - gpointer data) -{ - Style* self = (Style*) data; - - self->Refresh(); -} - nux::NBitmapData* Style::GetBackground(int width, int height, float opacity) { nux::CairoGraphics context(CAIRO_FORMAT_ARGB32, width, height); @@ -158,8 +182,9 @@ nux::BaseTexture* Style::GetWindowButton(WindowButtonType type, WindowState state) { nux::BaseTexture* texture = NULL; - const char* names[] = { "close", "minimize", "unmaximize" }; - const char* states[] = { "", "_focused_prelight", "_focused_pressed" }; + std::string names[] = { "close", "minimize", "unmaximize", "maximize" }; + std::string states[] = { "", "_focused_prelight", "_focused_pressed", "_unfocused", + "_unfocused", "_unfocused_prelight", "_unfocused_pressed"}; std::ostringstream subpath; subpath << "unity/" << names[static_cast(type)] @@ -169,7 +194,7 @@ const char* home_dir = g_get_home_dir(); if (home_dir) { - glib::String filename(g_build_filename(home_dir, ".themes", _theme_name, subpath.str().c_str(), NULL)); + glib::String filename(g_build_filename(home_dir, ".themes", _theme_name.c_str(), subpath.str().c_str(), NULL)); if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS)) { @@ -191,7 +216,7 @@ if (!var) var = "/usr"; - glib::String filename(g_build_filename(var, "share", "themes", _theme_name, subpath.str().c_str(), NULL)); + glib::String filename(g_build_filename(var, "share", "themes", _theme_name.c_str(), subpath.str().c_str(), NULL)); if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS)) { @@ -215,26 +240,48 @@ nux::BaseTexture* Style::GetFallbackWindowButton(WindowButtonType type, WindowState state) { - int width = 18, height = 18; + int width = 17, height = 17; + int canvas_w = 19, canvas_h = 19; + + if (boost::starts_with(_theme_name, HIGH_CONTRAST_THEME_PREFIX)) + { + width = 20, height = 20; + canvas_w = 22, canvas_h = 22; + } + float w = width / 3.0f; float h = height / 3.0f; - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 22, 22); - cairo_t* cr; - nux::Color main = _text; + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, canvas_w, canvas_h); + nux::Color main = (state != WindowState::UNFOCUSED) ? _text_color : nux::color::Gray; + cairo_t* cr = cairo_graphics.GetContext(); if (type == WindowButtonType::CLOSE) { - main = nux::Color(1.0f, 0.3f, 0.3f, 0.8f); + double alpha = (state != WindowState::UNFOCUSED) ? 0.8f : 0.5; + main = nux::Color(1.0f, 0.3f, 0.3f, alpha); } - if (state == WindowState::PRELIGHT) - main = main * 1.2f; - else if (state == WindowState::PRESSED) - main = main * 0.8f; - else if (state == WindowState::DISABLED) - main = main * 0.5f; + switch (state) + { + case WindowState::PRELIGHT: + main = main * 1.2f; + break; + case WindowState::UNFOCUSED_PRELIGHT: + main = main * 0.9f; + break; + case WindowState::PRESSED: + main = main * 0.8f; + break; + case WindowState::UNFOCUSED_PRESSED: + main = main * 0.7f; + break; + case WindowState::DISABLED: + main = main * 0.5f; + break; + default: + break; + } - cr = cairo_graphics.GetContext(); cairo_translate(cr, 0.5, 0.5); cairo_set_line_width(cr, 1.5f); @@ -278,29 +325,58 @@ } cairo_stroke(cr); - cairo_destroy(cr); return texture_from_cairo_graphics(cairo_graphics); } -GdkPixbuf* Style::GetHomeButton() +glib::Object Style::GetHomeButton() { - GdkPixbuf* pixbuf = NULL; + glib::Object pixbuf; pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), "start-here", - 24, + panel_height, (GtkIconLookupFlags)0, NULL); - if (pixbuf == NULL) + if (!pixbuf) pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), "distributor-logo", - 24, + panel_height, (GtkIconLookupFlags)0, NULL); return pixbuf; } +std::string Style::GetFontDescription(PanelItem item) +{ + switch (item) + { + case PanelItem::INDICATOR: + case PanelItem::MENU: + { + glib::String font_name; + g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, nullptr); + return font_name.Str(); + } + case PanelItem::TITLE: + { + GConfClient* client = gconf_client_get_default(); + glib::String font_name(gconf_client_get_string(client, PANEL_TITLE_FONT_KEY.c_str(), nullptr)); + return font_name.Str(); + } + } + + return ""; +} + +int Style::GetTextDPI() +{ + int dpi = 0; + g_object_get(gtk_settings_get_default(), "gtk-xft-dpi", &dpi, nullptr); + + return dpi; +} + } // namespace panel } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/PanelStyle.h unity-5.10.0/plugins/unityshell/src/PanelStyle.h --- unity-5.8.0/plugins/unityshell/src/PanelStyle.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelStyle.h 2012-04-12 13:21:21.000000000 +0000 @@ -16,6 +16,7 @@ * * Authored by: Mirco Müller * Neil Jagdish Patel + * Marco Trevisan <3v1n0@ubuntu.com> */ #ifndef PANEL_STYLE_H @@ -25,6 +26,8 @@ #include #include +#include +#include namespace unity { @@ -44,7 +47,17 @@ NORMAL, PRELIGHT, PRESSED, - DISABLED + DISABLED, + UNFOCUSED, + UNFOCUSED_PRELIGHT, + UNFOCUSED_PRESSED +}; + +enum class PanelItem +{ + INDICATOR, + MENU, + TITLE }; class Style @@ -56,32 +69,27 @@ static Style& Instance(); GtkStyleContext* GetStyleContext(); - nux::NBitmapData* GetBackground(int width, int height, float opacity); - nux::BaseTexture* GetWindowButton(WindowButtonType type, WindowState state); nux::BaseTexture* GetFallbackWindowButton(WindowButtonType type, WindowState state); + glib::Object GetHomeButton(); + std::string GetFontDescription(PanelItem item); + int GetTextDPI(); - GdkPixbuf* GetHomeButton(); + nux::Property panel_height; sigc::signal changed; - bool IsAmbianceOrRadiance(); - - nux::Property panel_height; - private: void Refresh(); - static void OnGtkThemeChanged(GObject* gobject, - GParamSpec* pspec, - gpointer data); -private: - GtkStyleContext* _style_context; - char* _theme_name; - nux::Color _text; - - gulong _gtk_theme_changed_id; + glib::Object _style_context; + glib::Signal _style_changed_signal; + glib::Signal _font_changed_signal; + glib::Signal _dpi_changed_signal; + guint _gconf_notify_id; + std::string _theme_name; + nux::Color _text_color; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp unity-5.10.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp --- unity-5.8.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-04-12 13:21:21.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 @@ -27,17 +27,41 @@ #include #include +namespace unity +{ +namespace +{ + unsigned int MOUSE_DOWN_TIMEOUT = 150; + unsigned int MOUSE_MOVEMENT_TOLERANCE = 4; +} + PanelTitlebarGrabArea::PanelTitlebarGrabArea() : InputArea(NUX_TRACKER_LOCATION) - , _grab_cursor(None) + , grab_cursor_(None) + , grab_started_(false) + , mouse_down_timer_(0) + , mouse_down_button_(0) { EnableDoubleClick(true); + + mouse_down.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseDown)); + mouse_up.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseUp)); + mouse_drag.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnGrabMove)); + + mouse_double_click.connect([&] (int x, int y, unsigned long button_flags, unsigned long) + { + if (nux::GetEventButton(button_flags) == 1) + restore_request.emit(x, y); + }); } PanelTitlebarGrabArea::~PanelTitlebarGrabArea() { - if (_grab_cursor) - XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), _grab_cursor); + if (grab_cursor_) + XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), grab_cursor_); + + if (mouse_down_timer_) + g_source_remove(mouse_down_timer_); } void PanelTitlebarGrabArea::SetGrabbed(bool enabled) @@ -48,32 +72,120 @@ if (!panel_window || !display) return; - if (enabled && !_grab_cursor) + if (enabled && !grab_cursor_) { - _grab_cursor = XCreateFontCursor(display, XC_fleur); - XDefineCursor(display, panel_window->GetInputWindowId(), _grab_cursor); + grab_cursor_ = XCreateFontCursor(display, XC_fleur); + XDefineCursor(display, panel_window->GetInputWindowId(), grab_cursor_); } - else if (!enabled && _grab_cursor) + else if (!enabled && grab_cursor_) { XUndefineCursor(display, panel_window->GetInputWindowId()); - XFreeCursor(display, _grab_cursor); - _grab_cursor = None; + XFreeCursor(display, grab_cursor_); + grab_cursor_ = None; } } bool PanelTitlebarGrabArea::IsGrabbed() { - return (_grab_cursor != None); + return (grab_cursor_ != None); +} + +void PanelTitlebarGrabArea::OnMouseDown(int x, int y, unsigned long button_flags, unsigned long) +{ + mouse_down_button_ = nux::GetEventButton(button_flags); + + if (mouse_down_button_ == 2) + { + lower_request.emit(x, y); + } + else if (mouse_down_button_ == 1) + { + mouse_down_point_.x = x; + mouse_down_point_.y = y; + + mouse_down_timer_ = + g_timeout_add(MOUSE_DOWN_TIMEOUT, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + + if (!self->grab_started_) + { + nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); + self->grab_started.emit(mouse.x - self->GetAbsoluteX(), mouse.y - self->GetAbsoluteY()); + self->grab_started_ = true; + } + + self->mouse_down_timer_ = 0; + return FALSE; + }, this); + } +} + +void PanelTitlebarGrabArea::OnMouseUp(int x, int y, unsigned long button_flags, unsigned long) +{ + int button = nux::GetEventButton(button_flags); + + if (button == 1) + { + if (mouse_down_timer_) + { + g_source_remove(mouse_down_timer_); + mouse_down_timer_ = 0; + + activate_request.emit(x, y); + } + + if (grab_started_) + { + grab_end.emit(x, y); + grab_started_ = false; + } + } + + mouse_down_button_ = 0; + mouse_down_point_.x = 0; + mouse_down_point_.y = 0; +} + +void PanelTitlebarGrabArea::OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long) +{ + if (mouse_down_button_ != 1) + return; + + if (mouse_down_timer_) + { + if (abs(mouse_down_point_.x - x) <= MOUSE_MOVEMENT_TOLERANCE && + abs(mouse_down_point_.y - y) <= MOUSE_MOVEMENT_TOLERANCE) + { + return; + } + + g_source_remove(mouse_down_timer_); + mouse_down_timer_ = 0; + } + + if (!grab_started_) + { + grab_started.emit(x, y); + grab_started_ = true; + } + else + { + grab_move.emit(x, y); + } } std::string PanelTitlebarGrabArea::GetName() const { - return "panel-titlebar-grab-area"; + return "GrabArea"; } void PanelTitlebarGrabArea::AddProperties(GVariantBuilder* builder) { - unity::variant::BuilderWrapper(builder).add(GetGeometry()); + unity::variant::BuilderWrapper(builder) + .add(GetAbsoluteGeometry()) + .add("grabbed", IsGrabbed()); +} + } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.h unity-5.10.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.h --- unity-5.8.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-04-12 13:21:21.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 @@ -27,10 +27,13 @@ #include "Introspectable.h" +namespace unity +{ + class PanelTitlebarGrabArea : public nux::InputArea, public unity::debug::Introspectable { - /* This acts a bit like a titlebar, it can be grabbed (such that we can pull - * the window down) */ + /* This acts a bit like a decorator, it can be clicked or grabbed (such that + * we can pull the window down) */ public: PanelTitlebarGrabArea(); @@ -39,11 +42,29 @@ void SetGrabbed(bool enabled); bool IsGrabbed(); -private: + sigc::signal lower_request; + sigc::signal activate_request; + sigc::signal restore_request; + sigc::signal grab_started; + sigc::signal grab_move; + sigc::signal grab_end; + +protected: std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void AddProperties(GVariantBuilder* builder); - Cursor _grab_cursor; +private: + void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long); + void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long); + void OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long); + + Cursor grab_cursor_; + bool grab_started_; + guint mouse_down_timer_; + nux::Point mouse_down_point_; + unsigned int mouse_down_button_; }; +} // NAMESPACE + #endif diff -Nru unity-5.8.0/plugins/unityshell/src/PanelTray.cpp unity-5.10.0/plugins/unityshell/src/PanelTray.cpp --- unity-5.8.0/plugins/unityshell/src/PanelTray.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelTray.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Canonical Ltd + * Copyright (C) 2010-2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as @@ -14,11 +14,14 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include "PanelTray.h" +#include "PanelStyle.h" #include +#include namespace { @@ -31,137 +34,122 @@ { PanelTray::PanelTray() - : View(NUX_TRACKER_LOCATION), - _window(0), - _tray(NULL), - _last_x(0), - _last_y(0), - _tray_icon_added_id(0) -{ - _settings = g_settings_new(SETTINGS_NAME.c_str()); - _whitelist = g_settings_get_strv(_settings, "systray-whitelist"); - - RealInit(); -} - -unsigned int -PanelTray::xid () -{ - if (!_window) - return 0; - - return gdk_x11_window_get_xid (gtk_widget_get_window (_window)); -} - -void PanelTray::RealInit() -{ - _window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_type_hint(GTK_WINDOW(_window), GDK_WINDOW_TYPE_HINT_DOCK); - gtk_window_set_has_resize_grip(GTK_WINDOW(_window), FALSE); - gtk_window_set_keep_above(GTK_WINDOW(_window), TRUE); - gtk_window_set_skip_pager_hint(GTK_WINDOW(_window), TRUE); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(_window), TRUE); - gtk_window_resize(GTK_WINDOW(_window), 1, 24); - gtk_window_move(GTK_WINDOW(_window), -24,-24); - gtk_widget_set_name(_window, "UnityPanelApplet"); - - gtk_widget_set_visual(_window, gdk_screen_get_rgba_visual(gdk_screen_get_default())); - gtk_widget_realize(_window); - gtk_widget_set_app_paintable(_window, TRUE); - _tray_expose_id = g_signal_connect(_window, "draw", G_CALLBACK(PanelTray::OnTrayDraw), this); + : View(NUX_TRACKER_LOCATION) + , settings_(g_settings_new(SETTINGS_NAME.c_str())) + , window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)) + , whitelist_(g_settings_get_strv(settings_, "systray-whitelist")) +{ + int panel_height = panel::Style::Instance().panel_height; + + whitelist_changed_.Connect(settings_, "changed::systray-whitelist", [&] (GSettings*, gchar*) { + g_strfreev(whitelist_); + whitelist_ = g_settings_get_strv(settings_, "systray-whitelist"); + }); + + auto gtkwindow = glib::object_cast(window_); + gtk_window_set_type_hint(gtkwindow, GDK_WINDOW_TYPE_HINT_DOCK); + gtk_window_set_has_resize_grip(gtkwindow, FALSE); + gtk_window_set_keep_above(gtkwindow, TRUE); + gtk_window_set_skip_pager_hint(gtkwindow, TRUE); + gtk_window_set_skip_taskbar_hint(gtkwindow, TRUE); + gtk_window_resize(gtkwindow, 1, panel_height); + gtk_window_move(gtkwindow, -panel_height,-panel_height); + gtk_widget_set_name(window_, "UnityPanelApplet"); + + gtk_widget_set_visual(window_, gdk_screen_get_rgba_visual(gdk_screen_get_default())); + gtk_widget_realize(window_); + gtk_widget_set_app_paintable(window_, TRUE); + draw_signal_.Connect(window_, "draw", sigc::mem_fun(this, &PanelTray::OnTrayDraw)); if (!g_getenv("UNITY_PANEL_TRAY_DISABLE")) { - _tray = na_tray_new_for_screen(gdk_screen_get_default(), + tray_ = na_tray_new_for_screen(gdk_screen_get_default(), GTK_ORIENTATION_HORIZONTAL, (NaTrayFilterCallback)FilterTrayCallback, this); - na_tray_set_icon_size(_tray, 24); + na_tray_set_icon_size(tray_, panel_height); - _tray_icon_added_id = g_signal_connect(na_tray_get_manager(_tray), "tray_icon_removed", - G_CALLBACK(PanelTray::OnTrayIconRemoved), this); + icon_removed_signal_.Connect(na_tray_get_manager(tray_), "tray_icon_removed", + sigc::mem_fun(this, &PanelTray::OnTrayIconRemoved)); - gtk_container_add(GTK_CONTAINER(_window), GTK_WIDGET(_tray)); - gtk_widget_show(GTK_WIDGET(_tray)); + gtk_container_add(GTK_CONTAINER(window_.RawPtr()), GTK_WIDGET(tray_.RawPtr())); + gtk_widget_show(GTK_WIDGET(tray_.RawPtr())); } - SetMinMaxSize(1, 24); - + SetMinMaxSize(1, panel_height); } PanelTray::~PanelTray() { - if (_tray) + g_idle_remove_by_data(this); + g_strfreev(whitelist_); + + if (gtk_widget_get_realized(window_)) { - g_signal_handler_disconnect(na_tray_get_manager(_tray), _tray_icon_added_id); - _tray = NULL; + // We call Release since we're deleting the window here manually, + // and we don't want the smart pointer to try and delete it as well. + gtk_widget_destroy(window_.Release()); } +} - g_idle_remove_by_data(this); - - if (_tray_expose_id) - g_signal_handler_disconnect(_window, _tray_expose_id); +Window PanelTray::xid() +{ + if (!window_) + return 0; - gtk_widget_destroy(_window); - g_strfreev(_whitelist); - g_object_unref(_settings); + return gdk_x11_window_get_xid(gtk_widget_get_window(window_)); } -void -PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw) +void PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw) { - nux::Geometry geo(GetAbsoluteGeometry()); + nux::Geometry const& geo = GetAbsoluteGeometry(); gfx_context.PushClippingRectangle(geo); nux::GetPainter().PaintBackground(gfx_context, geo); gfx_context.PopClippingRectangle(); - if (geo.x != _last_x || geo.y != _last_y) + if (geo != last_geo_) { - _last_x = geo.x; - _last_y = geo.y; - - gtk_window_move(GTK_WINDOW(_window), geo.x + PADDING, geo.y); + last_geo_ = geo; + gtk_window_move(GTK_WINDOW(window_.RawPtr()), geo.x + PADDING, geo.y); } } -void -PanelTray::Sync() +void PanelTray::Sync() { - if (_tray) + if (tray_) { - SetMinMaxSize(WidthOfTray() + (PADDING * 2), 24); + SetMinMaxSize(WidthOfTray() + (PADDING * 2), panel::Style::Instance().panel_height); QueueRelayout(); QueueDraw(); - if (_children.size()) - gtk_widget_show(_window); + if (!children_.empty()) + gtk_widget_show(window_); else - gtk_widget_hide(_window); + gtk_widget_hide(window_); } } -gboolean -PanelTray::FilterTrayCallback(NaTray* tray, NaTrayChild* icon, PanelTray* self) +gboolean PanelTray::FilterTrayCallback(NaTray* tray, NaTrayChild* icon, PanelTray* self) { - char* title; - char* res_name = NULL; - char* res_class = NULL; - char* name; - int i = 0; - bool accept = false; + int i = 0; + bool accept = false; + const char *name = nullptr; + + glib::String title(na_tray_child_get_title(icon)); - title = na_tray_child_get_title(icon); + glib::String res_class; + glib::String res_name; na_tray_child_get_wm_class(icon, &res_name, &res_class); - while ((name = self->_whitelist[i])) + while ((name = self->whitelist_[i])) { if (g_strcmp0(name, "all") == 0) { accept = true; break; } - else if (!name || g_strcmp0(name, "") == 0) + else if (!name || name[0] == '\0') { accept = false; break; @@ -182,7 +170,7 @@ if (na_tray_child_has_alpha(icon)) na_tray_child_set_composited(icon, TRUE); - self->_children.push_back(icon); + self->children_.push_back(icon); g_idle_add((GSourceFunc)IdleSync, self); } @@ -191,32 +179,26 @@ << na_tray_child_get_title(icon) << " " << res_name << " " << res_class; - g_free(res_name); - g_free(res_class); - g_free(title); - return accept ? TRUE : FALSE; } -void -PanelTray::OnTrayIconRemoved(NaTrayManager* manager, NaTrayChild* child, PanelTray* self) +void PanelTray::OnTrayIconRemoved(NaTrayManager* manager, NaTrayChild* removed) { - for (auto it = self->_children.begin(); it != self->_children.end(); ++it) + for (auto child : children_) { - if (*it == child) + if (child == removed) { - g_idle_add((GSourceFunc)IdleSync, self); - self->_children.erase(it); + g_idle_add((GSourceFunc)IdleSync, this); + children_.remove(child); break; } } } -gboolean -PanelTray::IdleSync(PanelTray* self) +gboolean PanelTray::IdleSync(PanelTray* self) { int width = self->WidthOfTray(); - gtk_window_resize(GTK_WINDOW(self->_window), width, 24); + gtk_window_resize(GTK_WINDOW(self->window_.RawPtr()), width, panel::Style::Instance().panel_height); self->Sync(); return FALSE; } @@ -224,7 +206,7 @@ int PanelTray::WidthOfTray() { int width = 0; - for (auto child: _children) + for (auto child: children_) { int w = gtk_widget_get_allocated_width(GTK_WIDGET(child)); width += w > 24 ? w : 24; @@ -232,8 +214,7 @@ return width; } -gboolean -PanelTray::OnTrayDraw(GtkWidget* widget, cairo_t* cr, PanelTray* tray) +gboolean PanelTray::OnTrayDraw(GtkWidget* widget, cairo_t* cr) { GtkAllocation alloc; @@ -254,16 +235,16 @@ return FALSE; } -std::string -PanelTray::GetName() const +std::string PanelTray::GetName() const { - return "PanelTray"; + return "Tray"; } -void -PanelTray::AddProperties(GVariantBuilder* builder) +void PanelTray::AddProperties(GVariantBuilder* builder) { - + variant::BuilderWrapper(builder) + .add(GetAbsoluteGeometry()) + .add("children_count", children_.size()); } } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/PanelTray.h unity-5.10.0/plugins/unityshell/src/PanelTray.h --- unity-5.8.0/plugins/unityshell/src/PanelTray.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelTray.h 2012-04-12 13:21:21.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Canonical Ltd + * Copyright (C) 2010-2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as @@ -14,18 +14,20 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #ifndef PANEL_TRAY_H #define PANEL_TRAY_H #include +#include #include - #include -#include #include "Introspectable.h" +#include +#include #include #include @@ -37,40 +39,35 @@ class PanelTray : public nux::View, public unity::debug::Introspectable { public: - typedef std::vector TrayChildren; PanelTray(); ~PanelTray(); - void Draw(nux::GraphicsEngine& gfx_content, bool force_draw); void Sync(); + Window xid(); - unsigned int xid (); - -public: - char** _whitelist; protected: + void Draw(nux::GraphicsEngine& gfx_content, bool force_draw); std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void AddProperties(GVariantBuilder* builder); private: static gboolean FilterTrayCallback(NaTray* tray, NaTrayChild* child, PanelTray* self); - static void OnTrayIconRemoved(NaTrayManager* manager, NaTrayChild* child, PanelTray* self); static gboolean IdleSync(PanelTray* tray); - static gboolean OnTrayDraw(GtkWidget* widget, cairo_t* cr, PanelTray* tray); - - void RealInit(); - int WidthOfTray(); + void OnTrayIconRemoved(NaTrayManager* manager, NaTrayChild* child); + gboolean OnTrayDraw(GtkWidget* widget, cairo_t* cr); -private: - GSettings* _settings; - GtkWidget* _window; - NaTray* _tray; - TrayChildren _children; - int _last_x; - int _last_y; + int WidthOfTray(); - gulong _tray_expose_id; - gulong _tray_icon_added_id; + glib::Object settings_; + glib::Object window_; + glib::Object tray_; + char** whitelist_; + + glib::Signal whitelist_changed_; + glib::Signal draw_signal_; + glib::Signal icon_removed_signal_; + std::list children_; + nux::Geometry last_geo_; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/PanelView.cpp unity-5.10.0/plugins/unityshell/src/PanelView.cpp --- unity-5.8.0/plugins/unityshell/src/PanelView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelView.cpp 2012-04-12 13:21:21.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 @@ -15,6 +15,7 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include @@ -37,7 +38,6 @@ #include "PanelIndicatorsView.h" #include -#include "ubus-server.h" #include "UBusMessages.h" #include "PanelView.h" @@ -53,35 +53,34 @@ NUX_IMPLEMENT_OBJECT_TYPE(PanelView); PanelView::PanelView(NUX_FILE_LINE_DECL) - : View(NUX_FILE_LINE_PARAM), - _last_width(0), - _last_height(0), - _is_dirty(true), - _opacity(1.0f), - _opacity_maximized_toggle(false), - _is_primary(false), - _monitor(0), - _overlay_is_open(false) + : View(NUX_FILE_LINE_PARAM) + , _is_dirty(true) + , _opacity_maximized_toggle(false) + , _needs_geo_sync(false) + , _is_primary(false) + , _overlay_is_open(false) + , _opacity(1.0f) + , _monitor(0) { - _needs_geo_sync = false; panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelView::ForceUpdateBackground)); - _bg_layer = new nux::ColorLayer(nux::Color(0xff595853), true); + _bg_layer.reset(new nux::ColorLayer(nux::Color(0xff595853), true)); nux::ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_ZERO; rop.DstBlend = GL_SRC_COLOR; - _bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.9f, 0.9f, 0.9f, 1.0f), false, rop); + + _bg_darken_layer.reset(new nux::ColorLayer(nux::Color(0.9f, 0.9f, 0.9f, 1.0f), false, rop)); _layout = new nux::HLayout("", NUX_TRACKER_LOCATION); + _layout->SetContentDistribution(nux::eStackLeft); _menu_view = new PanelMenuView(); AddPanelView(_menu_view, 1); SetCompositionLayout(_layout); - // Pannel tray shouldn't be an indicator view _tray = new PanelTray(); _layout->AddView(_tray, 0, nux::eCenter, nux::eFull); AddChild(_tray); @@ -94,43 +93,29 @@ _remote->on_object_removed.connect(sigc::mem_fun(this, &PanelView::OnObjectRemoved)); _remote->on_entry_activate_request.connect(sigc::mem_fun(this, &PanelView::OnEntryActivateRequest)); _remote->on_entry_activated.connect(sigc::mem_fun(this, &PanelView::OnEntryActivated)); - _remote->on_synced.connect(sigc::mem_fun(this, &PanelView::OnSynced)); _remote->on_entry_show_menu.connect(sigc::mem_fun(this, &PanelView::OnEntryShowMenu)); - UBusServer *ubus = ubus_server_get_default(); + _ubus_manager.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &PanelView::OnBackgroundUpdate)); + _ubus_manager.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &PanelView::OnOverlayHidden)); + _ubus_manager.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &PanelView::OnOverlayShown)); - _handle_bg_color_update = ubus_server_register_interest(ubus, UBUS_BACKGROUND_COLOR_CHANGED, - (UBusCallback)&PanelView::OnBackgroundUpdate, - this); - - _handle_dash_hidden = ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN, - (UBusCallback)&PanelView::OnDashHidden, - this); - - _handle_dash_shown = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN, - (UBusCallback)&PanelView::OnDashShown, - this); - // request the latest colour from bghash - ubus_server_send_message (ubus, UBUS_BACKGROUND_REQUEST_COLOUR_EMIT, NULL); + // request the latest colour from bghash + _ubus_manager.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT); _track_menu_pointer_id = 0; - bg_effect_helper_.owner = this; + _bg_effect_helper.owner = this; //FIXME (gord)- replace with async loading glib::Object pixbuf; glib::Error error; - pixbuf = gdk_pixbuf_new_from_file(PKGDATADIR"/dash_sheen.png", &error); + pixbuf = gdk_pixbuf_new_from_file(PKGDATADIR "/dash_sheen.png", &error); if (error) { LOG_WARN(logger) << "Unable to texture " << PKGDATADIR << "/dash_sheen.png" << ": " << error; } else { - _panel_sheen = nux::CreateTexture2DFromPixbuf(pixbuf, true); - // TODO: when nux has the ability to create a smart pointer that takes - // ownership without adding a reference, we can remove the unref here. By - // unreferencing, the object is solely owned by the smart pointer. - _panel_sheen->UnReference(); + _panel_sheen.Adopt(nux::CreateTexture2DFromPixbuf(pixbuf, true)); } } @@ -138,10 +123,6 @@ { if (_track_menu_pointer_id) g_source_remove(_track_menu_pointer_id); - UBusServer *ubus = ubus_server_get_default(); - ubus_server_unregister_interest(ubus, _handle_bg_color_update); - ubus_server_unregister_interest(ubus, _handle_dash_hidden); - ubus_server_unregister_interest(ubus, _handle_dash_shown); for (auto conn : _on_indicator_updated_connections) conn.disconnect(); @@ -151,27 +132,30 @@ indicator::EntryLocationMap locations; _remote->SyncGeometries(GetName() + boost::lexical_cast(_monitor), locations); - - delete _bg_layer; } -unsigned int PanelView::GetTrayXid () +Window PanelView::GetTrayXid() const { if (!_tray) return 0; - return _tray->xid (); + return _tray->xid(); } -void PanelView::OnBackgroundUpdate (GVariant *data, PanelView *self) +void PanelView::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); - self->ForceUpdateBackground(); + + _bg_color.red = red; + _bg_color.green = green; + _bg_color.blue = blue; + _bg_color.alpha = alpha; + + ForceUpdateBackground(); } -void PanelView::OnDashHidden(GVariant* data, PanelView* self) +void PanelView::OnOverlayHidden(GVariant* data) { unity::glib::String overlay_identity; gboolean can_maximise = FALSE; @@ -179,19 +163,20 @@ 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 (_monitor == overlay_monitor && overlay_identity.Str() == _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(); + if (_opacity >= 1.0f) + _bg_effect_helper.enabled = false; + + _overlay_is_open = false; + _active_overlay = ""; + _menu_view->OverlayHidden(); + _indicators->OverlayHidden(); + ForceUpdateBackground(); } } -void PanelView::OnDashShown(GVariant* data, PanelView* self) +void PanelView::OnOverlayShown(GVariant* data) { unity::glib::String overlay_identity; gboolean can_maximise = FALSE; @@ -199,13 +184,14 @@ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); - if (self->_monitor == overlay_monitor) + if (_monitor == overlay_monitor) { - self->bg_effect_helper_.enabled = true; - self->_overlay_is_open = true; - self->_active_overlay = overlay_identity.Str(); - self->_indicators->DashShown(); - self->ForceUpdateBackground(); + _bg_effect_helper.enabled = true; + _active_overlay = overlay_identity.Str(); + _overlay_is_open = true; + _indicators->OverlayShown(); + _menu_view->OverlayShown(); + ForceUpdateBackground(); } } @@ -227,7 +213,9 @@ { variant::BuilderWrapper(builder) .add("backend", "remote") - .add(GetGeometry()); + .add("monitor", _monitor) + .add("active", IsActive()) + .add(GetAbsoluteGeometry()); } void @@ -239,18 +227,26 @@ GfxContext.PushClippingRectangle(GetGeometry()); - if (BackgroundEffectHelper::blur_type != BLUR_NONE && (_overlay_is_open || (_opacity != 1.0f && _opacity != 0.0f))) + if ((_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 && (_overlay_is_open || _opacity != 1.0f)) + if (BackgroundEffectHelper::blur_type != BLUR_NONE) + { + _bg_blur_texture = _bg_effect_helper.GetBlurRegion(blur_geo); + } + else + { + _bg_blur_texture = _bg_effect_helper.GetRegion(blur_geo); + } + + if (_bg_blur_texture.IsValid() && (_overlay_is_open || _opacity != 1.0f)) { nux::TexCoordXForm texxform_blur_bg; texxform_blur_bg.flip_v_coord = true; texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform_blur_bg.uoffset = ((float) geo.x) / geo_absolute.width; - texxform_blur_bg.voffset = ((float) geo.y) / geo_absolute.height; + texxform_blur_bg.uoffset = geo.x / static_cast(geo_absolute.width); + texxform_blur_bg.voffset = geo.y / static_cast(geo_absolute.height); nux::ROPConfig rop; rop.Blend = false; @@ -263,7 +259,7 @@ #ifndef NUX_OPENGLES_20 if (GfxContext.UsingGLSLCodePath()) gPainter.PushDrawCompositionLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, _bg_color, @@ -271,14 +267,14 @@ true, rop); else gPainter.PushDrawTextureLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, true, rop); #else gPainter.PushDrawCompositionLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, _bg_color, @@ -291,14 +287,12 @@ if (_overlay_is_open) { - nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_darken_layer_); + nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_darken_layer.get()); } } - - - if (_overlay_is_open == false) - nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_layer); + if (!_overlay_is_open) + nux::GetPainter().RenderSinglePaintLayer(GfxContext, GetGeometry(), _bg_layer.get()); GfxContext.PopClippingRectangle(); @@ -312,7 +306,7 @@ void PanelView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::Geometry geo = GetGeometry(); + nux::Geometry const& geo = GetGeometry(); int bgs = 1; GfxContext.PushClippingRectangle(GetGeometry()); @@ -320,14 +314,15 @@ GfxContext.GetRenderStates().SetBlend(true); GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - if (bg_blur_texture_.IsValid() && BackgroundEffectHelper::blur_type != BLUR_NONE && (_overlay_is_open || (_opacity != 1.0f && _opacity != 0.0f))) + if (_bg_blur_texture.IsValid() && + (_overlay_is_open || (_opacity != 1.0f && _opacity != 0.0f))) { nux::Geometry geo_absolute = GetAbsoluteGeometry (); nux::TexCoordXForm texxform_blur_bg; texxform_blur_bg.flip_v_coord = true; texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform_blur_bg.uoffset = ((float) geo.x) / geo_absolute.width; - texxform_blur_bg.voffset = ((float) geo.y) / geo_absolute.height; + texxform_blur_bg.uoffset = geo.x / static_cast(geo_absolute.width); + texxform_blur_bg.voffset = geo.y / static_cast(geo_absolute.height); nux::ROPConfig rop; rop.Blend = false; @@ -337,7 +332,7 @@ #ifndef NUX_OPENGLES_20 if (GfxContext.UsingGLSLCodePath()) gPainter.PushCompositionLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, _bg_color, @@ -346,15 +341,15 @@ rop); else gPainter.PushTextureLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, true, rop); - + #else gPainter.PushCompositionLayer(GfxContext, geo, - bg_blur_texture_, + _bg_blur_texture, texxform_blur_bg, nux::color::White, _bg_color, @@ -366,13 +361,13 @@ if (_overlay_is_open) { - nux::GetPainter().PushLayer(GfxContext, GetGeometry(), _bg_darken_layer_); + nux::GetPainter().PushLayer(GfxContext, GetGeometry(), _bg_darken_layer.get()); bgs++; } } - if (_overlay_is_open == FALSE) - gPainter.PushLayer(GfxContext, GetGeometry(), _bg_layer); + if (!_overlay_is_open) + gPainter.PushLayer(GfxContext, GetGeometry(), _bg_layer.get()); if (_overlay_is_open) { @@ -401,46 +396,33 @@ } void -PanelView::PreLayoutManagement() -{ - nux::View::PreLayoutManagement(); -} - -long -PanelView::PostLayoutManagement(long LayoutResult) -{ - return nux::View::PostLayoutManagement(LayoutResult); -} - -void PanelView::UpdateBackground() { - nux::Geometry geo = GetGeometry(); + nux::Geometry const& geo = GetGeometry(); - if (!_is_dirty && geo.width == _last_width && geo.height == _last_height) + if (!_is_dirty && geo == _last_geo) return; - _last_width = geo.width; - _last_height = geo.height; + _last_geo = geo; _is_dirty = false; - + guint32 maximized_win = _menu_view->GetMaximizedWindow(); if (_overlay_is_open) { - if (_bg_layer) - delete _bg_layer; nux::ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - _bg_layer = new nux::ColorLayer (_bg_color, true, rop); + _bg_layer.reset(new nux::ColorLayer (_bg_color, true, rop)); } else { + WindowManager* wm = WindowManager::Default(); double opacity = _opacity; - if (_opacity_maximized_toggle && maximized_win != 0 && - !WindowManager::Default()->IsWindowObscured(maximized_win)) + + if (_opacity_maximized_toggle && (wm->IsExpoActive() || + (maximized_win != 0 && !wm->IsWindowObscured(maximized_win)))) { opacity = 1.0f; } @@ -454,8 +436,6 @@ nux::TexCoordXForm texxform; texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); - if (_bg_layer) - delete _bg_layer; nux::ROPConfig rop; rop.Blend = true; @@ -463,11 +443,11 @@ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; nux::Color col = nux::color::White; - _bg_layer = new nux::TextureLayer(texture2D->GetDeviceTexture(), + _bg_layer.reset(new nux::TextureLayer(texture2D->GetDeviceTexture(), texxform, col, true, - rop); + rop)); texture2D->UnReference(); } @@ -501,8 +481,6 @@ _indicators->AddIndicator(proxy); } - _layout->SetContentDistribution(nux::eStackLeft); - ComputeContentSize(); NeedRedraw(); } @@ -518,8 +496,6 @@ _indicators->RemoveIndicator(proxy); } - _layout->SetContentDistribution(nux::eStackLeft); - ComputeContentSize(); NeedRedraw(); } @@ -532,13 +508,13 @@ void PanelView::OnMenuPointerMoved(int x, int y) { - nux::Geometry geo = GetAbsoluteGeometry(); + nux::Geometry const& geo = GetAbsoluteGeometry(); if (geo.IsPointInside(x, y)) { PanelIndicatorEntryView* view = nullptr; - if (!_menu_view->HasOurWindowFocused()) + if (_menu_view->GetControlsActive()) view = _menu_view->ActivateEntryAt(x, y); if (!view) _indicators->ActivateEntryAt(x, y); @@ -553,13 +529,13 @@ void PanelView::OnEntryActivateRequest(std::string const& entry_id) { - if (!_menu_view->GetControlsActive()) + if (!IsActive()) return; bool ret; - ret = _menu_view->ActivateEntry(entry_id); - if (!ret) _indicators->ActivateEntry(entry_id); + ret = _menu_view->ActivateEntry(entry_id, 0); + if (!ret) _indicators->ActivateEntry(entry_id, 0); } void PanelView::TrackMenuPointer() @@ -572,12 +548,6 @@ } } -static gboolean track_menu_pointer(PanelView *self) -{ - self->TrackMenuPointer(); - return TRUE; -} - void PanelView::OnEntryActivated(std::string const& entry_id, nux::Rect const& geo) { bool active = (entry_id.size() > 0); @@ -593,7 +563,11 @@ // process. All the motion events will go to unity-panel-service while // scrubbing because the active panel menu has (needs) the pointer grab. // - _track_menu_pointer_id = g_timeout_add(16, (GSourceFunc) track_menu_pointer, this); + _track_menu_pointer_id = g_timeout_add(16, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + self->TrackMenuPointer(); + return TRUE; + }, this); } else if (!active) { @@ -602,16 +576,11 @@ g_source_remove(_track_menu_pointer_id); _track_menu_pointer_id = 0; } - _menu_view->AllMenusClosed(); + _menu_view->NotifyAllMenusClosed(); _tracked_pointer_pos = {-1, -1}; } - ubus_server_send_message(ubus_server_get_default(), UBUS_PLACE_VIEW_CLOSE_REQUEST, NULL); -} - -void PanelView::OnSynced() -{ - _needs_geo_sync = true; + _ubus_manager.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); } void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned int xid, @@ -649,11 +618,12 @@ // // Useful Public Methods // -bool PanelView::FirstMenuShow() + +bool PanelView::FirstMenuShow() const { bool ret = false; - if (!_menu_view->GetControlsActive()) + if (!IsActive()) return ret; ret = _menu_view->ActivateIfSensitive(); @@ -662,28 +632,24 @@ return ret; } -void -PanelView::SetOpacity(float opacity) +void PanelView::SetOpacity(float opacity) { if (_opacity == opacity) return; _opacity = opacity; - - bg_effect_helper_.enabled = (_opacity < 1.0f || _overlay_is_open); + _bg_effect_helper.enabled = (_opacity < 1.0f || _overlay_is_open); ForceUpdateBackground(); } -void -PanelView::SetMenuShowTimings(int fadein, int fadeout, int discovery, - int discovery_fadein, int discovery_fadeout) +void PanelView::SetMenuShowTimings(int fadein, int fadeout, int discovery, + int discovery_fadein, int discovery_fadeout) { _menu_view->SetMenuShowTimings(fadein, fadeout, discovery, discovery_fadein, discovery_fadeout); } -void -PanelView::SetOpacityMaximizedToggle(bool enabled) +void PanelView::SetOpacityMaximizedToggle(bool enabled) { if (_opacity_maximized_toggle != enabled) { @@ -699,6 +665,10 @@ conn->push_back(win_manager->window_restored.connect(update_bg_lambda)); conn->push_back(win_manager->window_mapped.connect(update_bg_lambda)); conn->push_back(win_manager->window_unmapped.connect(update_bg_lambda)); + conn->push_back(win_manager->initiate_expo.connect( + sigc::mem_fun(this, &PanelView::ForceUpdateBackground))); + conn->push_back(win_manager->terminate_expo.connect( + sigc::mem_fun(this, &PanelView::ForceUpdateBackground))); conn->push_back(win_manager->compiz_screen_viewport_switch_ended.connect( sigc::mem_fun(this, &PanelView::ForceUpdateBackground))); } @@ -715,20 +685,17 @@ } } -bool -PanelView::GetPrimary() +bool PanelView::GetPrimary() const { return _is_primary; } -void -PanelView::SetPrimary(bool primary) +void PanelView::SetPrimary(bool primary) { _is_primary = primary; } -void -PanelView::SyncGeometries() +void PanelView::SyncGeometries() { indicator::EntryLocationMap locations; std::string panel_id = GetName() + boost::lexical_cast(_monitor); @@ -740,11 +707,20 @@ _remote->SyncGeometries(panel_id, locations); } -void -PanelView::SetMonitor(int monitor) +void PanelView::SetMonitor(int monitor) { _monitor = monitor; _menu_view->SetMonitor(monitor); } +int PanelView::GetMonitor() const +{ + return _monitor; +} + +bool PanelView::IsActive() const +{ + return _menu_view->GetControlsActive(); +} + } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/PanelView.h unity-5.10.0/plugins/unityshell/src/PanelView.h --- unity-5.8.0/plugins/unityshell/src/PanelView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PanelView.h 2012-04-12 13:21:21.000000000 +0000 @@ -21,6 +21,7 @@ #define PANEL_VIEW_H #include +#include #include #include @@ -35,6 +36,7 @@ #include "PanelMenuView.h" #include "PanelTray.h" #include "PanelIndicatorsView.h" +#include "UBusWrapper.h" namespace unity { @@ -46,88 +48,84 @@ PanelView(NUX_FILE_LINE_PROTO); ~PanelView(); - void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); - void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); - - void PreLayoutManagement(); - long PostLayoutManagement(long LayoutResult); - - void OnObjectAdded(indicator::Indicator::Ptr const& proxy); - void OnObjectRemoved(indicator::Indicator::Ptr const& proxy); - void OnIndicatorViewUpdated(PanelIndicatorEntryView* view); - void OnMenuPointerMoved(int x, int y); - void OnEntryActivateRequest(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, unsigned int xid, int x, int y, - unsigned int button, unsigned int timestamp); - void SetPrimary(bool primary); - bool GetPrimary(); + bool GetPrimary() const; + void SetMonitor(int monitor); + int GetMonitor() const; - bool FirstMenuShow(); + bool IsActive() const; + bool FirstMenuShow() const; void SetOpacity(float opacity); void SetOpacityMaximizedToggle(bool enabled); void SetMenuShowTimings(int fadein, int fadeout, int discovery, int discovery_fadein, int discovery_fadeout); - void TrackMenuPointer(); - - unsigned int GetTrayXid (); + Window GetTrayXid() const; protected: + void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + // Introspectable methods std::string GetName() const; void AddProperties(GVariantBuilder* builder); + void OnObjectAdded(indicator::Indicator::Ptr const& proxy); + void OnObjectRemoved(indicator::Indicator::Ptr const& proxy); + void OnIndicatorViewUpdated(PanelIndicatorEntryView* view); + void OnMenuPointerMoved(int x, int y); + void OnEntryActivateRequest(std::string const& entry_id); + void OnEntryActivated(std::string const& entry_id, nux::Rect const& geo); + void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, int x, int y, + unsigned int button, unsigned int timestamp); + private: - static void OnBackgroundUpdate (GVariant *data, PanelView *self); - static void OnDashShown (GVariant *data, PanelView *self); - static void OnDashHidden (GVariant *data, PanelView *self); + void OnBackgroundUpdate(GVariant *data); + void OnOverlayShown(GVariant *data); + void OnOverlayHidden(GVariant *data); void UpdateBackground(); void ForceUpdateBackground(); + void TrackMenuPointer(); void SyncGeometries(); void AddPanelView(PanelIndicatorsView* child, unsigned int stretchFactor); -private: - typedef nux::ObjectPtr BaseTexturePtr; indicator::DBusIndicators::Ptr _remote; - // No ownership is taken for these views, that is done by the AddChild method. - PanelMenuView* _menu_view; - PanelTray* _tray; - PanelIndicatorsView* _indicators; - nux::AbstractPaintLayer* _bg_layer; - nux::ColorLayer* _bg_darken_layer_; - BaseTexturePtr _panel_sheen; - nux::HLayout* _layout; + // No ownership is taken for these views, that is done by the AddChild method. + PanelMenuView* _menu_view; + PanelTray* _tray; + PanelIndicatorsView* _indicators; + + typedef std::unique_ptr PaintLayerPtr; + PaintLayerPtr _bg_layer; + PaintLayerPtr _bg_darken_layer; + nux::ObjectPtr _panel_sheen; + nux::HLayout* _layout; - int _last_width; - int _last_height; + nux::Geometry _last_geo; nux::Color _bg_color; bool _is_dirty; - float _opacity; bool _opacity_maximized_toggle; bool _needs_geo_sync; bool _is_primary; + bool _overlay_is_open; + float _opacity; int _monitor; - bool _overlay_is_open; std::string _active_overlay; - guint _handle_dash_hidden; - guint _handle_dash_shown; - guint _handle_bg_color_update; + guint _track_menu_pointer_id; nux::Point _tracked_pointer_pos; std::vector _on_indicator_updated_connections; std::vector _maximized_opacity_toggle_connections; - BackgroundEffectHelper bg_effect_helper_; - nux::ObjectPtr bg_blur_texture_; + BackgroundEffectHelper _bg_effect_helper; + nux::ObjectPtr _bg_blur_texture; + UBusManager _ubus_manager; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/PlacesGroup.cpp unity-5.10.0/plugins/unityshell/src/PlacesGroup.cpp --- unity-5.8.0/plugins/unityshell/src/PlacesGroup.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PlacesGroup.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -426,8 +426,6 @@ nux::Geometry const& base = GetGeometry(); graphics_engine.PushClippingRectangle(base); - nux::GetPainter().PaintBackground(graphics_engine, base); - if (ShouldBeHighlighted()) { nux::Geometry geo(_header_layout->GetGeometry()); diff -Nru unity-5.8.0/plugins/unityshell/src/PlacesSimpleTile.cpp unity-5.10.0/plugins/unityshell/src/PlacesSimpleTile.cpp --- unity-5.8.0/plugins/unityshell/src/PlacesSimpleTile.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PlacesSimpleTile.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -37,23 +37,19 @@ { NUX_IMPLEMENT_OBJECT_TYPE(PlacesSimpleTile); -PlacesSimpleTile::PlacesSimpleTile(const char* icon_name, - const char* label, +PlacesSimpleTile::PlacesSimpleTile(std::string const& icon_name, + std::string const& label, int icon_size, bool defer_icon_loading, const void* id) : PlacesTile(NUX_TRACKER_LOCATION, id), - _label(NULL), - _icon(NULL), - _uri(NULL), + _label(label), + _icon(icon_name), _idealiconsize(icon_size) { dash::Style& style = dash::Style::Instance(); nux::VLayout* layout = new nux::VLayout("", NUX_TRACKER_LOCATION); - _label = g_strdup(label); - _icon = g_strdup(icon_name); - _icontex = new IconTexture(_icon, icon_size, defer_icon_loading); _icontex->SetMinMaxSize(style.GetTileWidth(), icon_size); AddChild(_icontex); @@ -76,14 +72,6 @@ SetDndEnabled(true, false); } - -PlacesSimpleTile::~PlacesSimpleTile() -{ - g_free(_label); - g_free(_icon); - g_free(_uri); -} - bool PlacesSimpleTile::DndSourceDragBegin() { @@ -104,14 +92,14 @@ GError* error = NULL; GIcon* icon; - const char* icon_name = _icon; + std::string icon_name = _icon; int size = 64; - if (!icon_name) + if (icon_name.empty()) icon_name = "application-default-icon"; theme = gtk_icon_theme_get_default(); - icon = g_icon_new_for_string(icon_name, NULL); + icon = g_icon_new_for_string(icon_name.c_str(), NULL); if (G_IS_ICON(icon)) { @@ -121,7 +109,7 @@ else { info = gtk_icon_theme_lookup_icon(theme, - icon_name, + icon_name.c_str(), size, (GtkIconLookupFlags) 0); } @@ -155,23 +143,21 @@ return result; } -std::list -PlacesSimpleTile::DndSourceGetDragTypes() +std::list PlacesSimpleTile::DndSourceGetDragTypes() { std::list result; result.push_back("text/uri-list"); return result; } -const char* -PlacesSimpleTile::DndSourceGetDataForType(const char* type, int* size, int* format) +const char* PlacesSimpleTile::DndSourceGetDataForType(const char* type, int* size, int* format) { *format = 8; - if (_uri) + if (!_uri.empty()) { - *size = strlen(_uri); - return _uri; + *size = _uri.size(); + return _uri.c_str(); } else { @@ -180,14 +166,12 @@ } } -void -PlacesSimpleTile::DndSourceDragFinished(nux::DndAction result) +void PlacesSimpleTile::DndSourceDragFinished(nux::DndAction result) { UnReference(); } -nux::Geometry -PlacesSimpleTile::GetHighlightGeometry() +nux::Geometry PlacesSimpleTile::GetHighlightGeometry() { nux::Geometry base = GetGeometry(); int width = 0, height = 0; @@ -202,50 +186,37 @@ return _highlight_geometry; } -const char* -PlacesSimpleTile::GetLabel() +std::string PlacesSimpleTile::GetLabel() const { return _label; } -const char* -PlacesSimpleTile::GetIcon() +std::string PlacesSimpleTile::GetIcon() const { return _icon; } -const char* -PlacesSimpleTile::GetURI() +std::string PlacesSimpleTile::GetURI() const { return _uri; } -void -PlacesSimpleTile::SetURI(const char* uri) +void PlacesSimpleTile::SetURI(std::string const& uri) { - if (_uri) - g_free(_uri); - - _uri = NULL; - - if (uri) - _uri = g_strdup(uri); + _uri = uri; } -std::string -PlacesSimpleTile::GetName() const +std::string PlacesSimpleTile::GetName() const { return "PlacesTile"; } -void -PlacesSimpleTile::AddProperties(GVariantBuilder* builder) +void PlacesSimpleTile::AddProperties(GVariantBuilder* builder) { unity::variant::BuilderWrapper(builder).add(GetGeometry()); } -void -PlacesSimpleTile::LoadIcon() +void PlacesSimpleTile::LoadIcon() { _icontex->LoadIcon(); diff -Nru unity-5.8.0/plugins/unityshell/src/PlacesSimpleTile.h unity-5.10.0/plugins/unityshell/src/PlacesSimpleTile.h --- unity-5.8.0/plugins/unityshell/src/PlacesSimpleTile.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PlacesSimpleTile.h 2012-04-12 13:21:21.000000000 +0000 @@ -35,13 +35,12 @@ NUX_DECLARE_OBJECT_TYPE(PlacesSimpleTile, PlacesTile); public: - PlacesSimpleTile(const char* icon, const char* label, int icon_size = 64, bool defer_icon_loading = false, const void* id = NULL); - ~PlacesSimpleTile(); + PlacesSimpleTile(std::string const& icon, std::string const& label, int icon_size = 64, bool defer_icon_loading = false, const void* id = NULL); - const char* GetLabel(); - const char* GetIcon(); - const char* GetURI(); - void SetURI(const char* uri); + std::string GetLabel() const; + std::string GetIcon() const; + std::string GetURI() const; + void SetURI(std::string const& uri); void LoadIcon(); @@ -59,9 +58,9 @@ private: nux::Geometry _highlight_geometry; - char* _label; - char* _icon; - char* _uri; + std::string _label; + std::string _icon; + std::string _uri; int _idealiconsize; IconTexture* _icontex; nux::StaticCairoText* _cairotext; diff -Nru unity-5.8.0/plugins/unityshell/src/PluginAdapter.cpp unity-5.10.0/plugins/unityshell/src/PluginAdapter.cpp --- unity-5.8.0/plugins/unityshell/src/PluginAdapter.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PluginAdapter.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -66,6 +66,7 @@ _last_focused_window(nullptr) { _spread_state = false; + _spread_windows_state = false; _expo_state = false; _vp_switch_started = false; @@ -105,6 +106,7 @@ if (_spread_state && !screen->grabExist("scale")) { _spread_state = false; + _spread_windows_state = false; terminate_spread.emit(); } @@ -296,7 +298,7 @@ unsigned long long PluginAdapter::GetWindowActiveNumber (guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -370,6 +372,12 @@ } bool +PluginAdapter::IsScaleActiveForGroup() +{ + return _spread_windows_state && m_Screen->grabExist("scale"); +} + +bool PluginAdapter::IsExpoActive() { return m_Screen->grabExist("expo"); @@ -387,7 +395,7 @@ bool PluginAdapter::IsWindowMaximized(guint xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -442,7 +450,7 @@ bool PluginAdapter::IsWindowOnCurrentDesktop(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -458,13 +466,18 @@ bool PluginAdapter::IsWindowObscured(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); + if (window) { + if (window->inShowDesktopMode()) + return true; + CompPoint window_vp = window->defaultViewport(); + nux::Geometry const& win_geo = GetWindowGeometry(window->id()); // Check if any windows above this one are blocking it for (CompWindow* sibling = window->next; sibling != NULL; sibling = sibling->next) { @@ -472,8 +485,11 @@ && !sibling->minimized() && sibling->isMapped() && sibling->isViewable() - && (sibling->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE) + && (sibling->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE + && !GetWindowGeometry(sibling->id()).Intersect(win_geo).IsNull()) + { return true; + } } } @@ -483,7 +499,7 @@ bool PluginAdapter::IsWindowMapped(guint32 xid) { - Window win = (Window) xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -495,20 +511,33 @@ bool PluginAdapter::IsWindowVisible(guint32 xid) { - Window win = (Window) xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); if (window) - return !(window->state () & CompWindowStateHiddenMask); + return !(window->state() & CompWindowStateHiddenMask) && !window->inShowDesktopMode(); - return true; + return false; +} + +bool +PluginAdapter::IsWindowMinimizable(guint32 xid) +{ + Window win = xid; + CompWindow* window; + + window = m_Screen->findWindow(win); + if (window) + return (window->actions() & CompWindowActionMinimizeMask); + + return false; } void PluginAdapter::Restore(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -517,20 +546,37 @@ } void +PluginAdapter::RestoreAt(guint32 xid, int x, int y) +{ + Window win = xid; + CompWindow* window; + + window = m_Screen->findWindow(win); + if (window && (window->state() & MAXIMIZE_STATE)) + { + nux::Geometry new_geo(GetWindowSavedGeometry(xid)); + new_geo.x = x; + new_geo.y = y; + window->maximize(0); + MoveResizeWindow(xid, new_geo); + } +} + +void PluginAdapter::Minimize(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); - if (window) + if (window && (window->actions() & CompWindowActionMinimizeMask)) window->minimize(); } void PluginAdapter::Close(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -541,7 +587,7 @@ void PluginAdapter::Activate(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -552,7 +598,7 @@ void PluginAdapter::Raise(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -563,7 +609,7 @@ void PluginAdapter::Lower(guint32 xid) { - Window win = (Window)xid; + Window win = xid; CompWindow* window; window = m_Screen->findWindow(win); @@ -664,9 +710,13 @@ } if (monitor > 0 && top_window_on_monitor) + { top_window_on_monitor->activate(); + } else if (top_window) + { top_window->activate(); + } } bool @@ -676,6 +726,7 @@ { std::string match = MatchStringForXids(&windows); InitiateScale(match, state); + _spread_windows_state = true; return true; } return false; @@ -718,9 +769,9 @@ } nux::Geometry -PluginAdapter::GetWindowGeometry(guint32 xid) +PluginAdapter::GetWindowGeometry(guint32 xid) const { - Window win = (Window)xid; + Window win = xid; CompWindow* window; nux::Geometry geo(0, 0, 1, 1); @@ -735,8 +786,28 @@ return geo; } +nux::Geometry +PluginAdapter::GetWindowSavedGeometry(guint32 xid) const +{ + Window win = xid; + nux::Geometry geo(0, 0, 1, 1); + CompWindow* window; + + window = m_Screen->findWindow(win); + if (window) + { + XWindowChanges &wc = window->saveWc(); + geo.x = wc.x; + geo.y = wc.y; + geo.width = wc.width; + geo.height = wc.height; + } + + return geo; +} + nux::Geometry -PluginAdapter::GetScreenGeometry() +PluginAdapter::GetScreenGeometry() const { nux::Geometry geo; @@ -748,6 +819,33 @@ return geo; } +nux::Geometry +PluginAdapter::GetWorkAreaGeometry(guint32 xid) const +{ + CompWindow* window = nullptr; + unsigned int output = 0; + + if (xid != 0) + { + Window win = xid; + + window = m_Screen->findWindow(win); + if (window) + { + output = window->outputDevice(); + } + } + + if (xid == 0 || !window) + { + output = m_Screen->currentOutputDev().id(); + } + + CompRect workarea = m_Screen->getWorkareaForOutput(output); + + return nux::Geometry(workarea.x(), workarea.y(), workarea.width(), workarea.height()); +} + bool PluginAdapter::CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) { @@ -1056,6 +1154,42 @@ } void +PluginAdapter::MoveResizeWindow(guint32 xid, nux::Geometry geometry) +{ + int w, h; + CompWindow* window = m_Screen->findWindow(xid); + + if (!window) + return; + + if (window->constrainNewWindowSize(geometry.width, geometry.height, &w, &h)) + { + CompRect workarea = m_Screen->getWorkareaForOutput(window->outputDevice()); + int dx = geometry.x + w - workarea.right() + window->border().right; + int dy = geometry.y + h - workarea.bottom() + window->border().bottom; + + if (dx > 0) + geometry.x -= dx; + if (dy > 0) + geometry.y -= dy; + + geometry.SetWidth(w); + geometry.SetHeight(h); + } + + XWindowChanges xwc; + xwc.x = geometry.x; + xwc.y = geometry.y; + xwc.width = geometry.width; + xwc.height = geometry.height; + + if (window->mapNum()) + window->sendSyncRequest(); + + window->configureXWindow(CWX | CWY | CWWidth | CWHeight, &xwc); +} + +void PluginAdapter::OnWindowClosed(CompWindow *w) { if (_last_focused_window == w) diff -Nru unity-5.8.0/plugins/unityshell/src/PluginAdapter.h unity-5.10.0/plugins/unityshell/src/PluginAdapter.h --- unity-5.8.0/plugins/unityshell/src/PluginAdapter.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PluginAdapter.h 2012-04-12 13:21:21.000000000 +0000 @@ -93,6 +93,7 @@ void TerminateScale(); bool IsScaleActive(); + bool IsScaleActiveForGroup(); void InitiateExpo(); bool IsExpoActive(); @@ -118,7 +119,10 @@ bool IsWindowObscured(guint xid); bool IsWindowMapped(guint xid); bool IsWindowVisible(guint32 xid); + bool IsWindowMinimizable(guint32 xid); + void Restore(guint32 xid); + void RestoreAt(guint32 xid, int x, int y); void Minimize(guint32 xid); void Close(guint32 xid); void Activate(guint32 xid); @@ -138,9 +142,11 @@ bool MaximizeIfBigEnough(CompWindow* window); - nux::Geometry GetWindowGeometry(guint32 xid); - nux::Geometry GetScreenGeometry(); - + nux::Geometry GetWindowGeometry(guint32 xid) const; + nux::Geometry GetWindowSavedGeometry(guint32 xid) const; + nux::Geometry GetScreenGeometry() const; + nux::Geometry GetWorkAreaGeometry(guint32 xid = 0) const; + void CheckWindowIntersections(nux::Geometry const& region, bool &active, bool &any); int WorkspaceCount(); @@ -150,6 +156,8 @@ bool saveInputFocus (); bool restoreInputFocus (); + void MoveResizeWindow(guint32 xid, nux::Geometry geometry); + protected: PluginAdapter(CompScreen* screen); @@ -165,6 +173,7 @@ MultiActionList m_ScaleActionList; bool _spread_state; + bool _spread_windows_state; bool _expo_state; bool _vp_switch_started; diff -Nru unity-5.8.0/plugins/unityshell/src/PointerBarrier.cpp unity-5.10.0/plugins/unityshell/src/PointerBarrier.cpp --- unity-5.8.0/plugins/unityshell/src/PointerBarrier.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PointerBarrier.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -37,6 +37,7 @@ PointerBarrierWrapper::PointerBarrierWrapper() { + direction = BOTH; last_event_ = 0; last_y_ = 0; last_x_ = 0; @@ -51,6 +52,9 @@ PointerBarrierWrapper::~PointerBarrierWrapper() { DestroyBarrier(); + + if (smoothing_handle_) + g_source_remove(smoothing_handle_); } void PointerBarrierWrapper::ConstructBarrier() @@ -69,7 +73,7 @@ DefaultRootWindow(dpy), x1, y1, x2, y2, - 0, + (int) direction, threshold, 0, NULL); diff -Nru unity-5.8.0/plugins/unityshell/src/PointerBarrier.h unity-5.10.0/plugins/unityshell/src/PointerBarrier.h --- unity-5.8.0/plugins/unityshell/src/PointerBarrier.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PointerBarrier.h 2012-04-12 13:21:21.000000000 +0000 @@ -41,6 +41,15 @@ int event_id; }; + +// values picked to match Xfixes values +enum BarrierDirection +{ + BOTH = 0, + LEFT = 1, + RIGHT = 4, +}; + class PointerBarrierWrapper { public: @@ -59,6 +68,10 @@ nux::Property max_velocity_multiplier; + nux::Property index; + + nux::Property direction; + PointerBarrierWrapper(); ~PointerBarrierWrapper(); diff -Nru unity-5.8.0/plugins/unityshell/src/PreviewApplications.cpp unity-5.10.0/plugins/unityshell/src/PreviewApplications.cpp --- unity-5.8.0/plugins/unityshell/src/PreviewApplications.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PreviewApplications.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -54,8 +54,8 @@ void PreviewApplications::BuildLayout() { - IconTexture *screenshot = new IconTexture (preview_->screenshot_icon_hint.c_str(), 420); - IconTexture *icon = new IconTexture (preview_->icon_hint.c_str(), 80); + IconTexture *screenshot = new IconTexture(preview_->screenshot_icon_hint, 420); + IconTexture *icon = new IconTexture(preview_->icon_hint, 80); nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name, NUX_TRACKER_LOCATION); name->SetFont("Ubuntu 25"); diff -Nru unity-5.8.0/plugins/unityshell/src/PreviewGeneric.cpp unity-5.10.0/plugins/unityshell/src/PreviewGeneric.cpp --- unity-5.8.0/plugins/unityshell/src/PreviewGeneric.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PreviewGeneric.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -54,7 +54,7 @@ void PreviewGeneric::BuildLayout() { - IconTexture *icon = new IconTexture (preview_->icon_hint.c_str(), 300); + IconTexture *icon = new IconTexture(preview_->icon_hint, 300); nux::StaticCairoText *name = new nux::StaticCairoText (preview_->name, NUX_TRACKER_LOCATION); name->SetFont("Ubuntu 25"); diff -Nru unity-5.8.0/plugins/unityshell/src/PreviewMusic.cpp unity-5.10.0/plugins/unityshell/src/PreviewMusic.cpp --- unity-5.8.0/plugins/unityshell/src/PreviewMusic.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PreviewMusic.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -57,7 +57,7 @@ void PreviewMusicAlbum::BuildLayout() { - IconTexture *cover = new IconTexture (preview_->album_cover.c_str(), 400); + IconTexture *cover = new IconTexture (preview_->album_cover, 400); nux::StaticCairoText *title = new nux::StaticCairoText(preview_->name, NUX_TRACKER_LOCATION); title->SetFont("Ubuntu 25"); diff -Nru unity-5.8.0/plugins/unityshell/src/PreviewMusicTrack.cpp unity-5.10.0/plugins/unityshell/src/PreviewMusicTrack.cpp --- unity-5.8.0/plugins/unityshell/src/PreviewMusicTrack.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/PreviewMusicTrack.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -56,7 +56,7 @@ void PreviewMusicTrack::BuildLayout() { - IconTexture *cover = new IconTexture (preview_->album_cover.c_str(), 400); + IconTexture *cover = new IconTexture(preview_->album_cover, 400); nux::StaticCairoText *title = new nux::StaticCairoText(preview_->title, NUX_TRACKER_LOCATION); title->SetFont("Ubuntu 25"); diff -Nru unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp unity-5.10.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp --- unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ResultRendererHorizontalTile.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -37,13 +37,34 @@ #include "IconTexture.h" #include "TextureCache.h" -//~ namespace -//~ { -//~ nux::logging::Logger logger("unity.dash.ResultRendererHorizontalTile"); -//~ } namespace unity { +namespace +{ +//~ nux::logging::Logger logger("unity.dash.ResultRendererHorizontalTile"); +const int CARD_VIEW_PADDING = 4; // pixels +const int CARD_VIEW_ICON_SIZE = 64; // pixels +const int CARD_VIEW_ICON_TEXT_GAP = 10; // pixels +//const int CARD_VIEW_GAP_VERT = 24; // pixels +//const int CARD_VIEW_GAP_HORIZ = 25; // pixels +const int CARD_VIEW_WIDTH = 277; // pixels +const int CARD_VIEW_HEIGHT = 74; // pixels +const int CARD_VIEW_HIGHLIGHT_CORNER_RADIUS = 2; // pixels +//const char CARD_VIEW_ICON_OUTLINE_COLOR = "#000000"; +//const float CARD_VIEW_ICON_OUTLINE_OPACITY = 1.0; //float +const int CARD_VIEW_ICON_OUTLINE_WIDTH = 1; // pixels +const int CARD_VIEW_TEXT_LINE_SPACING = 0; // points +//const char CARD_VIEW_TEXT_TITLE_COLOR = "#ffffff"; +//const float CARD_VIEW_TEXT_TITLE_OPACITY = 1.0; // float +//const float CARD_VIEW_TEXT_TITLE_SIZE = 13.0; // points +//const char CARD_VIEW_TEXT_TITLE_WEIGHT = "bold"; +//const char CARD_VIEW_TEXT_BODY_COLOR = "#ffffff"; +//const float CARD_VIEW_TEXT_BODY_OPACITY = 1.0; // float +//const float CARD_VIEW_TEXT_BODY_SIZE = 13.0; // points +//const int CARD_VIEW_TEXT_BODY_WEIGHT = "regular"; +} + namespace dash { NUX_IMPLEMENT_OBJECT_TYPE(ResultRendererHorizontalTile); @@ -51,17 +72,21 @@ ResultRendererHorizontalTile::ResultRendererHorizontalTile(NUX_FILE_LINE_DECL) : ResultRendererTile(NUX_FILE_LINE_PARAM) { - Style& style = Style::Instance(); - width = style.GetTileWidth() * 2; - height = style.GetTileIconSize() + (padding * 2); + width = CARD_VIEW_WIDTH; + height = CARD_VIEW_HEIGHT; // pre-load the highlight texture // try and get a texture from the texture cache TextureCache& cache = TextureCache::GetDefault(); prelight_cache_ = cache.FindTexture("ResultRendererHorizontalTile.PreLightTexture", - style.GetTileIconSize() + (highlight_padding * 2), - style.GetTileIconSize() + (highlight_padding * 2), + CARD_VIEW_WIDTH, + CARD_VIEW_HEIGHT, sigc::mem_fun(this, &ResultRendererHorizontalTile::DrawHighlight)); + normal_cache_ = cache.FindTexture("ResultRendererHorizontalTile.NormalTexture", + CARD_VIEW_WIDTH, + CARD_VIEW_HEIGHT, + sigc::mem_fun(this, &ResultRendererHorizontalTile::DrawNormal)); + } ResultRendererHorizontalTile::~ResultRendererHorizontalTile() @@ -78,33 +103,49 @@ if (container == nullptr) return; - Style& style = Style::Instance(); - // set up our texture mode nux::TexCoordXForm texxform; int icon_left_hand_side = geometry.x + padding; - int icon_top_side = geometry.y + ((geometry.height - style.GetTileIconSize()) / 2); - + int icon_top_side = geometry.y + ((geometry.height - CARD_VIEW_ICON_SIZE) / 2); - if (container->blurred_icon && state == ResultRendererState::RESULT_RENDERER_NORMAL) + // render overall tile background "rectangle" + if (state == ResultRendererState::RESULT_RENDERER_NORMAL) { - GfxContext.QRP_1Tex(icon_left_hand_side - 5 - x_offset, - icon_top_side - 5 - y_offset, - style.GetTileIconSize() + 10, - style.GetTileIconSize() + 10, - container->blurred_icon->GetDeviceTexture(), + int x = icon_left_hand_side; + int y = icon_top_side; + int w = CARD_VIEW_WIDTH; + int h = CARD_VIEW_HEIGHT; + + unsigned int alpha = 0; + unsigned int src = 0; + unsigned int dest = 0; + GfxContext.GetRenderStates().GetBlend(alpha, src, dest); + GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + GfxContext.QRP_1Tex(x, + y, + w, + h, + normal_cache_->GetDeviceTexture(), texxform, - nux::Color(0.15f, 0.15f, 0.15f, 0.15f)); + nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + + GfxContext.GetRenderStates().SetBlend(alpha, src, dest); } // render highlight if its needed if (state != ResultRendererState::RESULT_RENDERER_NORMAL) { - GfxContext.QRP_1Tex(icon_left_hand_side - highlight_padding, - icon_top_side - highlight_padding, - style.GetTileIconSize() + (highlight_padding * 2), - style.GetTileIconSize() + (highlight_padding * 2), + int x = icon_left_hand_side; + int y = icon_top_side; + int w = CARD_VIEW_WIDTH; + int h = CARD_VIEW_HEIGHT; + + GfxContext.QRP_1Tex(x, + y, + w, + h, prelight_cache_->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); @@ -113,10 +154,20 @@ // draw the icon if (container->icon) { - GfxContext.QRP_1Tex(icon_left_hand_side, - icon_top_side, - style.GetTileIconSize(), - style.GetTileIconSize(), + int x = icon_left_hand_side + CARD_VIEW_PADDING + CARD_VIEW_ICON_OUTLINE_WIDTH; + int y = icon_top_side + CARD_VIEW_PADDING + CARD_VIEW_ICON_OUTLINE_WIDTH; + int w = CARD_VIEW_ICON_SIZE; + int h = CARD_VIEW_ICON_SIZE; + gPainter.Paint2DQuadColor(GfxContext, + x - CARD_VIEW_ICON_OUTLINE_WIDTH, + y - CARD_VIEW_ICON_OUTLINE_WIDTH, + w + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH, + h + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH, + nux::color::Black); + GfxContext.QRP_1Tex(x, + y, + w, + h, container->icon->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); @@ -124,15 +175,19 @@ if (container->text) { - GfxContext.QRP_1Tex(icon_left_hand_side + style.GetTileIconSize() + spacing, - icon_top_side, - container->text->GetWidth(), - container->text->GetHeight(), + int x = icon_left_hand_side + CARD_VIEW_PADDING + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH + CARD_VIEW_ICON_SIZE + CARD_VIEW_ICON_TEXT_GAP; + int y = icon_top_side + CARD_VIEW_PADDING; + int w = container->text->GetWidth(); + int h = container->text->GetHeight(); + + GfxContext.QRP_1Tex(x, + y, + w, + h, container->text->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); } - } nux::BaseTexture* ResultRendererHorizontalTile::DrawHighlight(std::string const& texid, @@ -147,55 +202,46 @@ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); - int PADDING = 4; - int BLUR_SIZE = 5; - - int bg_width = width - PADDING - BLUR_SIZE; - int bg_height = height - PADDING - BLUR_SIZE; - int bg_x = BLUR_SIZE - 1; - int bg_y = BLUR_SIZE - 1; - - // draw the glow + // draw the highlight cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_set_line_width(cr, 1.0f); - cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.75f); + cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.2f); cairo_graphics.DrawRoundedRectangle(cr, - 1.0f, - bg_x, - bg_y, - 5.0, - bg_width, - bg_height, - true); + 1.0f, + 0.0f, + 0.0f, + CARD_VIEW_HIGHLIGHT_CORNER_RADIUS, + width, + height, + false); cairo_fill(cr); - cairo_graphics.BlurSurface(BLUR_SIZE - 2); + return texture_from_cairo_graphics(cairo_graphics); +} - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_graphics.DrawRoundedRectangle(cr, - 1.0, - bg_x, - bg_y, - 5.0, - bg_width, - bg_height, - true); - cairo_clip(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); +nux::BaseTexture* ResultRendererHorizontalTile::DrawNormal(std::string const& texid, + int width, int height) +{ + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); + cairo_t* cr = cairo_graphics.GetInternalContext(); - cairo_graphics.DrawRoundedRectangle(cr, - 1.0, - bg_x, - bg_y, - 5.0, - bg_width, - bg_height, - true); - cairo_set_source_rgba(cr, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f, 1.0f); - cairo_fill_preserve(cr); + cairo_scale(cr, 1.0f, 1.0f); - cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0); - cairo_stroke(cr); + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0); + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cr); + + // draw the normal bg + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.075f); + cairo_graphics.DrawRoundedRectangle(cr, + 1.0f, + 0.0f, + 0.0f, + CARD_VIEW_HIGHLIGHT_CORNER_RADIUS, + width, + height, + false); + cairo_fill(cr); return texture_from_cairo_graphics(cairo_graphics); } @@ -205,16 +251,18 @@ std::stringstream final_text; char *name = g_markup_escape_text(row.name().c_str() , -1); char *comment = g_markup_escape_text(row.comment().c_str() , -1); - final_text << name << "\n" - << comment << ""; + + if(row.comment().empty()) + final_text << "" << name << ""; + else + final_text << "" << name << "" << "\n" << comment; g_free(name); g_free(comment); - Style& style = Style::Instance(); nux::CairoGraphics _cairoGraphics(CAIRO_FORMAT_ARGB32, - width() - style.GetTileIconSize() + spacing - (padding * 2), - height() - (padding * 2)); + CARD_VIEW_WIDTH - CARD_VIEW_ICON_SIZE - 2 * CARD_VIEW_ICON_OUTLINE_WIDTH - 2 * CARD_VIEW_PADDING - CARD_VIEW_ICON_TEXT_GAP, + CARD_VIEW_HEIGHT - 2 * CARD_VIEW_PADDING); cairo_t* cr = _cairoGraphics.GetContext(); @@ -222,23 +270,22 @@ PangoFontDescription* desc = NULL; PangoContext* pango_context = NULL; GdkScreen* screen = gdk_screen_get_default(); // not ref'ed - glib::String font; int dpi = -1; - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font, NULL); g_object_get(gtk_settings_get_default(), "gtk-xft-dpi", &dpi, NULL); 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()); + desc = pango_font_description_from_string("Ubuntu 10"); pango_layout_set_font_description(layout, desc); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - pango_layout_set_width(layout, (width() - style.GetTileIconSize() - spacing)* PANGO_SCALE); - pango_layout_set_height(layout, (height() - (padding * 2)) * PANGO_SCALE); + pango_layout_set_spacing(layout, CARD_VIEW_TEXT_LINE_SPACING * PANGO_SCALE); + pango_layout_set_width(layout, (CARD_VIEW_WIDTH - CARD_VIEW_ICON_SIZE - 2 * CARD_VIEW_ICON_OUTLINE_WIDTH - 2 * CARD_VIEW_PADDING - CARD_VIEW_ICON_TEXT_GAP) * PANGO_SCALE); + pango_layout_set_height(layout, -4); pango_layout_set_markup(layout, final_text.str().c_str(), -1); @@ -255,7 +302,12 @@ cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f); - cairo_move_to(cr, 0.0f, 0.0f); + double offset = 0.0; + PangoRectangle logRect = {0, 0, 0, 0}; + pango_layout_get_extents(layout, NULL, &logRect); + if (pango_layout_get_line_count(layout) < 4) + offset = ((CARD_VIEW_HEIGHT - 2 * CARD_VIEW_PADDING) - (logRect.height / PANGO_SCALE)) / 2.0; + cairo_move_to(cr, 0.0f, offset); pango_cairo_show_layout(cr, layout); // clean up diff -Nru unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.h unity-5.10.0/plugins/unityshell/src/ResultRendererHorizontalTile.h --- unity-5.8.0/plugins/unityshell/src/ResultRendererHorizontalTile.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ResultRendererHorizontalTile.h 2012-04-12 13:21:21.000000000 +0000 @@ -59,6 +59,8 @@ private: nux::BaseTexture* DrawHighlight(std::string const& texid, int width, int height); + nux::BaseTexture* DrawNormal(std::string const& texid, + int width, int height); }; } diff -Nru unity-5.8.0/plugins/unityshell/src/ResultRendererTile.cpp unity-5.10.0/plugins/unityshell/src/ResultRendererTile.cpp --- unity-5.8.0/plugins/unityshell/src/ResultRendererTile.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ResultRendererTile.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -53,7 +53,6 @@ nux::logging::Logger logger("unity.dash.results"); const int FONT_SIZE = 10; - } namespace dash @@ -96,7 +95,7 @@ int x_offset, int y_offset) { TextureContainer* container = row.renderer(); - if (container == nullptr) + if (container == nullptr || container->icon == nullptr) return; dash::Style& style = dash::Style::Instance(); @@ -105,29 +104,28 @@ // set up our texture mode nux::TexCoordXForm texxform; - int icon_left_hand_side = geometry.x + (geometry.width - tile_icon_size) / 2; - int icon_top_side = geometry.y + padding; - + int icon_left_hand_side = geometry.x + (geometry.width - container->icon->GetWidth()) / 2; + int icon_top_side = geometry.y + padding + ((tile_icon_size - container->icon->GetHeight()) / 2); if (container->blurred_icon && state == ResultRendererState::RESULT_RENDERER_NORMAL) { GfxContext.QRP_1Tex(icon_left_hand_side - 5 - x_offset, icon_top_side - 5 - y_offset, - tile_icon_size + 10, - tile_icon_size + 10, + container->blurred_icon->GetWidth(), + container->blurred_icon->GetHeight(), container->blurred_icon->GetDeviceTexture(), texxform, nux::Color(0.15f, 0.15f, 0.15f, 0.15f)); } // render highlight if its needed - if (state != ResultRendererState::RESULT_RENDERER_NORMAL) + if (container->prelight && state != ResultRendererState::RESULT_RENDERER_NORMAL) { GfxContext.QRP_1Tex(icon_left_hand_side - highlight_padding, icon_top_side - highlight_padding, - tile_icon_size + (highlight_padding * 2), - tile_icon_size + (highlight_padding * 2), - prelight_cache_->GetDeviceTexture(), + container->prelight->GetWidth(), + container->prelight->GetHeight(), + container->prelight->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); } @@ -137,8 +135,8 @@ { GfxContext.QRP_1Tex(icon_left_hand_side, icon_top_side, - tile_icon_size, - tile_icon_size, + container->icon->GetWidth(), + container->icon->GetHeight(), container->icon->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); @@ -153,8 +151,6 @@ container->text->GetDeviceTexture(), texxform, nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); - - } } @@ -244,7 +240,7 @@ std::string const& icon_hint = row.icon_hint; #define DEFAULT_GICON ". GThemedIcon text-x-preview" std::string icon_name; - if (neko) + if (G_UNLIKELY(neko)) { int tmp1 = style.GetTileIconSize() + (rand() % 16) - 8; gsize tmp3; @@ -291,6 +287,13 @@ int pixbuf_width, pixbuf_height; pixbuf_width = gdk_pixbuf_get_width(pixbuf); pixbuf_height = gdk_pixbuf_get_height(pixbuf); + if (G_UNLIKELY(!pixbuf_height || !pixbuf_width)) + { + LOG_ERROR(logger) << "Pixbuf: " << texid << " has a zero height/width: " + << width << "," << height; + pixbuf_width = (pixbuf_width) ? pixbuf_width : 1; // no zeros please + pixbuf_height = (pixbuf_height) ? pixbuf_height: 1; // no zeros please + } if (pixbuf_width == pixbuf_height) { @@ -301,21 +304,39 @@ { // slow path for non square icons that must be resized to fit in the square // texture - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); + + Style& style = Style::Instance(); + float aspect = static_cast(pixbuf_height) / pixbuf_width; // already sanitized width/height so can not be 0.0 + if (aspect < 1.0f) + { + pixbuf_width = style.GetTileWidth() - (padding * 2); + pixbuf_height = pixbuf_width * aspect; + + + if (pixbuf_height > height) + { + // scaled too big, scale down + pixbuf_height = height; + pixbuf_width = pixbuf_height / aspect; + } + } + else + { + pixbuf_height = height; + pixbuf_width = pixbuf_height / aspect; + } + + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, pixbuf_width, pixbuf_height); cairo_t* cr = cairo_graphics.GetInternalContext(); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); - float scale; - if (pixbuf_width > pixbuf_height) - scale = pixbuf_height / static_cast(pixbuf_width); - else - scale = pixbuf_width / static_cast(pixbuf_height); + float scale = gdk_pixbuf_get_height(pixbuf) / float(pixbuf_height); - cairo_translate(cr, - static_cast((width - (pixbuf_width * scale)) * 0.5), - static_cast((height - (pixbuf_height * scale)) * 0.5)); + //cairo_translate(cr, + // static_cast((width - (pixbuf_width * scale)) * 0.5), + // static_cast((height - (pixbuf_height * scale)) * 0.5)); cairo_scale(cr, scale, scale); @@ -386,8 +407,11 @@ BaseTexturePtr texture_blurred(cache.FindTexture(blur_texid, style.GetTileIconSize(), style.GetTileIconSize(), sigc::bind(sigc::mem_fun(this, &ResultRendererTile::CreateBlurredTextureCallback), pixbuf))); + BaseTexturePtr texture_prelight(cache.FindTexture("resultview_prelight", texture->GetWidth() + highlight_padding*2, texture->GetHeight() + highlight_padding*2, sigc::mem_fun(this, &ResultRendererTile::DrawHighlight))); + container->icon = texture; container->blurred_icon = texture_blurred; + container->prelight = texture_prelight; NeedsRedraw.emit(); diff -Nru unity-5.8.0/plugins/unityshell/src/ResultRendererTile.h unity-5.10.0/plugins/unityshell/src/ResultRendererTile.h --- unity-5.8.0/plugins/unityshell/src/ResultRendererTile.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ResultRendererTile.h 2012-04-12 13:21:21.000000000 +0000 @@ -45,6 +45,7 @@ BaseTexturePtr text; BaseTexturePtr icon; BaseTexturePtr blurred_icon; + BaseTexturePtr prelight; int slot_handle; TextureContainer() @@ -87,7 +88,7 @@ virtual void LoadText(Result& row); void LoadIcon(Result& row); nux::ObjectPtr prelight_cache_; - + nux::ObjectPtr normal_cache_; private: //icon loading callbacks void IconLoaded(std::string const& texid, diff -Nru unity-5.8.0/plugins/unityshell/src/ResultViewGrid.cpp unity-5.10.0/plugins/unityshell/src/ResultViewGrid.cpp --- unity-5.8.0/plugins/unityshell/src/ResultViewGrid.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ResultViewGrid.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -620,8 +620,6 @@ void ResultViewGrid::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { - gPainter.PaintBackground(GfxContext, GetGeometry()); - int items_per_row = GetItemsPerRow(); uint total_rows = (!expanded) ? 0 : (results_.size() / items_per_row) + 1; diff -Nru unity-5.8.0/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp unity-5.10.0/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp --- unity-5.8.0/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -101,9 +101,6 @@ void unity::ScreenEffectFramebufferObject::bind (const nux::Geometry &output) { - if (!BackgroundEffectHelper::HasDirtyHelpers()) - return; - /* Clear the error bit */ glGetError (); diff -Nru unity-5.8.0/plugins/unityshell/src/SearchBar.cpp unity-5.10.0/plugins/unityshell/src/SearchBar.cpp --- unity-5.8.0/plugins/unityshell/src/SearchBar.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SearchBar.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -50,7 +50,9 @@ const int SPINNER_TIMEOUT = 100; const int SPACE_BETWEEN_SPINNER_AND_TEXT = 5; -const int LEFT_INTERNAL_PADDING = 7; +const int SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT = 10; +const int LEFT_INTERNAL_PADDING = 6; +const int SEARCH_ENTRY_RIGHT_BORDER = 10; const int HIGHLIGHT_HEIGHT = 24; @@ -121,42 +123,23 @@ , search_hint("") , showing_filters(false) , can_refine_search(false) - , disable_glow(false) , show_filter_hint_(true) , expander_view_(nullptr) , show_filters_(nullptr) - , search_bar_width_(621) , live_search_timeout_(0) , start_spinner_timeout_(0) { Init(); } -SearchBar::SearchBar(int search_bar_width, bool show_filter_hint_, NUX_FILE_LINE_DECL) +SearchBar::SearchBar(bool show_filter_hint_, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , search_hint("") , showing_filters(false) , can_refine_search(false) - , disable_glow(false) , show_filter_hint_(show_filter_hint_) , expander_view_(nullptr) , show_filters_(nullptr) - , search_bar_width_(search_bar_width) - , live_search_timeout_(0) - , start_spinner_timeout_(0) -{ - Init(); -} - -SearchBar::SearchBar(int search_bar_width, NUX_FILE_LINE_DECL) - : View(NUX_FILE_LINE_PARAM) - , search_hint("") - , showing_filters(false) - , can_refine_search(false) - , disable_glow(false) - , show_filter_hint_(true) - , expander_view_(nullptr) - , search_bar_width_(search_bar_width) , live_search_timeout_(0) , start_spinner_timeout_(0) { @@ -165,25 +148,30 @@ void SearchBar::Init() { - nux::BaseTexture* icon = dash::Style::Instance().GetSearchMagnifyIcon(); + dash::Style& style = dash::Style::Instance(); + nux::BaseTexture* icon = style.GetSearchMagnifyIcon(); bg_layer_ = new nux::ColorLayer(nux::Color(0xff595853), true); layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); - layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, 10); - layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_SPINNER_AND_TEXT); + layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, SEARCH_ENTRY_RIGHT_BORDER); + layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT); SetLayout(layout_); + entry_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); + entry_layout_->SetLeftAndRightPadding(0, 10); + layout_->AddLayout(entry_layout_); + spinner_ = new SearchBarSpinner(); spinner_->SetMinMaxSize(icon->GetWidth(), icon->GetHeight()); spinner_->mouse_click.connect(sigc::mem_fun(this, &SearchBar::OnClearClicked)); - layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + entry_layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + entry_layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_SPINNER_AND_TEXT); 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); @@ -195,16 +183,13 @@ pango_entry_->cursor_moved.connect([&](int i) { QueueDraw(); }); pango_entry_->mouse_down.connect(sigc::mem_fun(this, &SearchBar::OnMouseButtonDown)); pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &SearchBar::OnEndKeyFocus)); - pango_entry_->SetMaximumWidth(search_bar_width_ - 1.5 * icon->GetWidth()); layered_layout_ = new nux::LayeredLayout(); layered_layout_->AddLayout(hint_layout); layered_layout_->AddLayer(pango_entry_); layered_layout_->SetPaintAll(true); layered_layout_->SetActiveLayerN(1); - layered_layout_->SetMinimumWidth(search_bar_width_); - layered_layout_->SetMaximumWidth(search_bar_width_); - layout_->AddView(layered_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); + entry_layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); if (show_filter_hint_) { @@ -217,7 +202,7 @@ show_filters_->SetLines(1); nux::BaseTexture* arrow; - arrow = dash::Style::Instance().GetGroupExpandIcon(); + arrow = style.GetGroupExpandIcon(); expand_icon_ = new IconTexture(arrow, arrow->GetWidth(), arrow->GetHeight()); @@ -227,6 +212,8 @@ filter_layout_ = new nux::HLayout(); filter_layout_->SetHorizontalInternalMargin(8); + filter_layout_->SetLeftAndRightPadding(style.GetFilterResultsHighlightLeftPadding(), style.GetFilterResultsHighlightRightPadding()); + filter_layout_->SetContentDistribution(nux::MAJOR_POSITION_END); filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER); arrow_layout_ = new nux::VLayout(); @@ -238,16 +225,18 @@ filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER); - layout_->AddLayout(new nux::SpaceLayout(1, 10000, 0, 1), 1); - expander_view_ = new ExpanderView(NUX_TRACKER_LOCATION); expander_view_->SetVisible(false); 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); + int width = style.GetFilterBarWidth() + + style.GetFilterResultsHighlightLeftPadding() + + style.GetFilterResultsHighlightRightPadding(); + + expander_view_->SetMaximumWidth(width); + expander_view_->SetMinimumWidth(width); + show_filters_->SetMaximumWidth(style.GetFilterBarWidth() - arrow_layout_->GetBaseWidth() - 8); // Lambda functions auto mouse_expand = [&](int, int, unsigned long, unsigned long) @@ -283,6 +272,7 @@ search_string.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_search_string)); search_string.SetSetterFunction(sigc::mem_fun(this, &SearchBar::set_search_string)); im_active.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_im_active)); + im_preedit.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_im_preedit)); showing_filters.changed.connect(sigc::mem_fun(this, &SearchBar::OnShowingFiltersChanged)); can_refine_search.changed.connect([&] (bool can_refine) { @@ -293,15 +283,6 @@ expand_icon_->SetVisible(can_refine); } }); - - disable_glow.changed.connect([&](bool disabled) - { - layout_->SetVerticalExternalMargin(0); - layout_->SetHorizontalExternalMargin(0); - UpdateBackground(true); - QueueDraw(); - }); - } SearchBar::~SearchBar() @@ -426,13 +407,10 @@ { dash::Style& style = dash::Style::Instance(); - nux::Geometry geo(show_filters_->GetGeometry()); - nux::Geometry const& geo_arrow = arrow_layout_->GetGeometry(); + nux::Geometry geo(expander_view_->GetGeometry()); geo.y -= (HIGHLIGHT_HEIGHT- geo.height) / 2; geo.height = HIGHLIGHT_HEIGHT; - 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(style.FocusOverlay(geo.width, geo.height)); @@ -496,6 +474,30 @@ activated.emit(); } +void SearchBar::ForceSearchChanged() +{ + // this method will emit search_changed (and live_search_reached after + // returning to mainloop) and starts animating the spinner + + if (live_search_timeout_) + g_source_remove(live_search_timeout_); + + live_search_timeout_ = g_idle_add_full(G_PRIORITY_DEFAULT, + (GSourceFunc)&OnLiveSearchTimeout, + this, NULL); + + // Don't animate the spinner immediately, the searches are fast and + // the spinner would just flicker + if (start_spinner_timeout_) + g_source_remove(start_spinner_timeout_); + + start_spinner_timeout_ = g_timeout_add(SPINNER_TIMEOUT * 2, + (GSourceFunc)&OnSpinnerStartCb, + this); + + search_changed.emit(pango_entry_->GetText()); +} + void SearchBar::SearchFinished() { @@ -514,7 +516,10 @@ { int RADIUS = 5; nux::Geometry geo(GetGeometry()); - geo.width = layered_layout_->GetGeometry().width; + geo.width = layered_layout_->GetAbsoluteX() + + layered_layout_->GetAbsoluteWidth() - + GetAbsoluteX() + + SEARCH_ENTRY_RIGHT_BORDER; LOG_DEBUG(logger) << "height: " << geo.height << " - " @@ -534,16 +539,16 @@ cairo_graphics.DrawRoundedRectangle(cr, 1.0f, - 1 + 0.5, 1 + 0.5, + 0.5, 0.5, RADIUS, - last_width_ - 1 - 2, last_height_ - 1 - 2, + last_width_ - 1, last_height_ - 1, false); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.57f); + cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f); 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_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.7f); cairo_stroke(cr); cairo_destroy(cr); @@ -616,6 +621,11 @@ return pango_entry_->im_active(); } +bool SearchBar::get_im_preedit() const +{ + return pango_entry_->im_preedit(); +} + // // Highlight // diff -Nru unity-5.8.0/plugins/unityshell/src/SearchBar.h unity-5.10.0/plugins/unityshell/src/SearchBar.h --- unity-5.8.0/plugins/unityshell/src/SearchBar.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SearchBar.h 2012-04-12 13:21:21.000000000 +0000 @@ -57,10 +57,10 @@ public: typedef nux::ObjectPtr Ptr; SearchBar(NUX_FILE_LINE_PROTO); - SearchBar(int search_width, bool show_filter_hint, NUX_FILE_LINE_PROTO); - SearchBar(int search_width, NUX_FILE_LINE_PROTO); + SearchBar(bool show_filter_hint, NUX_FILE_LINE_PROTO); ~SearchBar(); + void ForceSearchChanged(); void SearchFinished(); nux::TextEntry* text_entry() const; nux::View* show_filters() const; @@ -69,8 +69,8 @@ nux::Property search_hint; nux::Property showing_filters; nux::Property can_refine_search; - nux::Property disable_glow; nux::ROProperty im_active; + nux::ROProperty im_preedit; sigc::signal activated; sigc::signal search_changed; @@ -98,6 +98,7 @@ std::string get_search_string() const; bool set_search_string(std::string const& string); bool get_im_active() const; + bool get_im_preedit() const; bool show_filter_hint_; static gboolean OnLiveSearchTimeout(SearchBar* self); @@ -115,6 +116,7 @@ nux::AbstractPaintLayer* bg_layer_; std::unique_ptr highlight_layer_; nux::HLayout* layout_; + nux::HLayout* entry_layout_; nux::LayeredLayout* layered_layout_; nux::StaticCairoText* hint_; nux::LinearLayout* expander_layout_; @@ -126,7 +128,6 @@ nux::SpaceLayout* arrow_top_space_; nux::SpaceLayout* arrow_bottom_space_; IconTexture* expand_icon_; - int search_bar_width_; int last_width_; int last_height_; diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutController.cpp unity-5.10.0/plugins/unityshell/src/ShortcutController.cpp --- unity-5.8.0/plugins/unityshell/src/ShortcutController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -30,8 +30,8 @@ const unsigned int SUPER_TAP_DURATION = 650; const unsigned int FADE_DURATION = 100; } // anonymouse namespace; - -Controller::Controller(std::list& hints) + +Controller::Controller(std::list& hints) : view_window_(0) , visible_(false) , enabled_(true) @@ -72,7 +72,7 @@ { if (view_window_) view_window_->UnReference(); - + view_.Release(); } @@ -109,18 +109,22 @@ view_->background_color = bg_color_; } -void Controller::Show() +bool Controller::Show() { if (show_timer_) - g_source_remove (show_timer_); + g_source_remove(show_timer_); + show_timer_ = 0; if (enabled_) { show_timer_ = g_timeout_add(SUPER_TAP_DURATION, &Controller::OnShowTimer, this); model_->Fill(); visible_ = true; + + return true; } + return false; } gboolean Controller::OnShowTimer(gpointer data) @@ -132,14 +136,15 @@ return FALSE; } - if (!self->view_window_) - self->ConstructView(); + self->EnsureView(); - self->ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); + nux::Geometry geo; + if (!self->view_->GetBaseGeometry(geo)) + return FALSE; + self->view_window_->SetGeometry(geo); if (self->visible_) { - self->view_window_->SetGeometry(self->workarea_); self->view_->SetupBackground(true); self->fade_out_animator_.Stop(); self->fade_in_animator_.Start(self->view_window_->GetOpacity()); @@ -167,23 +172,32 @@ view_window_->SetBackgroundColor(nux::Color(0x00000000)); } - main_layout_->AddView(view_.GetPointer(), 1); + main_layout_->AddView(view_.GetPointer()); view_->SetupBackground(false); view_window_->SetOpacity(0.0); view_window_->ShowWindow(true); } -void Controller::SetWorkspace(nux::Geometry const& geo) +void Controller::EnsureView() +{ + if (!view_window_) + ConstructView(); +} + +void Controller::SetAdjustment(int x, int y) { - workarea_ = geo; + EnsureView(); + + view_->SetAdjustment(x, y); } + void Controller::Hide() { if (!visible_) return; - + visible_ = false; if (show_timer_) @@ -215,6 +229,9 @@ enabled_ = enabled; } +// +// Introspection +// std::string Controller::GetName() const { return "ShortcutController"; @@ -223,7 +240,6 @@ 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)) diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutController.h unity-5.10.0/plugins/unityshell/src/ShortcutController.h --- unity-5.8.0/plugins/unityshell/src/ShortcutController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutController.h 2012-04-12 13:21:21.000000000 +0000 @@ -42,19 +42,19 @@ { public: typedef std::shared_ptr Ptr; - + // Ctor and dtor - Controller(std::list& hints); - ~Controller(); - + Controller(std::list& hints); + ~Controller(); + // Public Methods - void Show(); + bool Show(); void Hide(); - + bool Visible(); bool IsEnabled(); - void SetWorkspace(nux::Geometry const& geo); + void SetAdjustment(int x, int y); void SetEnabled(bool enabled); protected: @@ -64,6 +64,7 @@ private: // Private Methods void ConstructView(); + void EnsureView(); void OnBackgroundUpdate(GVariant* data); void OnFadeInUpdated(double opacity); void OnFadeInEnded(); @@ -71,20 +72,20 @@ void OnFadeOutEnded(); static gboolean OnShowTimer(gpointer data); - + // Private Members View::Ptr view_; Model::Ptr model_; - + nux::Geometry workarea_; nux::BaseWindow* view_window_; nux::HLayout* main_layout_; - + bool visible_; bool enabled_; nux::Color bg_color_; guint show_timer_; - + Animator fade_in_animator_; Animator fade_out_animator_; diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutHint.cpp unity-5.10.0/plugins/unityshell/src/ShortcutHint.cpp --- unity-5.8.0/plugins/unityshell/src/ShortcutHint.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutHint.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -103,7 +103,7 @@ { if (opt.name() == arg2()) { - std::string temp = impl::FixShortcutFormat(opt.value().action().keyToString()); + std::string temp(impl::GetTranslatableLabel(opt.value().action().keyToString())); temp = impl::ProperCase(temp); if (value() != temp) diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutHint.h unity-5.10.0/plugins/unityshell/src/ShortcutHint.h --- unity-5.8.0/plugins/unityshell/src/ShortcutHint.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutHint.h 2012-04-12 13:21:21.000000000 +0000 @@ -16,7 +16,7 @@ * * Authored by: Andrea Azzarone */ - + #ifndef UNITYSHELL_SHORTCUTHINT_H #define UNITYSHELL_SHORTCUTHINT_H @@ -36,10 +36,10 @@ std::string const& postfix, std::string const& description, OptionType const type, - std::string const& arg1, + std::string const& arg1, std::string const& arg2 = "", std::string const& arg3 = ""); - + // Dtor ~Hint(); diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.cpp unity-5.10.0/plugins/unityshell/src/ShortcutHintPrivate.cpp --- unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutHintPrivate.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -17,8 +17,10 @@ */ #include +#include #include "ShortcutHintPrivate.h" +#include "UnityCore/GLibWrapper.h" #include @@ -51,6 +53,31 @@ return ret; } +std::string GetTranslatableLabel(std::string const& scut) +{ + guint accelerator_key; + GdkModifierType accelerator_mods; + + gtk_accelerator_parse(scut.c_str(), + &accelerator_key, + &accelerator_mods); + + std::string temp(glib::String(gtk_accelerator_get_label(accelerator_key, accelerator_mods)).Str()); + + // gtk_accelerator_get_label adds an extra '+' at the end of the label. + if (temp.length() > 0) + { + std::string::iterator it = temp.end() - 1; + if (*it == '+') + temp.erase(it); + } + + // Adds an extra space around the '+'. + boost::replace_all(temp, "+", " + "); + + return temp; +} + std::string FixMouseShortcut(std::string const& scut) { std::string ret(scut); diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.h unity-5.10.0/plugins/unityshell/src/ShortcutHintPrivate.h --- unity-5.8.0/plugins/unityshell/src/ShortcutHintPrivate.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutHintPrivate.h 2012-04-12 13:21:21.000000000 +0000 @@ -30,6 +30,7 @@ std::string GetMetaKey(std::string const& scut); std::string FixShortcutFormat(std::string const& scut); +std::string GetTranslatableLabel(std::string const& scut); std::string FixMouseShortcut(std::string const& scut); std::string ProperCase(std::string const& str); diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutModel.cpp unity-5.10.0/plugins/unityshell/src/ShortcutModel.cpp --- unity-5.8.0/plugins/unityshell/src/ShortcutModel.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutModel.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -25,7 +25,7 @@ { // Ctor -Model::Model(std::list& hints) +Model::Model(std::list& hints) { for (auto hint : hints) AddHint(hint); @@ -37,14 +37,14 @@ } -void Model::AddHint(AbstractHint* hint) +void Model::AddHint(AbstractHint::Ptr hint) { if (!hint) return; - + if (hints_.find(hint->category()) == hints_.end()) categories_.push_back(hint->category()); - + hints_[hint->category()].push_back(hint); } diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutModel.h unity-5.10.0/plugins/unityshell/src/ShortcutModel.h --- unity-5.8.0/plugins/unityshell/src/ShortcutModel.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutModel.h 2012-04-12 13:21:21.000000000 +0000 @@ -16,7 +16,7 @@ * * Authored by: Andrea Azzarone */ - + #ifndef UNITYSHELL_SHORTCUSMODEL_H #define UNITYSHELL_SHORTCUSMODEL_H @@ -39,23 +39,23 @@ public: typedef std::shared_ptr Ptr; - // Ctor and dtor - Model(std::list& hints); + // Ctor and dtor + Model(std::list& hints); ~Model(); - + // Accessors std::vector& categories() { return categories_; } - std::map>& hints() { return hints_; } - - void Fill(); - + std::map>& hints() { return hints_; } + + void Fill(); + private: // Private functions - void AddHint(AbstractHint* hint); + void AddHint(AbstractHint::Ptr hint); // Private members std::vector categories_; - std::map> hints_; + std::map> hints_; }; } // shortcut diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutView.cpp unity-5.10.0/plugins/unityshell/src/ShortcutView.cpp --- unity-5.8.0/plugins/unityshell/src/ShortcutView.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutView.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -25,6 +25,7 @@ #include "LineSeparator.h" #include "StaticCairoText.h" +#include "UScreen.h" namespace unity { @@ -38,12 +39,36 @@ int SHORTKEY_COLUMN_WIDTH = 150; int DESCRIPTION_COLUMN_WIDTH = 265; int LINE_SPACING = 5; -} // namespace anonymouse + + // We need this class because SetVisible doesn't work for layouts. + class SectionView : public nux::View + { + public: + SectionView(NUX_FILE_LINE_DECL) + : nux::View(NUX_FILE_LINE_PARAM) + { + } + + protected: + void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) + { + } + + void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) + { + if (GetLayout()) + GetLayout()->ProcessDraw(graphics_engine, force_draw); + } + }; + +} // unnamed namespace NUX_IMPLEMENT_OBJECT_TYPE(View); View::View() : ui::UnityWindowView() + , x_adjustment_(0) + , y_adjustment_(0) { layout_ = new nux::VLayout(); layout_->SetPadding(50, 38); @@ -91,6 +116,33 @@ return model_; } +void View::SetAdjustment(int x, int y) +{ + x_adjustment_ = x; + y_adjustment_ = y; +} + +bool View::GetBaseGeometry(nux::Geometry& geo) +{ + UScreen* uscreen = UScreen::GetDefault(); + int primary_monitor = uscreen->GetMonitorWithMouse(); + auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); + + int w = GetAbsoluteWidth(); + int h = GetAbsoluteHeight(); + + if (x_adjustment_ + w > monitor_geo.width || + y_adjustment_ + h > monitor_geo.height) + return false; + + geo.width = w; + geo.height = h; + + geo.x = monitor_geo.x + x_adjustment_ + (monitor_geo.width - geo.width - x_adjustment_) / 2; + geo.y = monitor_geo.y + y_adjustment_ + (monitor_geo.height - geo.height - y_adjustment_) / 2; + return true; +} + nux::LinearLayout* View::CreateSectionLayout(const char* section_name) { nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); @@ -109,9 +161,13 @@ return layout; } -nux::LinearLayout* View::CreateShortKeyEntryLayout(AbstractHint* hint) +nux::View* View::CreateShortKeyEntryView(AbstractHint::Ptr const& hint) { + nux::View* view = new SectionView(NUX_TRACKER_LOCATION); + nux::HLayout* layout = new nux::HLayout("EntryLayout", NUX_TRACKER_LOCATION); + view->SetLayout(layout); + nux::HLayout* shortkey_layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::HLayout* description_layout = new nux::HLayout(NUX_TRACKER_LOCATION); @@ -152,17 +208,18 @@ 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 = ""; + auto on_shortkey_changed = [](std::string const& new_shortkey, nux::View* main_view, nux::StaticText* view) { + std::string skey(""); skey += new_shortkey; skey += ""; view->SetText(skey); + main_view->SetVisible(!new_shortkey.empty()); }; - hint->shortkey.changed.connect(sigc::bind(sigc::slot(on_shortkey_changed), shortkey_view)); + hint->shortkey.changed.connect(sigc::bind(sigc::slot(on_shortkey_changed), view, shortkey_view)); - return layout; + return view; } nux::LinearLayout* View::CreateIntermediateLayout() @@ -208,12 +265,9 @@ 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); + nux::View* view = CreateShortKeyEntryView(hint); + view->SetVisible(!hint->shortkey().empty()); + intermediate_layout->AddView(view, 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); } section_layout->AddLayout(intermediate_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); diff -Nru unity-5.8.0/plugins/unityshell/src/ShortcutView.h unity-5.10.0/plugins/unityshell/src/ShortcutView.h --- unity-5.8.0/plugins/unityshell/src/ShortcutView.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ShortcutView.h 2012-04-12 13:21:21.000000000 +0000 @@ -46,11 +46,13 @@ // Ctor and dtor View(); ~View(); - + // Public methods + bool GetBaseGeometry(nux::Geometry&); + void SetAdjustment(int x, int y); void SetModel(Model::Ptr model); Model::Ptr GetModel(); - + protected: // Protected methods void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry clip); @@ -59,17 +61,20 @@ private: // Private methods nux::LinearLayout* CreateSectionLayout(const char* section_name); - nux::LinearLayout* CreateShortKeyEntryLayout(AbstractHint* hint); + nux::View* CreateShortKeyEntryView(AbstractHint::Ptr const& hint); nux::LinearLayout* CreateIntermediateLayout(); void RenderColumns(); - + // Private members Model::Ptr model_; nux::VLayout* layout_; nux::HLayout* columns_layout_; std::vector columns_; + + int x_adjustment_; + int y_adjustment_; }; } // namespace shortcut diff -Nru unity-5.8.0/plugins/unityshell/src/SimpleLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/SimpleLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/SimpleLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SimpleLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include #include "SimpleLauncherIcon.h" #include "PluginAdapter.h" @@ -148,6 +149,12 @@ return "SimpleLauncherIcon"; } +void SimpleLauncherIcon::AddProperties(GVariantBuilder* builder) +{ + LauncherIcon::AddProperties(builder); + variant::BuilderWrapper(builder).add("icon_name", icon_name); +} + } // namespace launcher } // namespace unity diff -Nru unity-5.8.0/plugins/unityshell/src/SimpleLauncherIcon.h unity-5.10.0/plugins/unityshell/src/SimpleLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/SimpleLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SimpleLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -47,6 +47,8 @@ protected: std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + virtual void OnMouseDown(int button, int monitor); virtual void OnMouseUp(int button, int monitor); virtual void OnMouseClick(int button, int monitor); diff -Nru unity-5.8.0/plugins/unityshell/src/SingleMonitorLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/SingleMonitorLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/SingleMonitorLauncherIcon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SingleMonitorLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,75 @@ +// -*- 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 "SingleMonitorLauncherIcon.h" +#include "MultiMonitor.h" + +namespace unity +{ +namespace launcher +{ + +SingleMonitorLauncherIcon::SingleMonitorLauncherIcon(int monitor) + : SimpleLauncherIcon() + , monitor_(monitor) +{ + UpdateMonitor(); +} + +void SingleMonitorLauncherIcon::UpdateMonitor() +{ + for (int i = 0; i < max_num_monitors; ++i) + { + SetVisibleOnMonitor(i, i == monitor_); + } + + EmitNeedsRedraw(); +} + +void SingleMonitorLauncherIcon::SetMonitor(int monitor) +{ + if (monitor != monitor_) + { + monitor_ = monitor; + UpdateMonitor(); + } +} + +int SingleMonitorLauncherIcon::GetMonitor() +{ + return monitor_; +} + +std::string SingleMonitorLauncherIcon::GetName() const +{ + return "SingleMonitorLauncherIcon"; +} + +void SingleMonitorLauncherIcon::AddProperties(GVariantBuilder* builder) +{ + SimpleLauncherIcon::AddProperties(builder); + + variant::BuilderWrapper(builder).add("monitor", monitor_); +} + +} // namespace launcher +} // namespace unity + diff -Nru unity-5.8.0/plugins/unityshell/src/SingleMonitorLauncherIcon.h unity-5.10.0/plugins/unityshell/src/SingleMonitorLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/SingleMonitorLauncherIcon.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SingleMonitorLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,52 @@ +// -*- 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 UNITYSHELL_SINGLE_MONITOR_LAUNCHER_ICON_H +#define UNITYSHELL_SINGLE_MONITOR_LAUNCHER_ICON_H + +#include "SimpleLauncherIcon.h" + +namespace unity +{ +namespace launcher +{ + +class SingleMonitorLauncherIcon : public SimpleLauncherIcon +{ + +public: + SingleMonitorLauncherIcon(int monitor); + +void SetMonitor(int monitor); +int GetMonitor(); + +protected: + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + +private: + void UpdateMonitor(); + + int monitor_; +}; + +} +} + +#endif // UNITYSHELL_SINGLE_MONITOR_LAUNCHER_ICON_H diff -Nru unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-04-13 16:25:29.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -18,29 +18,42 @@ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ +#include #include #include "SoftwareCenterLauncherIcon.h" +#include "Launcher.h" +#include "LauncherDragWindow.h" +#include "LauncherModel.h" namespace unity { namespace launcher { +NUX_IMPLEMENT_OBJECT_TYPE(SoftwareCenterLauncherIcon); + SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(BamfApplication* app, std::string const& aptdaemon_trans_id, std::string const& icon_path) : BamfLauncherIcon(app), - _aptdaemon_trans("org.debian.apt", + aptdaemon_trans_("org.debian.apt", aptdaemon_trans_id, "org.debian.apt.transaction", G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) +, finished_(true) +, needs_urgent_(false) { - _aptdaemon_trans.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged)); - _aptdaemon_trans.Connect("Finished", [&] (GVariant *) { + + aptdaemon_trans_.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged)); + aptdaemon_trans_.Connect("Finished", [&] (GVariant *) + { tooltip_text = BamfName(); SetQuirk(QUIRK_PROGRESS, false); + SetQuirk(QUIRK_URGENT, true); SetProgress(0.0f); + finished_ = true; + needs_urgent_ = true; }); SetIconType(TYPE_APPLICATION); @@ -48,27 +61,102 @@ tooltip_text = _("Waiting to install"); } -void -SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params) +void SoftwareCenterLauncherIcon::Animate(nux::ObjectPtr launcher, + int icon_x, + int icon_y, + int icon_size) +{ + int target_x = 0; + int target_y = 0; + + launcher_ = launcher; + + icon_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture( + launcher->GetIconSize(), + launcher->GetIconSize(), + 1, + nux::BITFMT_R8G8B8A8); + + drag_window_ = new LauncherDragWindow(icon_texture_); + + launcher->RenderIconToTexture(nux::GetWindowThread()->GetGraphicsEngine(), + AbstractLauncherIcon::Ptr(this), + icon_texture_); + nux::Geometry geo = drag_window_->GetGeometry(); + drag_window_->SetBaseXY(icon_x, icon_y); + drag_window_->ShowWindow(true); + drag_window_->SinkReference(); + + // Find out the center of last BamfLauncherIcon with non-zero co-ordinates + auto bamf_icons = launcher->GetModel()->GetSublist(); + //TODO: don't iterate through them and pick the last one, just use back() to get the last one. + for (auto current_bamf_icon : bamf_icons) + { + int x = (int) current_bamf_icon->GetCenter(launcher->monitor).x; + int y = (int) current_bamf_icon->GetCenter(launcher->monitor).y; + if (x != 0 && y != 0) + { + target_x = x; + target_y = y; + } + } + + target_y = target_y + (launcher->GetIconSize() / 2); + drag_window_->SetAnimationTarget(target_x, target_y); + + drag_window_->on_anim_completed = drag_window_->anim_completed.connect(sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnDragAnimationFinished)); + drag_window_->StartAnimation(); +} + +void SoftwareCenterLauncherIcon::OnDragAnimationFinished() +{ + drag_window_->ShowWindow(false); + launcher_->icon_animation_complete.emit(AbstractLauncherIcon::Ptr(this)); + drag_window_ = nullptr; +} + +void SoftwareCenterLauncherIcon::ActivateLauncherIcon(ActionArg arg) +{ + if (finished_) + { + if (needs_urgent_) + { + SetQuirk(QUIRK_URGENT, false); + needs_urgent_ = false; + } + BamfLauncherIcon::ActivateLauncherIcon(arg); + } + else + SetQuirk(QUIRK_STARTING, false); +} + +void SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params) { gint32 progress; glib::String property_name; - g_variant_get_child(params, 0, "s", property_name.AsOutParam()); + g_variant_get_child(params, 0, "s", &property_name); if (property_name.Str() == "Progress") { - GVariant* property_value; + GVariant* property_value = nullptr; g_variant_get_child(params, 1, "v", &property_value); g_variant_get(property_value, "i", &progress); if (progress < 100) + { SetQuirk(QUIRK_PROGRESS, true); + finished_ = false; + } SetProgress(progress/100.0f); g_variant_unref(property_value); } +} +std::string SoftwareCenterLauncherIcon::GetName() const +{ + return "SoftwareCenterLauncherIcon"; } } diff -Nru unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.h unity-5.10.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SoftwareCenterLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -21,25 +21,45 @@ #ifndef SOFTWARE_CENTER_LAUNCHERICON_H #define SOFTWARE_CENTER_LAUNCHERICON_H -#include "BamfLauncherIcon.h" #include +#include "BamfLauncherIcon.h" + +class LauncherDragWindow; namespace unity { namespace launcher { +class Launcher; class SoftwareCenterLauncherIcon : public BamfLauncherIcon { + NUX_DECLARE_OBJECT_TYPE(SoftwareCenterLauncherIcon, BamfLauncherIcon); public: + typedef nux::ObjectPtr Ptr; + SoftwareCenterLauncherIcon(BamfApplication* app, std::string const& aptdaemon_trans_id, std::string const& icon_path); + void Animate(nux::ObjectPtr launcher, int icon_x, int icon_y, int icon_size); + + std::string GetName() const; + +protected: + void ActivateLauncherIcon(ActionArg arg); + private: void OnPropertyChanged(GVariant* params); + void OnDragAnimationFinished(); + + glib::DBusProxy aptdaemon_trans_; - glib::DBusProxy _aptdaemon_trans; + nux::ObjectPtr icon_texture_; + nux::ObjectPtr drag_window_; + nux::ObjectPtr launcher_; + bool finished_; + bool needs_urgent_; }; } diff -Nru unity-5.8.0/plugins/unityshell/src/SpacerLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/SpacerLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/SpacerLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SpacerLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -27,8 +27,8 @@ namespace launcher { -SpacerLauncherIcon::SpacerLauncherIcon() - : SimpleLauncherIcon() +SpacerLauncherIcon::SpacerLauncherIcon(int monitor) + : SingleMonitorLauncherIcon(monitor) { SetQuirk(QUIRK_VISIBLE, true); SetQuirk(QUIRK_RUNNING, false); diff -Nru unity-5.8.0/plugins/unityshell/src/SpacerLauncherIcon.h unity-5.10.0/plugins/unityshell/src/SpacerLauncherIcon.h --- unity-5.8.0/plugins/unityshell/src/SpacerLauncherIcon.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SpacerLauncherIcon.h 2012-04-12 13:21:21.000000000 +0000 @@ -20,17 +20,17 @@ #ifndef SPACERLAUNCHERICON_H #define SPACERLAUNCHERICON_H -#include "SimpleLauncherIcon.h" +#include "SingleMonitorLauncherIcon.h" namespace unity { namespace launcher { -class SpacerLauncherIcon : public SimpleLauncherIcon +class SpacerLauncherIcon : public SingleMonitorLauncherIcon { public: - SpacerLauncherIcon(); + SpacerLauncherIcon(int monitor); bool IsSpacer() { diff -Nru unity-5.8.0/plugins/unityshell/src/StaticCairoText.cpp unity-5.10.0/plugins/unityshell/src/StaticCairoText.cpp --- unity-5.8.0/plugins/unityshell/src/StaticCairoText.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/StaticCairoText.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -42,6 +42,8 @@ StaticCairoText::StaticCairoText(std::string const& text, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM), + _cached_base_width(-1), + _cached_base_height(-1), _baseline(0), _fontstring(NULL), _cairoGraphics(NULL), diff -Nru unity-5.8.0/plugins/unityshell/src/SwitcherController.cpp unity-5.10.0/plugins/unityshell/src/SwitcherController.cpp --- unity-5.8.0/plugins/unityshell/src/SwitcherController.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SwitcherController.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -34,9 +34,17 @@ namespace switcher { +namespace +{ +gboolean OnDetailTimerCb(gpointer data); +} Controller::Controller(unsigned int load_timeout) - : construct_timeout_(load_timeout) + : timeout_length(75) + , detail_on_timeout(true) + , detail_timeout_length(500) + , initial_detail_timeout_length(1500) + , construct_timeout_(load_timeout) , view_window_(nullptr) , main_layout_(nullptr) , monitor_(0) @@ -47,10 +55,6 @@ , view_idle_timer_(0) , bg_color_(0, 0, 0, 0.5) { - timeout_length = 75; - detail_on_timeout = true; - detail_timeout_length = 1500; - ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &Controller::OnBackgroundUpdate)); /* Construct the view after a prefixed timeout, to improve the startup time */ @@ -132,11 +136,11 @@ { if (detail_timer_) g_source_remove (detail_timer_); - detail_timer_ = g_timeout_add(detail_timeout_length, &Controller::OnDetailTimer, this); + detail_timer_ = g_timeout_add(initial_detail_timeout_length, OnDetailTimerCb, this); } ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); - ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new_boolean(true)); + ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", true, monitor_)); } void Controller::Select(int index) @@ -145,17 +149,15 @@ model_->Select(index); } -gboolean Controller::OnDetailTimer(gpointer data) +gboolean Controller::OnDetailTimer() { - Controller* self = static_cast(data); - - if (self->visible_ && !self->model_->detail_selection) + if (visible_ && !model_->detail_selection) { - self->SetDetail(true, 2); - self->detail_mode_ = TAB_NEXT_WINDOW; + SetDetail(true, 2); + detail_mode_ = TAB_NEXT_WINDOW; } - self->detail_timer_ = 0; + detail_timer_ = 0; return FALSE; } @@ -166,11 +168,19 @@ if (detail_timer_) g_source_remove(detail_timer_); - detail_timer_ = g_timeout_add(detail_timeout_length, &Controller::OnDetailTimer, this); + detail_timer_ = g_timeout_add(detail_timeout_length, OnDetailTimerCb, this); } - ubus_manager_.SendMessage(UBUS_SWITCHER_SELECTION_CHANGED, - g_variant_new_string(icon->tooltip_text().c_str())); + if (icon) + { + if (!visible_) + { + ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", true, monitor_)); + } + + ubus_manager_.SendMessage(UBUS_SWITCHER_SELECTION_CHANGED, + g_variant_new_string(icon->tooltip_text().c_str())); + } } void Controller::ShowView() @@ -295,7 +305,7 @@ g_source_remove(detail_timer_); detail_timer_ = 0; - ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new_boolean(false)); + ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", false, monitor_)); view_.Release(); } @@ -494,10 +504,21 @@ unity::variant::BuilderWrapper(builder) .add("timeout-length", timeout_length()) .add("detail-on-timeout", detail_on_timeout()) + .add("initial-detail-timeout-length", initial_detail_timeout_length()) .add("detail-timeout-length", detail_timeout_length()) .add("visible", visible_) .add("detail-mode", detail_mode_); } +namespace +{ + +gboolean OnDetailTimerCb(gpointer data) +{ + Controller* controller = static_cast(data); + return controller->OnDetailTimer(); +} + +} } } diff -Nru unity-5.8.0/plugins/unityshell/src/SwitcherController.h unity-5.10.0/plugins/unityshell/src/SwitcherController.h --- unity-5.8.0/plugins/unityshell/src/SwitcherController.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/SwitcherController.h 2012-04-12 13:21:21.000000000 +0000 @@ -69,6 +69,7 @@ nux::Property timeout_length; nux::Property detail_on_timeout; nux::Property detail_timeout_length; + nux::Property initial_detail_timeout_length; void Show(ShowMode show, SortMode sort, bool reverse, std::vector results); void Hide(bool accept_state=true); @@ -84,6 +85,7 @@ void Select (int index); void SetDetail(bool detail, unsigned int min_windows = 1); + virtual gboolean OnDetailTimer(); void SelectFirstItem(); @@ -102,6 +104,8 @@ virtual void ConstructView(); virtual void ShowView(); + void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr icon); + unsigned int construct_timeout_; private: @@ -112,7 +116,6 @@ TAB_NEXT_TILE, }; - void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr icon); void OnBackgroundUpdate(GVariant* data); SwitcherModel::Ptr model_; @@ -133,8 +136,6 @@ nux::Color bg_color_; DetailMode detail_mode_; - static gboolean OnDetailTimer(gpointer data); - static bool CompareSwitcherItemsPriority(launcher::AbstractLauncherIcon::Ptr first, launcher::AbstractLauncherIcon::Ptr second); }; diff -Nru unity-5.8.0/plugins/unityshell/src/TrashLauncherIcon.cpp unity-5.10.0/plugins/unityshell/src/TrashLauncherIcon.cpp --- unity-5.8.0/plugins/unityshell/src/TrashLauncherIcon.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/TrashLauncherIcon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -22,6 +22,7 @@ #include #include +#include #include "Launcher.h" #include "QuicklistManager.h" @@ -31,9 +32,14 @@ { namespace launcher { +namespace +{ + nux::logging::Logger logger("unity.launcher.TrashLauncherIcon"); +} TrashLauncherIcon::TrashLauncherIcon() : SimpleLauncherIcon() + , on_trash_changed_handler_id_(0) , proxy_("org.gnome.Nautilus", "/org/gnome/Nautilus", "org.gnome.Nautilus.FileOperations") { tooltip_text = _("Trash"); @@ -45,15 +51,23 @@ glib::Object location(g_file_new_for_uri("trash:///")); + glib::Error err; trash_monitor_ = g_file_monitor_directory(location, G_FILE_MONITOR_NONE, NULL, - NULL); + &err); - on_trash_changed_handler_id_ = g_signal_connect(trash_monitor_, + if (err) + { + LOG_ERROR(logger) << "Could not create file monitor for trash uri: " << err; + } + else + { + on_trash_changed_handler_id_ = g_signal_connect(trash_monitor_, "changed", G_CALLBACK(&TrashLauncherIcon::OnTrashChanged), this); + } UpdateTrashIcon(); } diff -Nru unity-5.8.0/plugins/unityshell/src/UBusMessages.h unity-5.10.0/plugins/unityshell/src/UBusMessages.h --- unity-5.8.0/plugins/unityshell/src/UBusMessages.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/UBusMessages.h 2012-04-12 13:21:21.000000000 +0000 @@ -48,6 +48,7 @@ #define UBUS_LAUNCHER_END_KEY_NAV "LAUNCHER_END_KEY_NAV" #define UBUS_LAUNCHER_START_KEY_SWTICHER "LAUNCHER_START_KEY_SWITCHER" #define UBUS_LAUNCHER_END_KEY_SWTICHER "LAUNCHER_END_KEY_SWITCHER" +#define UBUS_LAUNCHER_SELECTION_CHANGED "LAUNCHER_ICON_SELECTION_CHANGED" #define UBUS_LAUNCHER_ICON_URGENT_CHANGED "LAUNCHER_ICON_URGENT_CHANGED" #define UBUS_QUICKLIST_START_KEY_NAV "QUICKLIST_START_KEY_NAV" #define UBUS_QUICKLIST_END_KEY_NAV "QUICKLIST_END_KEY_NAV" @@ -89,4 +90,7 @@ #define UBUS_SWITCHER_SHOWN "SWITCHER_SHOWN" #define UBUS_SWITCHER_SELECTION_CHANGED "SWITCHER_SELECTION_CHANGED" +// Signal sent when someone thinks the decoration might got damanged by a paint +#define UBUS_DASH_DECORATION_DAMAGED "DASH_DECORATION_DAMAGED" + #endif // UBUS_MESSAGES_H diff -Nru unity-5.8.0/plugins/unityshell/src/ubus-server.cpp unity-5.10.0/plugins/unityshell/src/ubus-server.cpp --- unity-5.8.0/plugins/unityshell/src/ubus-server.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/ubus-server.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -272,6 +272,7 @@ if (dispatch_list == NULL) { + ubus_message_info_free(info); continue; // no handlers for this message } diff -Nru unity-5.8.0/plugins/unityshell/src/unity-places-simple-tile-accessible.cpp unity-5.10.0/plugins/unityshell/src/unity-places-simple-tile-accessible.cpp --- unity-5.8.0/plugins/unityshell/src/unity-places-simple-tile-accessible.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/unity-places-simple-tile-accessible.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -129,7 +129,7 @@ tile = dynamic_cast(nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj))); if (tile != NULL) { - name = tile->GetLabel(); + name = tile->GetLabel().c_str(); pango_parse_markup(name, -1, 0, NULL, &self->priv->stripped_name, NULL, NULL); diff -Nru unity-5.8.0/plugins/unityshell/src/unityshell.cpp unity-5.10.0/plugins/unityshell/src/unityshell.cpp --- unity-5.8.0/plugins/unityshell/src/unityshell.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/unityshell.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -44,9 +44,11 @@ #include #include #include +#include #include #include +#include #include @@ -106,7 +108,6 @@ , cScreen(CompositeScreen::get(screen)) , gScreen(GLScreen::get(screen)) , enable_shortcut_overlay_(true) - , gestureEngine(nullptr) , wt(nullptr) , panelWindow(nullptr) , debugger(nullptr) @@ -123,11 +124,12 @@ #ifndef USE_GLES , _active_fbo (0) #endif - , dash_is_open_ (false) , grab_index_ (0) , painting_tray_ (false) , last_scroll_event_(0) , hud_keypress_time_(0) + , panel_texture_has_changed_(true) + , paint_panel_(false) { Timer timer; gfloat version; @@ -343,14 +345,20 @@ ubus_manager_.RegisterInterest(UBUS_LAUNCHER_START_KEY_NAV, sigc::mem_fun(this, &UnityScreen::OnLauncherStartKeyNav)); + ubus_manager_.RegisterInterest(UBUS_LAUNCHER_START_KEY_SWTICHER, + sigc::mem_fun(this, &UnityScreen::OnLauncherStartKeyNav)); + ubus_manager_.RegisterInterest(UBUS_LAUNCHER_END_KEY_NAV, sigc::mem_fun(this, &UnityScreen::OnLauncherEndKeyNav)); + ubus_manager_.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWTICHER, + sigc::mem_fun(this, &UnityScreen::OnLauncherEndKeyNav)); + g_idle_add_full (G_PRIORITY_DEFAULT, &UnityScreen::initPluginActions, this, NULL); super_keypressed_ = false; - GeisAdapter::Default()->Run(); - gestureEngine = new GestureEngine(screen); + geis_adapter_.Run(); + gesture_engine_.reset(new GestureEngine(screen)); CompString name(PKGDATADIR"/panel-shadow.png"); CompString pname("unityshell"); @@ -359,14 +367,25 @@ BackgroundEffectHelper::updates_enabled = true; - ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&](GVariant * args) { - dash_is_open_ = true; - dash_monitor_ = g_variant_get_int32(args); - RaiseInputWindows(); + ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&](GVariant * data) + { + 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); + + dash_monitor_ = overlay_monitor; + + RaiseInputWindows(); }); - ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, [&](GVariant * args) { dash_is_open_ = false; }); - LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s"; + + Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default());; + XSelectInput(display, GDK_ROOT_WINDOW(), PropertyChangeMask); + LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s"; } + + panel::Style::Instance().changed.connect(sigc::mem_fun(this, &UnityScreen::OnPanelStyleChanged)); } UnityScreen::~UnityScreen() @@ -541,7 +560,7 @@ float vc[4]; float h = 20.0f; float w = 1.0f; - float panel_h = 24.0f; + float panel_h = panel_style_.panel_height; float x1 = output->x(); float y1 = output->y() + panel_h; @@ -571,7 +590,8 @@ i++; } - if (!(dash_is_open_ && current_monitor == dash_monitor_) && panel_controller_->opacity() > 0.0f) + if (!(launcher_controller_->IsOverlayOpen() && current_monitor == dash_monitor_) + && panel_controller_->opacity() > 0.0f) { foreach(GLTexture * tex, _shadow_texture) { @@ -622,7 +642,7 @@ float vc[4]; float h = 20.0f; float w = 1.0f; - float panel_h = 24.0f; + float panel_h = static_cast(panel_style_.panel_height); float x1 = output->x(); float y1 = output->y() + panel_h; @@ -649,7 +669,8 @@ i++; } - if (!(dash_is_open_ && current_monitor == dash_monitor_) && panel_controller_->opacity() > 0.0f) + if (!(launcher_controller_->IsOverlayOpen() && current_monitor == dash_monitor_) + && panel_controller_->opacity() > 0.0f) { foreach(GLTexture * tex, _shadow_texture) { @@ -715,6 +736,12 @@ wy = y + (last_bound.height - height) / 2; } +void +UnityScreen::OnPanelStyleChanged() +{ + panel_texture_has_changed_ = true; +} + #ifdef USE_GLES void UnityScreen::paintDisplay() #else @@ -722,10 +749,44 @@ #endif { CompOutput *output = _last_output; - Window tray_xid = panel_controller_->GetTrayXid (); #ifndef USE_GLES bool was_bound = _fbo->bound (); + + if (nux::GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath()) + { + if (was_bound && launcher_controller_->IsOverlayOpen() && paint_panel_) + { + if (panel_texture_has_changed_ || !panel_texture_.IsValid()) + { + panel_texture_.Release(); + + nux::NBitmapData* bitmap = panel::Style::Instance().GetBackground(screen->width (), screen->height(), 1.0f); + nux::BaseTexture* texture2D = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); + if (bitmap && texture2D) + { + texture2D->Update(bitmap); + panel_texture_ = texture2D->GetDeviceTexture(); + texture2D->UnReference(); + delete bitmap; + } + panel_texture_has_changed_ = false; + } + + if (panel_texture_.IsValid()) + { + nux::GetGraphicsDisplay()->GetGraphicsEngine()->ResetModelViewMatrixStack(); + nux::GetGraphicsDisplay()->GetGraphicsEngine()->Push2DTranslationModelViewMatrix(0.0f, 0.0f, 0.0f); + nux::GetGraphicsDisplay()->GetGraphicsEngine()->ResetProjectionMatrix(); + nux::GetGraphicsDisplay()->GetGraphicsEngine()->SetOrthographicProjectionMatrix(screen->width (), screen->height()); + + nux::TexCoordXForm texxform; + int panel_height = panel_style_.panel_height; + nux::GetGraphicsDisplay()->GetGraphicsEngine()->QRP_GLSL_1Tex(0, 0, screen->width (), panel_height, panel_texture_, texxform, nux::color::White); + } + } + } + _fbo->unbind (); /* Draw the bit of the relevant framebuffer for each output */ @@ -740,11 +801,11 @@ glPopMatrix (); } - nux::ObjectPtr device_texture = + nux::ObjectPtr device_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(), screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8); #else - nux::ObjectPtr device_texture = + nux::ObjectPtr device_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(gScreen->fbo ()->tex ()->name (), output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8); #endif @@ -768,64 +829,67 @@ _in_paint = false; nuxEpilogue(); - if (tray_xid && !allowWindowPaint) + for (Window tray_xid : panel_controller_->GetTrayXids()) { - CompWindow *tray = screen->findWindow (tray_xid); - - if (tray) + if (tray_xid && !allowWindowPaint) { - GLMatrix oTransform; - UnityWindow *uTrayWindow = UnityWindow::get (tray); + CompWindow *tray = screen->findWindow (tray_xid); + + if (tray) + { + GLMatrix oTransform; + UnityWindow *uTrayWindow = UnityWindow::get (tray); #ifndef USE_GLES - GLFragment::Attrib attrib (uTrayWindow->gWindow->lastPaintAttrib()); + GLFragment::Attrib attrib (uTrayWindow->gWindow->lastPaintAttrib()); #else - GLWindowPaintAttrib attrib (uTrayWindow->gWindow->lastPaintAttrib()); + GLWindowPaintAttrib attrib (uTrayWindow->gWindow->lastPaintAttrib()); #endif - unsigned int oldGlAddGeometryIndex = uTrayWindow->gWindow->glAddGeometryGetCurrentIndex (); - unsigned int oldGlDrawIndex = uTrayWindow->gWindow->glDrawGetCurrentIndex (); + unsigned int oldGlAddGeometryIndex = uTrayWindow->gWindow->glAddGeometryGetCurrentIndex (); + unsigned int oldGlDrawIndex = uTrayWindow->gWindow->glDrawGetCurrentIndex (); #ifndef USE_GLES - unsigned int oldGlDrawGeometryIndex = uTrayWindow->gWindow->glDrawGeometryGetCurrentIndex (); + unsigned int oldGlDrawGeometryIndex = uTrayWindow->gWindow->glDrawGeometryGetCurrentIndex (); #endif #ifndef USE_GLES - attrib.setOpacity (OPAQUE); - attrib.setBrightness (BRIGHT); - attrib.setSaturation (COLOR); + attrib.setOpacity (OPAQUE); + attrib.setBrightness (BRIGHT); + attrib.setSaturation (COLOR); #else - attrib.opacity = OPAQUE; - attrib.brightness = BRIGHT; - attrib.saturation = COLOR; + attrib.opacity = OPAQUE; + attrib.brightness = BRIGHT; + attrib.saturation = COLOR; #endif - oTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); + oTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); #ifndef USE_GLES - glPushMatrix (); - glLoadMatrixf (oTransform.getMatrix ()); + glPushMatrix (); + glLoadMatrixf (oTransform.getMatrix ()); #endif - painting_tray_ = true; + painting_tray_ = true; - /* force the use of the core functions */ - uTrayWindow->gWindow->glDrawSetCurrentIndex (MAXSHORT); - uTrayWindow->gWindow->glAddGeometrySetCurrentIndex ( MAXSHORT); + /* force the use of the core functions */ + uTrayWindow->gWindow->glDrawSetCurrentIndex (MAXSHORT); + uTrayWindow->gWindow->glAddGeometrySetCurrentIndex ( MAXSHORT); #ifndef USE_GLES - uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (MAXSHORT); + uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (MAXSHORT); #endif - uTrayWindow->gWindow->glDraw (oTransform, attrib, infiniteRegion, - PAINT_WINDOW_TRANSFORMED_MASK | - PAINT_WINDOW_BLEND_MASK | - PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK); + uTrayWindow->gWindow->glDraw (oTransform, attrib, infiniteRegion, + PAINT_WINDOW_TRANSFORMED_MASK | + PAINT_WINDOW_BLEND_MASK | + PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK); #ifndef USE_GLES - uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (oldGlDrawGeometryIndex); + uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (oldGlDrawGeometryIndex); #endif - uTrayWindow->gWindow->glAddGeometrySetCurrentIndex (oldGlAddGeometryIndex); - uTrayWindow->gWindow->glDrawSetCurrentIndex (oldGlDrawIndex); - painting_tray_ = false; + uTrayWindow->gWindow->glAddGeometrySetCurrentIndex (oldGlAddGeometryIndex); + uTrayWindow->gWindow->glDrawSetCurrentIndex (oldGlDrawIndex); + painting_tray_ = false; #ifndef USE_GLES - glPopMatrix (); + glPopMatrix (); #endif + } } } @@ -852,8 +916,8 @@ bool UnityScreen::forcePaintOnTop () { return !allowWindowPaint || - ((switcher_controller_->Visible() || - dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL)))); + ((switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen()) + && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL)))); } void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha) @@ -904,7 +968,9 @@ { for (CompWindow *w : screen->windows ()) { - if (UnityShowdesktopHandler::shouldHide (w)) + UnityWindow *uw = UnityWindow::get (w); + + if (ShowdesktopHandler::ShouldHide (static_cast (uw))) { UnityWindow::get (w)->enterShowDesktop (); // the animation plugin does strange things here ... @@ -941,16 +1007,16 @@ /* Where a window is inhibiting, only allow the window * that is inhibiting the leave show desktop to actually * fade in again - all other windows should remain faded out */ - if (!UnityShowdesktopHandler::inhibitingXid ()) + if (!ShowdesktopHandler::InhibitingXid ()) { for (CompWindow *cw : screen->windows ()) { if (cw->inShowDesktopMode ()) { - UnityWindow::get (cw)->leaveShowDesktop (); - // the animation plugin does strange things here ... - // if this notification is sent - //cw->windowNotify (CompWindowNotifyLeaveShowDesktopMode); + UnityWindow::get (cw)->leaveShowDesktop (); + // the animation plugin does strange things here ... + // if this notification is sent + //cw->windowNotify (CompWindowNotifyLeaveShowDesktopMode); } } @@ -960,12 +1026,12 @@ } else { - CompWindow *cw = screen->findWindow (UnityShowdesktopHandler::inhibitingXid ()); + CompWindow *cw = screen->findWindow (ShowdesktopHandler::InhibitingXid ()); if (cw) { if (cw->inShowDesktopMode ()) { - UnityWindow::get (cw)->leaveShowDesktop (); + UnityWindow::get (cw)->leaveShowDesktop (); } } } @@ -974,227 +1040,161 @@ void UnityWindow::enterShowDesktop () { if (!mShowdesktopHandler) - mShowdesktopHandler = new UnityShowdesktopHandler (window); + mShowdesktopHandler = new ShowdesktopHandler (static_cast (this)); window->setShowDesktopMode (true); - mShowdesktopHandler->fadeOut (); + mShowdesktopHandler->FadeOut (); } void UnityWindow::leaveShowDesktop () { if (mShowdesktopHandler) { - mShowdesktopHandler->fadeIn (); + mShowdesktopHandler->FadeIn (); window->setShowDesktopMode (false); - delete mShowdesktopHandler; - mShowdesktopHandler = NULL; } } void UnityWindow::activate () { - UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (window->id ()); + ShowdesktopHandler::InhibitLeaveShowdesktopMode (window->id ()); window->activate (); - UnityShowdesktopHandler::allowLeaveShowdesktopMode (window->id ()); + ShowdesktopHandler::AllowLeaveShowdesktopMode (window->id ()); } -bool UnityWindow::handleAnimations (unsigned int ms) +void UnityWindow::DoEnableFocus () { - if (mShowdesktopHandler) - if (mShowdesktopHandler->animate (ms)) - { - delete mShowdesktopHandler; - mShowdesktopHandler = NULL; - return true; - } - - return false; + window->focusSetEnabled (this, true); } -/* 300 ms */ -const unsigned int UnityShowdesktopHandler::fade_time = 300; -CompWindowList UnityShowdesktopHandler::animating_windows (0); - -bool UnityShowdesktopHandler::shouldHide (CompWindow *w) +void UnityWindow::DoDisableFocus () { - if (w->overrideRedirect ()) - return false; - - if (!w->managed ()) - return false; - - if (w->grabbed ()) - return false; - - if (w->wmType () & (CompWindowTypeDesktopMask | - CompWindowTypeDockMask)) - return false; - - if (w->state () & (CompWindowStateSkipPagerMask | - CompWindowStateSkipTaskbarMask)) - return false; - - if ((w->state () & CompWindowStateHiddenMask)) - if (!(w->inShowDesktopMode () || w->shaded ())) - return false; + window->focusSetEnabled (this, false); +} - return true; +bool UnityWindow::IsOverrideRedirect () +{ + return window->overrideRedirect (); } -guint32 UnityShowdesktopHandler::mInhibitingXid = 0; +bool UnityWindow::IsManaged () +{ + return window->managed (); +} -void -UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (guint32 xid) +bool UnityWindow::IsGrabbed () { - if (!mInhibitingXid) - mInhibitingXid = xid; + return window->grabbed (); } -void -UnityShowdesktopHandler::allowLeaveShowdesktopMode (guint32 xid) +bool UnityWindow::IsDesktopOrDock () { - if (mInhibitingXid == xid) - mInhibitingXid = 0; + return (window->type () & (CompWindowTypeDesktopMask | CompWindowTypeDockMask)); } -guint32 -UnityShowdesktopHandler::inhibitingXid () +bool UnityWindow::IsSkipTaskbarOrPager () { - return mInhibitingXid; + return (window->state () & (CompWindowStateSkipTaskbarMask | CompWindowStateSkipPagerMask)); } -UnityShowdesktopHandler::UnityShowdesktopHandler (CompWindow *w) : - mWindow (w), - mRemover (new compiz::WindowInputRemover (screen->dpy (), w->id ())), - mState (Visible), - mProgress (0.0f) +bool UnityWindow::IsInShowdesktopMode () { + return window->inShowDesktopMode (); } -UnityShowdesktopHandler::~UnityShowdesktopHandler () +bool UnityWindow::IsHidden () { - if (mRemover) - delete mRemover; + return window->state () & CompWindowStateHiddenMask; } -void UnityShowdesktopHandler::fadeOut () +bool UnityWindow::IsShaded () { - mState = UnityShowdesktopHandler::FadeOut; - mProgress = 1.0f; + return window->shaded (); +} - mWasHidden = mWindow->state () & CompWindowStateHiddenMask; +bool UnityWindow::IsMinimized () +{ + return window->minimized (); +} - if (!mWasHidden) - { - mWindow->changeState (mWindow->state () | CompWindowStateHiddenMask); - mWindow->windowNotify (CompWindowNotifyHide); - mRemover->save (); - mRemover->remove (); - } +void UnityWindow::DoOverrideFrameRegion (CompRegion ®ion) +{ + unsigned int oldUpdateFrameRegionIndex = window->updateFrameRegionGetCurrentIndex (); - CompositeWindow::get (mWindow)->addDamage (); + window->updateFrameRegionSetCurrentIndex (MAXSHORT); + window->updateFrameRegion (region); + window->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex); +} - if (std::find (animating_windows.begin(), - animating_windows.end(), - mWindow) == animating_windows.end()) - animating_windows.push_back(mWindow); +void UnityWindow::DoHide () +{ + window->changeState (window->state () | CompWindowStateHiddenMask); } -void UnityShowdesktopHandler::fadeIn () +void UnityWindow::DoNotifyHidden () { - mState = UnityShowdesktopHandler::FadeIn; + window->windowNotify (CompWindowNotifyHide); +} - if (!mWasHidden) - { - mWindow->changeState (mWindow->state () & ~CompWindowStateHiddenMask); - mWindow->windowNotify (CompWindowNotifyShow); - mRemover->restore (); - } +void UnityWindow::DoShow () +{ + window->changeState (window->state () & ~(CompWindowStateHiddenMask)); +} - CompositeWindow::get (mWindow)->addDamage (); +void UnityWindow::DoNotifyShown () +{ + window->windowNotify (CompWindowNotifyShow); } -bool UnityShowdesktopHandler::animate (unsigned int ms) +void UnityWindow::DoMoveFocusAway () { - float inc = fade_time / (float) ms; + window->moveInputFocusToOtherWindow (); +} - if (mState == UnityShowdesktopHandler::FadeOut) - { - mProgress -= inc; - if (mProgress <= 0.0f) - { - mProgress = 0.0f; - mState = Invisible; - } - else - CompositeWindow::get (mWindow)->addDamage (); - } - else if (mState == FadeIn) - { - mProgress += inc; - if (mProgress >= 1.0f) - { - mProgress = 1.0f; - mState = Visible; +ShowdesktopHandlerWindowInterface::PostPaintAction UnityWindow::DoHandleAnimations (unsigned int ms) +{ + ShowdesktopHandlerWindowInterface::PostPaintAction action = ShowdesktopHandlerWindowInterface::PostPaintAction::Wait; - return true; - } - else - CompositeWindow::get (mWindow)->addDamage (); - } + if (mShowdesktopHandler) + action = mShowdesktopHandler->Animate (ms); - return false; + return action; } -void UnityShowdesktopHandler::paintAttrib (GLWindowPaintAttrib &attrib) +void UnityWindow::DoAddDamage () { - attrib.opacity = static_cast (static_cast (attrib.opacity) * mProgress); + cWindow->addDamage (); } -unsigned int UnityShowdesktopHandler::getPaintMask () +void UnityWindow::DoDeleteHandler () { - return 0; + delete mShowdesktopHandler; + mShowdesktopHandler = NULL; + + window->updateFrameRegion (); } -void UnityShowdesktopHandler::handleEvent (XEvent *event) +compiz::WindowInputRemoverInterface::Ptr +UnityWindow::GetInputRemover () { - /* Ignore sent events from the InputRemover */ - if (screen->XShape () && event->type == - screen->shapeEvent () + ShapeNotify && - !event->xany.send_event) - { - if (mRemover) - { - mRemover->save (); - mRemover->remove (); - } - } + return compiz::WindowInputRemoverInterface::Ptr (new compiz::WindowInputRemover (screen->dpy (), window->id ())); } -void UnityShowdesktopHandler::windowNotify (CompWindowNotify n) +unsigned int +UnityWindow::GetNoCoreInstanceMask () { - if (n == CompWindowNotifyFocusChange && mWindow->minimized ()) - { - for (CompWindow *w : animating_windows) - w->focusSetEnabled (UnityWindow::get (w), false); - - mWindow->moveInputFocusToOtherWindow (); - - for (CompWindow *w : animating_windows) - w->focusSetEnabled (UnityWindow::get (w), true); - } + return PAINT_WINDOW_NO_CORE_INSTANCE_MASK; } -void UnityShowdesktopHandler::updateFrameRegion (CompRegion &r) +void UnityWindow::handleEvent (XEvent *event) { - unsigned int oldUpdateFrameRegionIndex; - r = CompRegion (); - - /* Ensure no other plugins can touch this frame region */ - oldUpdateFrameRegionIndex = mWindow->updateFrameRegionGetCurrentIndex (); - mWindow->updateFrameRegionSetCurrentIndex (MAXSHORT); - mWindow->updateFrameRegion (r); - mWindow->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex); + if (screen->XShape () && + event->type == screen->shapeEvent () + ShapeNotify && + !event->xany.send_event) + { + if (mShowdesktopHandler) + mShowdesktopHandler->HandleShapeEvent (); + } } /* called whenever we need to repaint parts of the screen */ @@ -1209,6 +1209,7 @@ doShellRepaint = true; allowWindowPaint = true; _last_output = output; + paint_panel_ = false; #ifndef USE_GLES /* bind the framebuffer here @@ -1275,16 +1276,10 @@ void UnityScreen::preparePaint(int ms) { - CompWindowList remove_windows; - cScreen->preparePaint(ms); - for (CompWindow *w : UnityShowdesktopHandler::animating_windows) - if (UnityWindow::get (w)->handleAnimations (ms)) - remove_windows.push_back(w); - - for (CompWindow *w : remove_windows) - UnityShowdesktopHandler::animating_windows.remove (w); + for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows) + wi->HandleAnimations (ms); if (damaged) { @@ -1294,6 +1289,28 @@ } +void UnityScreen::donePaint() +{ + std::list remove_windows; + + for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows) + { + ShowdesktopHandlerWindowInterface::PostPaintAction action = wi->HandleAnimations (0); + if (action == ShowdesktopHandlerWindowInterface::PostPaintAction::Remove) + remove_windows.push_back(wi); + else if (action == ShowdesktopHandlerWindowInterface::PostPaintAction::Damage) + wi->AddDamage (); + } + + for (ShowdesktopHandlerWindowInterface *wi : remove_windows) + { + wi->DeleteHandler (); + ShowdesktopHandler::animating_windows.remove (wi); + } + + cScreen->donePaint (); +} + /* Grab changed nux regions and add damage rects for them */ void UnityScreen::damageNuxRegions() { @@ -1340,7 +1357,7 @@ #ifndef USE_GLES cScreen->damageScreen(); // evil hack #endif - if (_key_nav_mode_requested) + if (_key_nav_mode_requested && !launcher_controller_->IsOverlayOpen()) launcher_controller_->KeyNavGrab(); _key_nav_mode_requested = false; break; @@ -1429,7 +1446,11 @@ break; } case MapRequest: - UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (event->xmaprequest.window); + ShowdesktopHandler::InhibitLeaveShowdesktopMode (event->xmaprequest.window); + break; + case PropertyNotify: + if (event->xproperty.window == GDK_ROOT_WINDOW()) + _bghash.RefreshColor(); break; default: if (screen->shapeEvent () + ShapeNotify == event->type) @@ -1441,8 +1462,7 @@ { UnityWindow *uw = UnityWindow::get (w); - if (uw->mShowdesktopHandler) - uw->mShowdesktopHandler->handleEvent(event); + uw->handleEvent(event); } } break; @@ -1463,7 +1483,7 @@ } break; case MapRequest: - UnityShowdesktopHandler::allowLeaveShowdesktopMode (event->xmaprequest.window); + ShowdesktopHandler::AllowLeaveShowdesktopMode (event->xmaprequest.window); break; } @@ -1520,7 +1540,7 @@ PluginAdapter::Default()->NotifyCompizEvent(plugin, event, option); compiz::CompizMinimizedWindowHandler::handleCompizEvent (plugin, event, option); - if (dash_is_open_ && g_strcmp0(event, "start_viewport_switch") == 0) + if (launcher_controller_->IsOverlayOpen() && g_strcmp0(event, "start_viewport_switch") == 0) { ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); } @@ -1543,32 +1563,15 @@ if (!shortcut_controller_->Visible() && shortcut_controller_->IsEnabled()) { - static nux::Geometry last_geo; - UScreen* uscreen = UScreen::GetDefault(); - int primary_monitor = uscreen->GetMonitorWithMouse(); - auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); - - int width = 970; - int height = 680; int launcher_width = optionGetIconSize() + 18; - int panel_height = 24; - int x = monitor_geo.x + launcher_width + (monitor_geo.width - launcher_width- width) / 2; - int y = monitor_geo.y + panel_height + (monitor_geo.height - panel_height - height) / 2; - - nux::Geometry geo (x, y, width, height); - - if (last_geo != geo) - { - shortcut_controller_->SetWorkspace(geo); - last_geo = geo; - } + int panel_height = panel_style_.panel_height; - if (last_geo.x > monitor_geo.x and last_geo.y > monitor_geo.y) + if (shortcut_controller_->Show()) { + shortcut_controller_->SetAdjustment(launcher_width, panel_height); EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, true, action->key().modifiers()); - shortcut_controller_->Show(); } - } + } return true; } @@ -1589,6 +1592,9 @@ LOG_DEBUG(logger) << "Super released: " << (was_tap ? "tapped" : "released"); int when = options[7].value().i(); // XEvent time in millisec + if (hud_controller_->IsVisible() && launcher_controller_->AboutToShowDash(was_tap, when)) + hud_controller_->HideHud(); + super_keypressed_ = false; launcher_controller_->KeyNavTerminate(true); launcher_controller_->HandleLauncherKeyRelease(was_tap, when); @@ -1624,6 +1630,7 @@ * keyboard and the Alt key is still pressed */ action->setState(action->state() | CompAction::StateTermKey); panel_controller_->FirstMenuShow(); + return true; } @@ -1637,6 +1644,10 @@ void UnityScreen::SendExecuteCommand() { + if (hud_controller_->IsVisible()) + { + hud_controller_->HideHud(); + } ubus_manager_.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "commands.lens", 0, "")); } @@ -1927,10 +1938,55 @@ PluginAdapter::Default ()->restoreInputFocus (); } +bool UnityScreen::ShowHud() +{ + if (switcher_controller_->Visible()) + { + LOG_ERROR(logger) << "this should never happen"; + return false; // early exit if the switcher is open + } + + if (hud_controller_->IsVisible()) + { + ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST); + } + else + { + // Handles closing KeyNav (Alt+F1) if the hud is about to show + if (launcher_controller_->KeyNavIsActive()) + launcher_controller_->KeyNavTerminate(false); + + // If an overlay is open, it must be the dash! Close it! + if (launcher_controller_->IsOverlayOpen()) + dash_controller_->HideDash(); + + hud_controller_->ShowHud(); + } + + // Consume the event. + return true; +} + bool UnityScreen::ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) { + // Look to see if there is a keycode. If there is, then this isn't a + // modifier only keybinding. + int key_code = 0; + if (options[6].type() != CompOption::TypeUnset) + { + key_code = options[6].value().i(); + LOG_DEBUG(logger) << "HUD initiate key code: " << key_code; + // show it now, no timings or terminate needed. + return ShowHud(); + } + else + { + LOG_DEBUG(logger) << "HUD initiate key code option not set, modifier only keypress."; + } + + // to receive the Terminate event if (state & CompAction::StateInitKey) action->setState(action->state() | CompAction::StateTermKey); @@ -1951,7 +2007,7 @@ action->setState(action->state() & ~CompAction::StateTermKey); - // And only respond to key taps + // If we have a modifier only keypress, check for tap and timing. if (!(state & CompAction::StateTermTapped)) return false; @@ -1963,27 +2019,7 @@ return false; } - if (switcher_controller_->Visible()) - { - LOG_ERROR(logger) << "this should never happen"; - return false; // early exit if the switcher is open - } - - if (hud_controller_->IsVisible()) - { - ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST); - } - else - { - // Handles closing KeyNav (Alt+F1) if the hud is about to show - if (launcher_controller_->KeyNavIsActive()) - { - launcher_controller_->KeyNavTerminate(false); - } - hud_controller_->ShowHud(); - } - - return true; + return ShowHud(); } gboolean UnityScreen::initPluginActions(gpointer data) @@ -2142,11 +2178,13 @@ } else if (mShowdesktopHandler) { - mShowdesktopHandler->paintAttrib (wAttrib); - mask |= mShowdesktopHandler->getPaintMask (); + mShowdesktopHandler->PaintOpacity (wAttrib.opacity); + mask |= mShowdesktopHandler->GetPaintMask (); } - if (uScreen->panel_controller_->GetTrayXid () == window->id () && !uScreen->allowWindowPaint) + std::vector const& tray_xids = uScreen->panel_controller_->GetTrayXids(); + if (std::find(tray_xids.begin(), tray_xids.end(), window->id()) != tray_xids.end() && + !uScreen->allowWindowPaint) { if (!uScreen->painting_tray_) { @@ -2174,6 +2212,22 @@ const CompRegion& region, unsigned int mask) { + if (uScreen->doShellRepaint && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask) + { + guint32 id = window->id(); + bool maximized = WindowManager::Default()->IsWindowMaximized(id); + bool on_current = window->onCurrentDesktop(); + bool override_redirect = window->overrideRedirect(); + bool managed = window->managed(); + CompPoint viewport = window->defaultViewport(); + int output = window->outputDevice(); + + if (maximized && on_current && !override_redirect && managed && viewport == uScreen->screen->vp() && output == (int)uScreen->screen->currentOutputDev().id()) + { + uScreen->paint_panel_ = true; + } + } + if (uScreen->doShellRepaint && !uScreen->forcePaintOnTop ()) { std::vector const& xwns = nux::XInputWindow::NativeHandleList(); @@ -2182,6 +2236,7 @@ for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev) { auto id = w->id(); + for (unsigned int i = 0; i < size; ++i) { if (xwns[i] == id) @@ -2190,7 +2245,7 @@ uScreen->paintDisplay(); #else uScreen->paintDisplay(region, matrix, mask); -#endif +#endif break; } } @@ -2208,7 +2263,8 @@ bool ret = gWindow->glDraw(matrix, attrib, region, mask); - if ((active_window == 0 || active_window == window->id()) && (window->type() == CompWindowTypeDesktopMask)) + if ((active_window == 0 || active_window == window->id()) && + (window->type() == CompWindowTypeDesktopMask)) { uScreen->paintPanelShadow(matrix); } @@ -2347,7 +2403,8 @@ } else if (mShowdesktopHandler) { - mShowdesktopHandler->windowNotify (n); + if (n == CompWindowNotifyFocusChange) + mShowdesktopHandler->WindowFocusChangeNotify (); } // We do this after the notify to ensure input focus has actually been moved. @@ -2356,7 +2413,7 @@ UnityScreen* us = UnityScreen::get(screen); CompWindow *lw; - if (us->dash_is_open_) + if (us->launcher_controller_->IsOverlayOpen()) { lw = screen->findWindow(us->launcher_controller_->LauncherWindowId(0)); lw->moveInputFocusTo(); @@ -2386,7 +2443,7 @@ if (mMinimizeHandler) mMinimizeHandler->updateFrameRegion (region); else if (mShowdesktopHandler) - mShowdesktopHandler->updateFrameRegion (region); + mShowdesktopHandler->UpdateFrameRegion (region); else window->updateFrameRegion (region); } @@ -2425,10 +2482,10 @@ for (auto launcher : launchers) { nux::Geometry geo = launcher->GetAbsoluteGeometry(); - + if (launcher->Hidden() || launcher->options()->hide_mode == LAUNCHER_HIDE_NEVER || launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE) continue; - + if (geo.IsInside(result)) { if (geo.x + geo.width + 1 + window_geo.width() < target_monitor.x + target_monitor.width) @@ -2520,6 +2577,7 @@ case UnityshellOptions::NumLaunchers: launcher_controller_->multiple_launchers = optionGetNumLaunchers() == 0; dash_controller_->use_primary = !launcher_controller_->multiple_launchers(); + hud_controller_->multiple_launchers = launcher_controller_->multiple_launchers(); break; case UnityshellOptions::LauncherCaptureMouse: launcher_options->edge_resist = optionGetLauncherCaptureMouse(); @@ -2540,7 +2598,7 @@ case UnityshellOptions::LauncherHideMode: { launcher_options->hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode(); - hud_controller_->SetLauncherIsLockedOut(launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); + hud_controller_->launcher_locked_out = (launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); break; } case UnityshellOptions::BacklightMode: @@ -2775,10 +2833,11 @@ /* 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); + hud_controller_->launcher_locked_out = (hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER); + hud_controller_->multiple_launchers = (optionGetNumLaunchers() == 0); AddChild(hud_controller_.get()); LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s"; - + // Setup Shortcut Hint InitHints(); shortcut_controller_.reset(new shortcut::Controller(hints_)); @@ -2792,62 +2851,62 @@ void UnityScreen::InitHints() { // TODO move category text into a vector... - + // 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::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")); + + hints_.push_back(std::make_shared(launcher, "", _(" (Press)"), _("Open Launcher, displays shortcuts."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher" )); + hints_.push_back(std::make_shared(launcher, "", "", _("Open Launcher keyboard navigation mode."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "keyboard_focus")); + hints_.push_back(std::make_shared(launcher, "", "", _("Switch applications via Launcher."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "launcher_switcher_forward")); + hints_.push_back(std::make_shared(launcher, "", _(" + 1 to 9"), _("Same as clicking on a Launcher icon."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); + hints_.push_back(std::make_shared(launcher, "", _(" + Shift + 1 to 9"), _("Open new window of the app."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); + hints_.push_back(std::make_shared(launcher, "", " + T", _("Open the Trash."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); // 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")); - hints_.push_back(new shortcut::Hint(dash, "", " + F", _("Open the Dash Files Lens."), shortcut::COMPIZ_KEY_OPTION,"unityshell", "show_launcher")); - hints_.push_back(new shortcut::Hint(dash, "", " + M", _("Open the Dash Music Lens."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); - 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(std::make_shared(dash, "", _(" (Tap)"), _("Open the Dash Home."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); + hints_.push_back(std::make_shared(dash, "", " + A", _("Open the Dash App Lens."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); + hints_.push_back(std::make_shared(dash, "", " + F", _("Open the Dash Files Lens."), shortcut::COMPIZ_KEY_OPTION,"unityshell", "show_launcher")); + hints_.push_back(std::make_shared(dash, "", " + M", _("Open the Dash Music Lens."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher")); + hints_.push_back(std::make_shared(dash, "", "", _("Switches between Lenses."), shortcut::HARDCODED_OPTION, _("Ctrl + Tab"))); + hints_.push_back(std::make_shared(dash, "", "", _("Moves the focus."), shortcut::HARDCODED_OPTION, _("Cursor Keys"))); + hints_.push_back(std::make_shared(dash, "", "", _("Open currently focused item."), shortcut::HARDCODED_OPTION, _("Enter & Return"))); + // Menu Bar 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"))); + hints_.push_back(std::make_shared(menubar, "", _(" (Tap)"), _("Open the HUD."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_hud")); + hints_.push_back(std::make_shared(menubar, "", _(" (Press)"), _("Reveals application menu."), shortcut::HARDCODED_OPTION, "Alt")); + hints_.push_back(std::make_shared(menubar, "", "", _("Opens the indicator menu."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "panel_first_menu")); + hints_.push_back(std::make_shared(menubar, "", "", _("Moves focus between indicators."), shortcut::HARDCODED_OPTION, _("Cursor Left or Right"))); // 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"))); + + hints_.push_back(std::make_shared(switching, "", "", _("Switch between applications."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "alt_tab_forward")); + hints_.push_back(std::make_shared(switching, "", "", _("Switch windows of current application."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "alt_tab_next_window")); + hints_.push_back(std::make_shared(switching, "", "", _("Moves the focus."), shortcut::HARDCODED_OPTION, _("Cursor Left or Right"))); // 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, "", _(" + 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")); + hints_.push_back(std::make_shared(workspaces, "", "", _("Spread workspaces."), shortcut::COMPIZ_KEY_OPTION, "expo", "expo_key")); + hints_.push_back(std::make_shared(workspaces, "", _(" + Cursor Keys"), _("Switch workspaces."), shortcut::COMPIZ_METAKEY_OPTION, "wall", "left_key")); + hints_.push_back(std::make_shared(workspaces, "", _(" + Cursor Keys"), _("Move focused window to different workspace."), shortcut::COMPIZ_METAKEY_OPTION, "wall", "left_window_key")); // 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")); - hints_.push_back(new shortcut::Hint(windows, "", "", _("Restores or minimises current window."), shortcut::COMPIZ_KEY_OPTION, "core", "unmaximize_window_key")); - hints_.push_back(new shortcut::Hint(windows, "", _(" or Right"), _("Semi-maximises current window."), shortcut::COMPIZ_KEY_OPTION, "grid", "put_left_key")); - hints_.push_back(new shortcut::Hint(windows, "", "", _("Closes current window."), shortcut::COMPIZ_KEY_OPTION, "core", "close_window_key")); - hints_.push_back(new shortcut::Hint(windows, "", "", _("Opens window accessibility menu."), shortcut::HARDCODED_OPTION, _("Alt + Space"))); - hints_.push_back(new shortcut::Hint(windows, "", "", _("Places window in corresponding positions."), shortcut::HARDCODED_OPTION, _("Ctrl + Alt + Num"))); - hints_.push_back(new shortcut::Hint(windows, "", _(" Drag"), _("Move window."), shortcut::COMPIZ_MOUSE_OPTION, "move", "initiate_button")); - hints_.push_back(new shortcut::Hint(windows, "", _(" Drag"), _("Resize window."), shortcut::COMPIZ_MOUSE_OPTION, "resize", "initiate_button")); + hints_.push_back(std::make_shared(windows, "", "", _("Spreads all windows in the current workspace."), shortcut::COMPIZ_KEY_OPTION, "scale", "initiate_all_key")); + hints_.push_back(std::make_shared(windows, "", "", _("Minimises all windows."), shortcut::COMPIZ_KEY_OPTION, "core", "show_desktop_key")); + hints_.push_back(std::make_shared(windows, "", "", _("Maximises the current window."), shortcut::COMPIZ_KEY_OPTION, "core", "maximize_window_key")); + hints_.push_back(std::make_shared(windows, "", "", _("Restores or minimises current window."), shortcut::COMPIZ_KEY_OPTION, "core", "unmaximize_window_key")); + hints_.push_back(std::make_shared(windows, "", _(" or Right"), _("Semi-maximises current window."), shortcut::COMPIZ_KEY_OPTION, "grid", "put_left_key")); + hints_.push_back(std::make_shared(windows, "", "", _("Closes current window."), shortcut::COMPIZ_KEY_OPTION, "core", "close_window_key")); + hints_.push_back(std::make_shared(windows, "", "", _("Opens window accessibility menu."), shortcut::HARDCODED_OPTION, _("Alt + Space"))); + hints_.push_back(std::make_shared(windows, "", "", _("Places window in corresponding positions."), shortcut::HARDCODED_OPTION, _("Ctrl + Alt + Num"))); + hints_.push_back(std::make_shared(windows, "", _(" Drag"), _("Move window."), shortcut::COMPIZ_MOUSE_OPTION, "move", "initiate_button")); + hints_.push_back(std::make_shared(windows, "", _(" Drag"), _("Resize window."), shortcut::COMPIZ_MOUSE_OPTION, "resize", "initiate_button")); } /* Window init */ @@ -2924,7 +2983,7 @@ window->minimize (); } - UnityShowdesktopHandler::animating_windows.remove (window); + ShowdesktopHandler::animating_windows.remove (static_cast (this)); if (mShowdesktopHandler) delete mShowdesktopHandler; @@ -3056,10 +3115,14 @@ } nux::logging::Logger logger(module); nux::logging::Level level = glog_level_to_nux(log_level); - if (logger.GetEffectiveLogLevel() >= level) + if (level >= logger.GetEffectiveLogLevel()) { nux::logging::LogStream(level, logger.module(), "", 0).stream() << message; + if (level >= nux::logging::Error) + { + nux::logging::Backtrace(); + } } } diff -Nru unity-5.8.0/plugins/unityshell/src/unityshell.h unity-5.10.0/plugins/unityshell/src/unityshell.h --- unity-5.8.0/plugins/unityshell/src/unityshell.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/unityshell.h 2012-04-12 13:21:21.000000000 +0000 @@ -38,6 +38,7 @@ #include "DashController.h" #include "DashSettings.h" #include "DashStyle.h" +#include "FavoriteStoreGSettings.h" #include "FontSettings.h" #include "ShortcutController.h" #include "ShortcutHint.h" @@ -50,6 +51,7 @@ #include "SwitcherController.h" #include "UBusWrapper.h" #include "UnityshellPrivate.h" +#include "UnityShowdesktopHandler.h" #ifndef USE_GLES #include "ScreenEffectFramebufferObject.h" #endif @@ -64,51 +66,6 @@ namespace unity { -class UnityShowdesktopHandler -{ - public: - - UnityShowdesktopHandler (CompWindow *w); - ~UnityShowdesktopHandler (); - - typedef enum { - Visible = 0, - FadeOut = 1, - FadeIn = 2, - Invisible = 3 - } State; - -public: - - void fadeOut (); - void fadeIn (); - bool animate (unsigned int ms); - void paintAttrib (GLWindowPaintAttrib &attrib); - unsigned int getPaintMask (); - void handleEvent (XEvent *); - void windowNotify (CompWindowNotify n); - void updateFrameRegion (CompRegion &r); - - UnityShowdesktopHandler::State state (); - - static const unsigned int fade_time; - static CompWindowList animating_windows; - static bool shouldHide (CompWindow *); - static void inhibitLeaveShowdesktopMode (guint32 xid); - static void allowLeaveShowdesktopMode (guint32 xid); - static guint32 inhibitingXid (); - -private: - - CompWindow *mWindow; - compiz::WindowInputRemover *mRemover; - UnityShowdesktopHandler::State mState; - float mProgress; - bool mWasHidden; - static guint32 mInhibitingXid; -}; - - /* base screen class */ class UnityScreen : public unity::debug::Introspectable, @@ -145,6 +102,7 @@ void preparePaint (int ms); void paintFboForOutput (CompOutput *output); + void donePaint (); void RaiseInputWindows(); @@ -206,6 +164,7 @@ bool altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); + bool ShowHud(); /* handle hud key activations */ bool ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options); @@ -272,10 +231,14 @@ void InitHints(); + void OnPanelStyleChanged(); + dash::Settings dash_settings_; dash::Style dash_style_; panel::Style panel_style_; FontSettings font_settings_; + GeisAdapter geis_adapter_; + internal::FavoriteStoreGSettings favorite_store_; launcher::Controller::Ptr launcher_controller_; dash::Controller::Ptr dash_controller_; @@ -284,10 +247,10 @@ hud::Controller::Ptr hud_controller_; shortcut::Controller::Ptr shortcut_controller_; - std::list hints_; + std::list hints_; bool enable_shortcut_overlay_; - GestureEngine* gestureEngine; + std::unique_ptr gesture_engine_; nux::WindowThread* wt; nux::BaseWindow* panelWindow; nux::Geometry lastTooltipArea; @@ -330,7 +293,6 @@ bool queryForShader (); UBusManager ubus_manager_; - bool dash_is_open_; int dash_monitor_; CompScreen::GrabHandle grab_index_; CompWindowList fullscreen_windows_; @@ -342,6 +304,10 @@ GLMatrix panel_shadow_matrix_; + bool panel_texture_has_changed_; + bool paint_panel_; + nux::ObjectPtr panel_texture_; + #ifndef USE_GLES ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP; #endif @@ -352,6 +318,7 @@ class UnityWindow : public WindowInterface, public GLWindowInterface, + public ShowdesktopHandlerWindowInterface, public BaseSwitchWindow, public PluginClassHandler { @@ -408,18 +375,50 @@ void enterShowDesktop (); void leaveShowDesktop (); - bool handleAnimations (unsigned int ms); + bool HandleAnimations (unsigned int ms); + + void handleEvent (XEvent *event); typedef compiz::CompizMinimizedWindowHandler UnityMinimizedHandler; std::unique_ptr mMinimizeHandler; - UnityShowdesktopHandler *mShowdesktopHandler; + ShowdesktopHandler *mShowdesktopHandler; private: guint focusdesktop_handle_; static gboolean FocusDesktopTimeout(gpointer data); + + void DoEnableFocus (); + void DoDisableFocus (); + + bool IsOverrideRedirect (); + bool IsManaged (); + bool IsGrabbed (); + bool IsDesktopOrDock (); + bool IsSkipTaskbarOrPager (); + bool IsHidden (); + bool IsInShowdesktopMode (); + bool IsShaded (); + bool IsMinimized (); + void DoOverrideFrameRegion (CompRegion &r); + + void DoHide (); + void DoNotifyHidden (); + void DoShow (); + void DoNotifyShown (); + + void DoAddDamage (); + ShowdesktopHandlerWindowInterface::PostPaintAction DoHandleAnimations (unsigned int ms); + + void DoMoveFocusAway (); + + void DoDeleteHandler (); + + unsigned int GetNoCoreInstanceMask (); + + compiz::WindowInputRemoverInterface::Ptr GetInputRemover (); }; diff -Nru unity-5.8.0/plugins/unityshell/src/UnityShowdesktopHandler.cpp unity-5.10.0/plugins/unityshell/src/UnityShowdesktopHandler.cpp --- unity-5.8.0/plugins/unityshell/src/UnityShowdesktopHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/UnityShowdesktopHandler.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,215 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* Compiz unity plugin + * unity.h + * + * Copyright (c) 2010-11 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * 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. + * + * Your own copyright notice would go above. You are free to choose whatever + * licence you want, just take note that some compiz code is GPL and you will + * not be able to re-use it if you want to use a different licence. + */ + +#include +#include "UnityShowdesktopHandler.h" + +namespace unity +{ + +ShowdesktopHandlerWindowInterface::~ShowdesktopHandlerWindowInterface() +{ +} + +/* 300 ms */ +const unsigned int ShowdesktopHandler::fade_time = 300; +std::list ShowdesktopHandler::animating_windows (0); + +bool ShowdesktopHandler::ShouldHide (ShowdesktopHandlerWindowInterface *wi) +{ + if (wi->OverrideRedirect()) + return false; + + if (!wi->Managed()) + return false; + + if (wi->Grabbed()) + return false; + + if (wi->DesktopOrDock()) + return false; + + if (wi->SkipTaskbarOrPager()) + return false; + + if (wi->Hidden()) + if ((wi->ShowDesktopMode() || wi->Shaded())) + return false; + + return true; +} + +guint32 ShowdesktopHandler::inhibiting_xid = 0; + +void +ShowdesktopHandler::InhibitLeaveShowdesktopMode (guint32 xid) +{ + if (!inhibiting_xid) + inhibiting_xid = xid; +} + +void +ShowdesktopHandler::AllowLeaveShowdesktopMode (guint32 xid) +{ + if (inhibiting_xid == xid) + inhibiting_xid = 0; +} + +guint32 +ShowdesktopHandler::InhibitingXid() +{ + return inhibiting_xid; +} + +ShowdesktopHandler::ShowdesktopHandler (ShowdesktopHandlerWindowInterface *wi) : + showdesktop_handler_window_interface_ (wi), + remover_ (wi->InputRemover()), + state_ (StateVisible), + progress_ (0.0f) +{ +} + +ShowdesktopHandler::~ShowdesktopHandler() +{ +} + +void ShowdesktopHandler::FadeOut() +{ + if (state_ != StateVisible && state_ != StateFadeIn) + return; + + state_ = ShowdesktopHandler::StateFadeOut; + progress_ = 0.0f; + + was_hidden_ = showdesktop_handler_window_interface_->Hidden(); + + if (!was_hidden_) + { + showdesktop_handler_window_interface_->Hide(); + showdesktop_handler_window_interface_->NotifyHidden(); + remover_->save(); + remover_->remove(); + + if (std::find (animating_windows.begin(), + animating_windows.end(), + showdesktop_handler_window_interface_) == animating_windows.end()) + animating_windows.push_back (showdesktop_handler_window_interface_); + + } +} + +void ShowdesktopHandler::FadeIn() +{ + if (state_ != StateInvisible && state_ != StateFadeOut) + return; + + state_ = ShowdesktopHandler::StateFadeIn; + + if (!was_hidden_) + { + showdesktop_handler_window_interface_->Show(); + showdesktop_handler_window_interface_->NotifyShown(); + remover_->restore(); + + if (std::find (animating_windows.begin(), + animating_windows.end(), + showdesktop_handler_window_interface_) == animating_windows.end()) + animating_windows.push_back(showdesktop_handler_window_interface_); + } +} + +ShowdesktopHandlerWindowInterface::PostPaintAction ShowdesktopHandler::Animate (unsigned int ms) +{ + float inc = ms / static_cast (fade_time); + + if (state_ == ShowdesktopHandler::StateFadeOut) + { + progress_ += inc; + if (progress_ >= 1.0f) + { + progress_ = 1.0f; + state_ = StateInvisible; + } + } + else if (state_ == StateFadeIn) + { + progress_ -= inc; + if (progress_ <= 0.0f) + { + progress_ = 0.0f; + state_ = StateVisible; + } + } + else if (state_ == StateVisible) + return ShowdesktopHandlerWindowInterface::PostPaintAction::Remove; + else if (state_ == StateInvisible) + return ShowdesktopHandlerWindowInterface::PostPaintAction::Wait; + + return ShowdesktopHandlerWindowInterface::PostPaintAction::Damage; +} + +void ShowdesktopHandler::PaintOpacity (unsigned short &opacity) +{ + if (progress_ == 1.0f || progress_ == 0.0f) + opacity = std::numeric_limits ::max(); + else + opacity *= (1.0f - progress_); +} + +unsigned int ShowdesktopHandler::GetPaintMask() +{ + return (progress_ == 1.0f) ? showdesktop_handler_window_interface_->NoCoreInstanceMask() : 0; +} + +void ShowdesktopHandler::HandleShapeEvent() +{ + /* Ignore sent events from the InputRemover */ + if (remover_) + { + remover_->save(); + remover_->remove(); + } +} + +void ShowdesktopHandler::WindowFocusChangeNotify() +{ + if (showdesktop_handler_window_interface_->Minimized()) + { + for (ShowdesktopHandlerWindowInterface *w : animating_windows) + w->DisableFocus(); + + showdesktop_handler_window_interface_->MoveFocusAway(); + + for (ShowdesktopHandlerWindowInterface *w : animating_windows) + w->EnableFocus(); + } +} + +void ShowdesktopHandler::UpdateFrameRegion (CompRegion &r) +{ + r = CompRegion(); + + /* Ensure no other plugins can touch this frame region */ + showdesktop_handler_window_interface_->OverrideFrameRegion (r); +} + +} + diff -Nru unity-5.8.0/plugins/unityshell/src/UnityShowdesktopHandler.h unity-5.10.0/plugins/unityshell/src/UnityShowdesktopHandler.h --- unity-5.8.0/plugins/unityshell/src/UnityShowdesktopHandler.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/UnityShowdesktopHandler.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,158 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* Compiz unity plugin + * unity.h + * + * Copyright (c) 2010-11 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * 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. + * + * Your own copyright notice would go above. You are free to choose whatever + * licence you want, just take note that some compiz code is GPL and you will + * not be able to re-use it if you want to use a different licence. + */ +#ifndef UNITY_SHOWDESKTOP_HANDLER_H +#define UNITY_SHOWDESKTOP_HANDLER_H + +#include +#include +#include + +#include + +#include "inputremover.h" + +namespace unity +{ + +class ShowdesktopHandlerWindowInterface +{ + public: + + enum class PostPaintAction { + Wait = 0, + Damage = 1, + Remove = 2 + }; + + virtual ~ShowdesktopHandlerWindowInterface (); + + void EnableFocus () { DoEnableFocus (); } + void DisableFocus () { DoDisableFocus (); } + + bool OverrideRedirect () { return IsOverrideRedirect (); } + bool Managed () { return IsManaged (); } + bool Grabbed () { return IsGrabbed (); } + bool DesktopOrDock () { return IsDesktopOrDock (); } + bool SkipTaskbarOrPager () { return IsSkipTaskbarOrPager (); } + bool Hidden () { return IsHidden (); } + bool Shaded () { return IsShaded (); } + bool Minimized () { return IsMinimized (); } + bool ShowDesktopMode () { return IsInShowdesktopMode (); } + void OverrideFrameRegion (CompRegion &r) { return DoOverrideFrameRegion (r); } + + void Hide () { DoHide (); } + void NotifyHidden () { DoNotifyHidden (); } + void Show () { DoShow (); } + void NotifyShown () { DoNotifyShown (); } + void MoveFocusAway () { DoMoveFocusAway (); } + + PostPaintAction HandleAnimations (unsigned int ms) { return DoHandleAnimations (ms); } + void AddDamage () { DoAddDamage (); } + + void DeleteHandler () { DoDeleteHandler (); } + + unsigned int NoCoreInstanceMask () { return GetNoCoreInstanceMask (); } + + compiz::WindowInputRemoverInterface::Ptr InputRemover () { return GetInputRemover (); } + + private: + + virtual void DoEnableFocus () = 0; + virtual void DoDisableFocus () = 0; + + virtual bool IsOverrideRedirect () = 0; + virtual bool IsManaged () = 0; + virtual bool IsGrabbed () = 0; + virtual bool IsDesktopOrDock () = 0; + + virtual bool IsSkipTaskbarOrPager () = 0; + virtual bool IsHidden () = 0; + virtual bool IsInShowdesktopMode () = 0; + virtual bool IsShaded () = 0; + + virtual bool IsMinimized () = 0; + + virtual void DoOverrideFrameRegion (CompRegion &) = 0; + + virtual void DoHide () = 0; + virtual void DoNotifyHidden () = 0; + virtual void DoShow () = 0; + virtual void DoNotifyShown () = 0; + + virtual void DoMoveFocusAway () = 0; + virtual PostPaintAction DoHandleAnimations (unsigned int ms) = 0; + virtual void DoAddDamage () = 0; + + virtual void DoDeleteHandler () = 0; + + virtual unsigned int GetNoCoreInstanceMask () = 0; + + virtual compiz::WindowInputRemoverInterface::Ptr GetInputRemover () = 0; +}; + +class ShowdesktopHandler +{ + public: + + ShowdesktopHandler (ShowdesktopHandlerWindowInterface *uwi); + ~ShowdesktopHandler (); + + typedef enum { + StateVisible = 0, + StateFadeOut = 1, + StateFadeIn = 2, + StateInvisible = 3 + } State; + +public: + + void FadeOut (); + void FadeIn (); + ShowdesktopHandlerWindowInterface::PostPaintAction Animate (unsigned int ms); + void PaintOpacity (unsigned short &opacity); + unsigned int GetPaintMask (); + void HandleShapeEvent (); + void WindowFocusChangeNotify (); + void UpdateFrameRegion (CompRegion &r); + + ShowdesktopHandler::State GetState (); + + static const unsigned int fade_time; + static std::list animating_windows; + static bool ShouldHide (ShowdesktopHandlerWindowInterface *); + static void InhibitLeaveShowdesktopMode (guint32 xid); + static void AllowLeaveShowdesktopMode (guint32 xid); + static guint32 InhibitingXid (); + +private: + + ShowdesktopHandlerWindowInterface *showdesktop_handler_window_interface_; + compiz::WindowInputRemoverInterface::Ptr remover_; + ShowdesktopHandler::State state_; + float progress_; + bool was_hidden_; + static guint32 inhibiting_xid; +}; + +} + + +#endif diff -Nru unity-5.8.0/plugins/unityshell/src/UScreen.cpp unity-5.10.0/plugins/unityshell/src/UScreen.cpp --- unity-5.8.0/plugins/unityshell/src/UScreen.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/UScreen.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -32,6 +32,9 @@ (GCallback)UScreen::Changed, this); Refresh(); + + proxy_ = unity::glib::DBusProxy::Ptr(new unity::glib::DBusProxy("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", G_BUS_TYPE_SYSTEM)); + proxy_->Connect("Resuming", [&](GVariant* data) -> void { resuming.emit(); }); } UScreen::~UScreen() diff -Nru unity-5.8.0/plugins/unityshell/src/UScreen.h unity-5.10.0/plugins/unityshell/src/UScreen.h --- unity-5.8.0/plugins/unityshell/src/UScreen.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/UScreen.h 2012-04-12 13:21:21.000000000 +0000 @@ -24,6 +24,8 @@ #include #include +#include "UnityCore/GLibDBusProxy.h" + class UScreen : public sigc::trackable { public: @@ -41,6 +43,8 @@ // sigc::signal&> changed; + sigc::signal resuming; + private: static void Changed(GdkScreen* screen, UScreen* self); static gboolean OnIdleChanged(UScreen* self); @@ -50,6 +54,7 @@ std::vector _monitors; guint32 _refresh_id; int primary_; + unity::glib::DBusProxy::Ptr proxy_; }; #endif // _UNITY_SCREEN_H_ diff -Nru unity-5.8.0/plugins/unityshell/src/WindowButtons.cpp unity-5.10.0/plugins/unityshell/src/WindowButtons.cpp --- unity-5.8.0/plugins/unityshell/src/WindowButtons.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/WindowButtons.cpp 2012-04-12 13:21:21.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 @@ -15,125 +15,139 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include "config.h" #include -#include -#include -#include - -#include -#include -#include +#include #include -#include "WindowButtons.h" -#include "ubus-server.h" -#include "UBusMessages.h" +#include "WindowButtons.h" #include "DashSettings.h" #include "PanelStyle.h" - -#include +#include "UBusMessages.h" +#include "WindowManager.h" namespace unity { -class WindowButton : public nux::Button +class WindowButton : public nux::Button, public debug::Introspectable { // A single window button public: WindowButton(panel::WindowButtonType type) - : nux::Button("", NUX_TRACKER_LOCATION), - _type(type), - _overlay_is_open(false), - _mouse_is_down(false), - _place_shown_interest(0), - _place_hidden_interest(0), - _opacity(1.0f) + : nux::Button("", NUX_TRACKER_LOCATION) + , _type(type) + , _focused(true) + , _overlay_is_open(false) + , _opacity(1.0f) { - LoadImages(); - UpdateDashUnmaximize(); panel::Style::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::LoadImages)); - dash::Settings::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::UpdateDashUnmaximize)); + LoadImages(); + } - UBusServer* ubus = ubus_server_get_default(); - _place_shown_interest = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN, - (UBusCallback)&WindowButton::OnOverlayShown, - this); - _place_hidden_interest = ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN, - (UBusCallback)&WindowButton::OnOverlayHidden, - this); - - /* FIXME HasMouseFocus() doesn't seem to work correctly, so we use this workaround */ - mouse_down.connect([&_mouse_is_down](int, int, unsigned long, unsigned long) { - _mouse_is_down = true; - }); - mouse_up.connect([&_mouse_is_down](int, int, unsigned long, unsigned long) { - _mouse_is_down = false; - }); - } - - ~WindowButton() - { - UBusServer* ubus = ubus_server_get_default(); - if (_place_shown_interest != 0) - ubus_server_unregister_interest(ubus, _place_shown_interest); - if (_place_hidden_interest != 0) - ubus_server_unregister_interest(ubus, _place_hidden_interest); + void SetVisualState(nux::ButtonVisualState new_state) + { + if (new_state != visual_state_) + { + visual_state_ = new_state; + QueueDraw(); + } } void Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::Geometry geo = GetGeometry(); - nux::BaseTexture* tex = nullptr; + nux::Geometry const& geo = GetGeometry(); + nux::BaseTexture* tex; nux::TexCoordXForm texxform; GfxContext.PushClippingRectangle(geo); if (_overlay_is_open) { - if (_type == panel::WindowButtonType::UNMAXIMIZE && !_overlay_can_maximize) + if (!IsEnabled()) { tex = _disabled_dash_tex.GetPointer(); } else { - //FIXME should use HasMouseFocus() - if (_mouse_is_down && IsMouseInside()) - tex = _pressed_dash_tex.GetPointer(); - else if (IsMouseInside()) - tex = _prelight_dash_tex.GetPointer(); - else - tex = _normal_dash_tex.GetPointer(); + switch (visual_state_) + { + case nux::VISUAL_STATE_PRESSED: + tex = _pressed_dash_tex.GetPointer(); + break; + case nux::VISUAL_STATE_PRELIGHT: + tex = _prelight_dash_tex.GetPointer(); + break; + default: + tex = _normal_dash_tex.GetPointer(); + } + } + } + else if (!IsEnabled()) + { + tex = _disabled_tex.GetPointer(); + } + else if (!_focused) + { + switch (visual_state_) + { + case nux::VISUAL_STATE_PRESSED: + tex = _unfocused_pressed_tex.GetPointer(); + break; + case nux::VISUAL_STATE_PRELIGHT: + tex = _unfocused_prelight_tex.GetPointer(); + break; + default: + tex = _unfocused_tex.GetPointer(); } } else { - //FIXME should use HasMouseFocus() - if (_mouse_is_down && IsMouseInside()) - tex = _pressed_tex.GetPointer(); - else if (IsMouseInside()) - tex = _prelight_tex.GetPointer(); - else - tex = _normal_tex.GetPointer(); + switch (visual_state_) + { + case nux::VISUAL_STATE_PRESSED: + tex = _pressed_tex.GetPointer(); + break; + case nux::VISUAL_STATE_PRELIGHT: + tex = _prelight_tex.GetPointer(); + break; + default: + tex = _normal_tex.GetPointer(); + } } if (tex) - GfxContext.QRP_1Tex(geo.x, - geo.y, - (float)geo.width, - (float)geo.height, - tex->GetDeviceTexture(), - texxform, + { + GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height, + tex->GetDeviceTexture(), texxform, nux::color::White * _opacity); + } GfxContext.PopClippingRectangle(); } + void UpdateSize() + { + int panel_height = panel::Style::Instance().panel_height; + nux::BaseTexture* tex; + tex = (_overlay_is_open) ? _normal_dash_tex.GetPointer() : _normal_tex.GetPointer(); + int width = 0; + int height = 0; + + if (tex) + { + width = std::min(panel_height, tex->GetWidth()); + height = std::min(panel_height, tex->GetHeight()); + } + + SetMinMaxSize(width, height); + } + void LoadImages() { panel::Style& style = panel::Style::Instance(); @@ -141,117 +155,156 @@ _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)); + _unfocused_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::UNFOCUSED)); + _disabled_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::DISABLED)); + _unfocused_prelight_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::UNFOCUSED_PRELIGHT)); + _unfocused_pressed_tex.Adopt(style.GetWindowButton(_type, panel::WindowState::UNFOCUSED_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)); + _disabled_dash_tex.Adopt(GetDashWindowButton(_type, panel::WindowState::DISABLED)); - if (_overlay_is_open) - { - if (_normal_dash_tex) - SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight()); - } - else - { - if (_normal_tex) - SetMinMaxSize(_normal_tex->GetWidth(), _normal_tex->GetHeight()); - } - + UpdateSize(); QueueDraw(); } - void UpdateDashUnmaximize() + void SetOpacity(double opacity) { - // only update the unmaximize button - if (_type != panel::WindowButtonType::UNMAXIMIZE) - return; - - panel::WindowButtonType real_type = panel::WindowButtonType::UNMAXIMIZE; - - if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP) + if (_opacity != opacity) { - real_type = panel::WindowButtonType::MAXIMIZE; + _opacity = opacity; + SetInputEventSensitivity(_opacity != 0.0f); + + QueueDraw(); } + } - //!!FIXME!! - don't have disabled instances of the (un)maximize buttons - // get (un)maximize buttons - _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)); + double GetOpacity() const + { + return _opacity; + } - // still check if the dash is really opened, - // someone could change the form factor through dconf - // when the dash is closed - if (_overlay_is_open) + void SetFocusedState(bool focused) + { + if (_focused != focused) { - if (_normal_dash_tex) - SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight()); + _focused = focused; + QueueDraw(); } + } + void SetOverlayOpen(bool open) + { + if (_overlay_is_open == open) + return; + + _overlay_is_open = open; + + UpdateSize(); QueueDraw(); } - void SetOpacity(double opacity) + bool IsOverlayOpen() { - if (_opacity != opacity) + return _overlay_is_open; + } + + panel::WindowButtonType GetType() const + { + return _type; + } + + void ChangeType(panel::WindowButtonType new_type) + { + if (_type != new_type) { - _opacity = opacity; - NeedRedraw(); + _type = new_type; + LoadImages(); } } - double GetOpacity() + void SetEnabled(bool enabled) { - return _opacity; - } + if (enabled == IsEnabled()) + return; -private: - panel::WindowButtonType _type; - 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; + SetEnableView(enabled); + QueueDraw(); + } - bool _overlay_is_open; - bool _overlay_can_maximize; - bool _mouse_is_down; - guint32 _place_shown_interest; - guint32 _place_hidden_interest; - double _opacity; + bool IsEnabled() + { + return IsViewEnabled(); + } - static void OnOverlayShown(GVariant* data, void* val) +protected: + std::string GetName() const { - 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); + return "WindowButton"; + } - WindowButton* self = (WindowButton*)val; + void AddProperties(GVariantBuilder* builder) + { + std::string type_name; + std::string state_name; - self->_overlay_is_open = true; - if (self->_normal_dash_tex) - self->SetMinMaxSize(self->_normal_dash_tex->GetWidth(), self->_normal_dash_tex->GetHeight()); + switch (_type) + { + case panel::WindowButtonType::CLOSE: + type_name = "Close"; + break; + case panel::WindowButtonType::MINIMIZE: + type_name = "Minimize"; + break; + case panel::WindowButtonType::MAXIMIZE: + type_name = "Maximize"; + break; + case panel::WindowButtonType::UNMAXIMIZE: + type_name = "Unmaximize"; + break; + } - self->_overlay_can_maximize = (can_maximise) ? true : false; + switch (visual_state_) + { + case nux::VISUAL_STATE_PRESSED: + state_name = "pressed"; + break; + case nux::VISUAL_STATE_PRELIGHT: + state_name = "prelight"; + break; + default: + state_name = "normal"; + } - self->QueueDraw(); + variant::BuilderWrapper(builder).add(GetAbsoluteGeometry()) + .add("type", type_name) + .add("visible", IsVisible() && _opacity != 0.0f) + .add("sensitive", GetInputEventSensitivity()) + .add("enabled", IsEnabled()) + .add("visual_state", state_name) + .add("opacity", _opacity) + .add("focused", _focused) + .add("overlay_mode", _overlay_is_open); } - static void OnOverlayHidden(GVariant* data, void* val) - { - WindowButton* self = (WindowButton*)val; - self->_overlay_is_open = false; - if (self->_normal_tex) - self->SetMinMaxSize(self->_normal_tex->GetWidth(), self->_normal_tex->GetHeight()); +private: + panel::WindowButtonType _type; + bool _focused; + bool _overlay_is_open; + double _opacity; - self->QueueDraw(); - } + nux::ObjectPtr _normal_tex; + nux::ObjectPtr _prelight_tex; + nux::ObjectPtr _pressed_tex; + nux::ObjectPtr _unfocused_tex; + nux::ObjectPtr _unfocused_prelight_tex; + nux::ObjectPtr _unfocused_pressed_tex; + nux::ObjectPtr _disabled_tex; + nux::ObjectPtr _normal_dash_tex; + nux::ObjectPtr _prelight_dash_tex; + nux::ObjectPtr _pressed_dash_tex; + nux::ObjectPtr _disabled_dash_tex; nux::BaseTexture* GetDashWindowButton(panel::WindowButtonType type, panel::WindowState state) @@ -282,7 +335,10 @@ WindowButtons::WindowButtons() : HLayout("", NUX_TRACKER_LOCATION) - , _opacity(1.0f) + , monitor_(0) + , opacity_(1.0f) + , focused_(true) + , window_xid_(0) { WindowButton* but; @@ -303,94 +359,411 @@ but = new WindowButton(panel::WindowButtonType::CLOSE); AddView(but, 0, nux::eCenter, nux::eFix); - but->state_change.connect(sigc::mem_fun(this, &WindowButtons::OnCloseClicked)); + AddChild(but); + but->click.connect(sigc::mem_fun(this, &WindowButtons::OnCloseClicked)); but->mouse_enter.connect(lambda_enter); but->mouse_leave.connect(lambda_leave); but->mouse_move.connect(lambda_moved); but = new WindowButton(panel::WindowButtonType::MINIMIZE); AddView(but, 0, nux::eCenter, nux::eFix); - but->state_change.connect(sigc::mem_fun(this, &WindowButtons::OnMinimizeClicked)); + AddChild(but); + but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMinimizeClicked)); but->mouse_enter.connect(lambda_enter); but->mouse_leave.connect(lambda_leave); but->mouse_move.connect(lambda_moved); but = new WindowButton(panel::WindowButtonType::UNMAXIMIZE); AddView(but, 0, nux::eCenter, nux::eFix); - but->state_change.connect(sigc::mem_fun(this, &WindowButtons::OnRestoreClicked)); + AddChild(but); + but->click.connect(sigc::mem_fun(this, &WindowButtons::OnRestoreClicked)); but->mouse_enter.connect(lambda_enter); but->mouse_leave.connect(lambda_leave); but->mouse_move.connect(lambda_moved); + but = new WindowButton(panel::WindowButtonType::MAXIMIZE); + AddView(but, 0, nux::eCenter, nux::eFix); + AddChild(but); + but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMaximizeClicked)); + but->mouse_enter.connect(lambda_enter); + but->mouse_leave.connect(lambda_leave); + but->mouse_move.connect(lambda_moved); + but->SetVisible(false); + SetContentDistribution(nux::eStackLeft); -} + ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &WindowButtons::OnOverlayShown)); + ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &WindowButtons::OnOverlayHidden)); + dash::Settings::Instance().changed.connect(sigc::mem_fun(this, &WindowButtons::OnDashSettingsUpdated)); +} -WindowButtons::~WindowButtons() +nux::Area* WindowButtons::FindAreaUnderMouse(const nux::Point& mouse, nux::NuxEventType event_type) { + /* The first button should be clickable on the left space too, to + * make Fitts happy. All also on their top side. See bug #839690 */ + bool first_found = false; + + for (auto area : GetChildren()) + { + if (area->IsVisible() && area->GetInputEventSensitivity()) + { + nux::Geometry const& geo = area->GetAbsoluteGeometry(); + + if (!first_found) + { + first_found = true; + + if (mouse.x < geo.x && mouse.y < (geo.y + geo.height)) + return area; + } + + if (geo.IsPointInside(mouse.x, mouse.y)) + return area; + + if (mouse.x >= geo.x && mouse.x <= (geo.x + geo.width) && mouse.y <= geo.y) + return area; + } + } + + return nullptr; } -void -WindowButtons::OnCloseClicked(nux::View* view) +void WindowButtons::OnCloseClicked(nux::Button *button) { + auto win_button = dynamic_cast(button); + + if (!win_button || !win_button->IsEnabled()) + return; + + if (win_button->IsOverlayOpen()) + { + ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); + } + else + { + WindowManager::Default()->Close(window_xid_); + } + close_clicked.emit(); } -void -WindowButtons::OnMinimizeClicked(nux::View* view) +void WindowButtons::OnMinimizeClicked(nux::Button *button) { + auto win_button = dynamic_cast(button); + + if (!win_button || !win_button->IsEnabled()) + return; + + if (!win_button->IsOverlayOpen()) + WindowManager::Default()->Minimize(window_xid_); + minimize_clicked.emit(); } -void -WindowButtons::OnRestoreClicked(nux::View* view) +void WindowButtons::OnRestoreClicked(nux::Button *button) { + auto win_button = dynamic_cast(button); + + if (!win_button || !win_button->IsEnabled()) + return; + + if (win_button->IsOverlayOpen()) + { + dash::Settings::Instance().SetFormFactor(dash::FormFactor::DESKTOP); + } + else + { + WindowManager* wm = WindowManager::Default(); + Window to_restore = window_xid_; + + wm->Raise(to_restore); + wm->Activate(to_restore); + wm->Restore(to_restore); + } + restore_clicked.emit(); } -nux::Area* -WindowButtons::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) +void WindowButtons::OnMaximizeClicked(nux::Button *button) +{ + auto win_button = dynamic_cast(button); + + if (!win_button || !win_button->IsEnabled()) + return; + + if (win_button->IsOverlayOpen()) + { + dash::Settings::Instance().SetFormFactor(dash::FormFactor::NETBOOK); + } + + maximize_clicked.emit(); +} + +void WindowButtons::OnOverlayShown(GVariant* data) +{ + WindowButton* maximize_button = nullptr; + WindowButton* restore_button = nullptr; + 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 (overlay_monitor != monitor_) + { + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + button->SetEnabled(false); + } + + return; + } + + active_overlay_ = overlay_identity.Str(); + + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + { + if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE) + restore_button = button; + + if (button->GetType() == panel::WindowButtonType::MAXIMIZE) + maximize_button = button; + + button->SetOverlayOpen(true); + } + } + + if (restore_button && maximize_button) + { + dash::Settings &dash_settings = dash::Settings::Instance(); + bool maximizable = (dash_settings.GetFormFactor() == dash::FormFactor::DESKTOP); + + restore_button->SetEnabled(can_maximise); + maximize_button->SetEnabled(can_maximise); + + if (maximizable != maximize_button->IsVisible()) + { + if (maximize_button->IsVisible()) + restore_button->SetVisualState(maximize_button->GetVisualState()); + else if (restore_button->IsVisible()) + maximize_button->SetVisualState(restore_button->GetVisualState()); + + restore_button->SetVisible(!maximizable); + maximize_button->SetVisible(maximizable); + + QueueDraw(); + } + } +} + +void WindowButtons::OnOverlayHidden(GVariant* data) +{ + WindowButton* maximize_button = nullptr; + WindowButton* restore_button = nullptr; + + 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 (overlay_monitor != monitor_) + { + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + button->SetEnabled(true); + } + } + + if (active_overlay_ != overlay_identity.Str()) + return; + + active_overlay_ = ""; + + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + { + if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE) + restore_button = button; + + if (button->GetType() == panel::WindowButtonType::MAXIMIZE) + maximize_button = button; + + button->SetOverlayOpen(false); + } + } + + if (restore_button && maximize_button) + { + restore_button->SetEnabled(true); + maximize_button->SetEnabled(true); + + if (!restore_button->IsVisible()) + { + restore_button->SetVisualState(maximize_button->GetVisualState()); + + restore_button->SetVisible(true); + maximize_button->SetVisible(false); + + QueueDraw(); + } + } +} + +void WindowButtons::OnDashSettingsUpdated() { - return nux::HLayout::FindAreaUnderMouse(mouse_position, event_type); + WindowButton* maximize_button = nullptr; + WindowButton* restore_button = nullptr; + + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + { + if (!button->IsOverlayOpen()) + break; + + if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE) + restore_button = button; + + if (button->GetType() == panel::WindowButtonType::MAXIMIZE) + maximize_button = button; + + if (restore_button && maximize_button) + break; + } + } + + if (restore_button && restore_button->IsOverlayOpen() && maximize_button) + { + dash::Settings &dash_settings = dash::Settings::Instance(); + bool maximizable = (dash_settings.GetFormFactor() == dash::FormFactor::DESKTOP); + + if (maximizable != maximize_button->IsVisible()) + { + if (maximize_button->IsVisible()) + restore_button->SetVisualState(maximize_button->GetVisualState()); + else if (restore_button->IsVisible()) + maximize_button->SetVisualState(restore_button->GetVisualState()); + + restore_button->SetVisible(!maximizable); + maximize_button->SetVisible(maximizable); + + QueueDraw(); + } + } } -void -WindowButtons::SetOpacity(double opacity) +void WindowButtons::SetOpacity(double opacity) { opacity = CLAMP(opacity, 0.0f, 1.0f); for (auto area : GetChildren()) { - auto but = dynamic_cast(area); + auto button = dynamic_cast(area); - if (but) - but->SetOpacity(opacity); + if (button) + button->SetOpacity(opacity); } - if (_opacity != opacity) + if (opacity_ != opacity) { - _opacity = opacity; - NeedRedraw(); + opacity_ = opacity; + SetInputEventSensitivity(opacity_ != 0.0f); + QueueDraw(); } } -double -WindowButtons::GetOpacity() +double WindowButtons::GetOpacity() { - return _opacity; + return opacity_; } -std::string -WindowButtons::GetName() const +void WindowButtons::SetFocusedState(bool focused) { - return "window-buttons"; + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button) + button->SetFocusedState(focused); + } + + if (focused_ != focused) + { + focused_ = focused; + QueueDraw(); + } +} + +bool WindowButtons::GetFocusedState() +{ + return focused_; +} + +void WindowButtons::SetControlledWindow(Window xid) +{ + if (xid != window_xid_) + { + window_xid_ = xid; + + for (auto area : GetChildren()) + { + auto button = dynamic_cast(area); + + if (button->GetType() == panel::WindowButtonType::MINIMIZE) + { + bool minimizable = WindowManager::Default()->IsWindowMinimizable(xid); + button->SetEnabled(minimizable); + break; + } + } + } } -void -WindowButtons::AddProperties(GVariantBuilder* builder) +Window WindowButtons::GetControlledWindow() { - unity::variant::BuilderWrapper(builder).add(GetGeometry()); + return window_xid_; } +void WindowButtons::SetMonitor(int monitor) +{ + monitor_ = monitor; +} + +int WindowButtons::GetMonitor() +{ + return monitor_; +} + +std::string WindowButtons::GetName() const +{ + return "WindowButtons"; +} + +void WindowButtons::AddProperties(GVariantBuilder* builder) +{ + variant::BuilderWrapper(builder).add(GetAbsoluteGeometry()) + .add("monitor", monitor_) + .add("opacity", opacity_) + .add("visible", opacity_ != 0.0f) + .add("sensitive", GetInputEventSensitivity()) + .add("focused", focused_) + .add("controlled_window", window_xid_); +} -} // namespace unity +} // unity namespace diff -Nru unity-5.8.0/plugins/unityshell/src/WindowButtons.h unity-5.10.0/plugins/unityshell/src/WindowButtons.h --- unity-5.8.0/plugins/unityshell/src/WindowButtons.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/WindowButtons.h 2012-04-12 13:21:21.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 @@ -15,49 +15,70 @@ * along with this program. If not, see . * * Authored by: Neil Jagdish Patel + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #ifndef WINDOW_BUTTONS_H #define WINDOW_BUTTONS_H #include -#include +#include +#include "UBusWrapper.h" #include "Introspectable.h" namespace unity { -class WindowButtons : public nux::HLayout, public unity::debug::Introspectable +class WindowButtons : public nux::HLayout, public debug::Introspectable { // These are the [close][minimize][restore] buttons on the panel when there // is a maximized window public: WindowButtons(); - ~WindowButtons(); void SetOpacity(double opacity); double GetOpacity(); + void SetFocusedState(bool focused); + bool GetFocusedState(); + + void SetControlledWindow(Window xid); + Window GetControlledWindow(); + + void SetMonitor(int monitor); + int GetMonitor(); + + virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_pos, nux::NuxEventType event_type); + sigc::signal close_clicked; sigc::signal minimize_clicked; sigc::signal restore_clicked; + sigc::signal maximize_clicked; sigc::signal mouse_move; sigc::signal mouse_enter; sigc::signal mouse_leave; - virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type); - protected: std::string GetName() const; - void AddProperties(GVariantBuilder* builder); + void AddProperties(GVariantBuilder* builder); private: - void OnCloseClicked(nux::View *view); - void OnMinimizeClicked(nux::View *view); - void OnRestoreClicked(nux::View *view); + void OnCloseClicked(nux::Button *button); + void OnMinimizeClicked(nux::Button *button); + void OnRestoreClicked(nux::Button *button); + void OnMaximizeClicked(nux::Button *button); + void OnOverlayShown(GVariant* data); + void OnOverlayHidden(GVariant* data); + void OnDashSettingsUpdated(); + + int monitor_; + double opacity_; + bool focused_; + Window window_xid_; + std::string active_overlay_; - double _opacity; + UBusManager ubus_manager_; }; } #endif diff -Nru unity-5.8.0/plugins/unityshell/src/WindowManager.cpp unity-5.10.0/plugins/unityshell/src/WindowManager.cpp --- unity-5.8.0/plugins/unityshell/src/WindowManager.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/WindowManager.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -73,11 +73,21 @@ return true; } + bool IsWindowMinimizable(guint32 xid) + { + return true; + } + void Restore(guint32 xid) { g_debug("%s", G_STRFUNC); } + void RestoreAt(guint32 xid, int x, int y) + { + g_debug("%s", G_STRFUNC); + } + void Minimize(guint32 xid) { g_debug("%s", G_STRFUNC); @@ -114,14 +124,24 @@ return false; } - nux::Geometry GetWindowGeometry(guint xid) + nux::Geometry GetWindowGeometry(guint xid) const { int width = (guint32)xid >> 16; int height = (guint32)xid & 0x0000FFFF; return nux::Geometry(0, 0, width, height); } - nux::Geometry GetScreenGeometry() + nux::Geometry GetWindowSavedGeometry(guint xid) const + { + return nux::Geometry(0, 0, 1, 1); + } + + nux::Geometry GetScreenGeometry() const + { + return nux::Geometry(0, 0, 1, 1); + } + + nux::Geometry GetWorkAreaGeometry(guint32 xid) const { return nux::Geometry(0, 0, 1, 1); } @@ -153,6 +173,12 @@ return false; } + bool IsScaleActiveForGroup() + { + g_debug("%s", G_STRFUNC); + return false; + } + void InitiateExpo() { g_debug("%s", G_STRFUNC); @@ -164,6 +190,10 @@ return false; } + void MoveResizeWindow(guint32 xid, nux::Geometry geometry) + { + g_debug("%s", G_STRFUNC); + } }; WindowManager* @@ -183,9 +213,7 @@ #define NET_WM_MOVERESIZE_MOVE 8 - -void -WindowManager::StartMove(guint32 xid, int x, int y) +void WindowManager::StartMove(guint32 xid, int x, int y) { if (x < 0 || y < 0) return; @@ -229,11 +257,11 @@ ev.xclient.message_type = m_MoveResizeAtom; ev.xclient.format = 32; - ev.xclient.data.l[0] = x; - ev.xclient.data.l[1] = y; - ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; - ev.xclient.data.l[3] = 1; - ev.xclient.data.l[4] = 1; + ev.xclient.data.l[0] = x; // x_root + ev.xclient.data.l[1] = y; // y_root + ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; //direction + ev.xclient.data.l[3] = 1; // button + ev.xclient.data.l[4] = 2; // source XSendEvent(d, DefaultRootWindow(d), FALSE, SubstructureRedirectMask | SubstructureNotifyMask, diff -Nru unity-5.8.0/plugins/unityshell/src/WindowManager.h unity-5.10.0/plugins/unityshell/src/WindowManager.h --- unity-5.8.0/plugins/unityshell/src/WindowManager.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/src/WindowManager.h 2012-04-12 13:21:21.000000000 +0000 @@ -61,10 +61,12 @@ virtual bool IsWindowObscured(guint32 xid) = 0; virtual bool IsWindowMapped(guint32 xid) = 0; virtual bool IsWindowVisible(guint32 xid) = 0; + virtual bool IsWindowMinimizable(guint32 xid) = 0; virtual void ShowDesktop() = 0; virtual void Restore(guint32 xid) = 0; + virtual void RestoreAt(guint32 xid, int x, int y) = 0; virtual void Minimize(guint32 xid) = 0; virtual void Close(guint32 xid) = 0; @@ -74,6 +76,7 @@ virtual void TerminateScale() = 0; virtual bool IsScaleActive() = 0; + virtual bool IsScaleActiveForGroup() = 0; virtual void InitiateExpo() = 0; virtual bool IsExpoActive() = 0; @@ -87,12 +90,15 @@ virtual bool IsScreenGrabbed() = 0; virtual bool IsViewPortSwitchStarted() = 0; - void StartMove(guint32 id, int, int); + virtual void MoveResizeWindow(guint32 xid, nux::Geometry geometry) = 0; + void StartMove(guint32 xid, int, int); - virtual nux::Geometry GetWindowGeometry(guint32 xid) = 0; - virtual nux::Geometry GetScreenGeometry() = 0; + virtual nux::Geometry GetWindowGeometry(guint32 xid) const = 0; + virtual nux::Geometry GetWindowSavedGeometry(guint32 xid) const = 0; + virtual nux::Geometry GetScreenGeometry() const = 0; + virtual nux::Geometry GetWorkAreaGeometry(guint32 xid = 0) const = 0; - virtual unsigned long long GetWindowActiveNumber (guint32 xid) = 0; + virtual unsigned long long GetWindowActiveNumber(guint32 xid) = 0; virtual void SetWindowIconGeometry(Window window, nux::Geometry const& geo) = 0; diff -Nru unity-5.8.0/plugins/unityshell/unityshell.xml.in unity-5.10.0/plugins/unityshell/unityshell.xml.in --- unity-5.8.0/plugins/unityshell/unityshell.xml.in 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/plugins/unityshell/unityshell.xml.in 2012-04-12 13:21:21.000000000 +0000 @@ -409,7 +409,7 @@ diff -Nru unity-5.8.0/standalone-clients/CMakeLists.txt unity-5.10.0/standalone-clients/CMakeLists.txt --- unity-5.8.0/standalone-clients/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/standalone-clients/CMakeLists.txt 2012-04-12 13:21:21.000000000 +0000 @@ -45,6 +45,8 @@ standalone_dash.cpp ${UNITY_SRC}/AbstractPlacesGroup.cpp ${UNITY_SRC}/AbstractPlacesGroup.h + ${UNITY_SRC}/AbstractSeparator.h + ${UNITY_SRC}/AbstractSeparator.cpp ${UNITY_SRC}/BackgroundEffectHelper.cpp ${UNITY_SRC}/BackgroundEffectHelper.h ${UNITY_SRC}/BGHash.cpp @@ -105,6 +107,8 @@ ${UNITY_SRC}/LensView.h ${UNITY_SRC}/LensViewPrivate.cpp ${UNITY_SRC}/LensViewPrivate.h + ${UNITY_SRC}/LineSeparator.cpp + ${UNITY_SRC}/LineSeparator.h ${UNITY_SRC}/OverlayRenderer.cpp ${UNITY_SRC}/PreviewApplications.cpp ${UNITY_SRC}/PreviewBase.cpp diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/bamf.py unity-5.10.0/tests/autopilot/autopilot/emulators/bamf.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/bamf.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/bamf.py 2012-04-12 13:21:21.000000000 +0000 @@ -13,6 +13,7 @@ import gobject import os from Xlib import display, X, protocol +from gtk import gdk from autopilot.emulators.dbus_handler import session_bus @@ -184,6 +185,11 @@ return self._view_iface.Name() @property + def icon(self): + """Get the application icon.""" + return self._view_iface.Icon() + + @property def is_active(self): """Is the application active (i.e.- has keyboard focus)?""" return self._view_iface.IsActive() @@ -256,9 +262,10 @@ Returns a tuple containing (x, y, width, height). """ - + # FIXME: We need to use the gdk window here to get the real coordinates geometry = self._x_win.get_geometry() - return (geometry.x, geometry.y, geometry.width, geometry.height) + origin = gdk.window_foreign_new(self._xid).get_origin() + return (origin[0], origin[1], geometry.width, geometry.height) @property def is_maximized(self): @@ -320,11 +327,29 @@ """ return not self._x_win is None + @property + def monitor(self): + """Returns the monitor to which the windows belongs to""" + return self._window_iface.Monitor() + + @property + def closed(self): + """Returns True if the window has been closed""" + # This will return False when the window is closed and then removed from BUS + try: + return (self._window_iface.GetXid() != self.x_id) + except: + return True + def close(self): """Close the window.""" self._setProperty('_NET_CLOSE_WINDOW', [0, 0]) + def set_focus(self): + self._x_win.set_input_focus(X.RevertToParent, X.CurrentTime) + self._x_win.configure(stack_mode=X.Above) + def __repr__(self): return "" % (self.title if self._x_win else str(self._xid)) diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/dbus_handler.py unity-5.10.0/tests/autopilot/autopilot/emulators/dbus_handler.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/dbus_handler.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/dbus_handler.py 2012-04-12 13:21:21.000000000 +0000 @@ -17,8 +17,10 @@ from dbus.mainloop.glib import DBusGMainLoop import gobject + DBusGMainLoop(set_as_default=True) session_bus = dbus.SessionBus() + gobject.threads_init() dbus.glib.init_threads() diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/ibus.py unity-5.10.0/tests/autopilot/autopilot/emulators/ibus.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/ibus.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/ibus.py 2012-04-12 13:21:21.000000000 +0000 @@ -6,7 +6,7 @@ # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -"Functions to deal with ibus service." +"""Functions to deal with ibus service.""" # without this the 'import ibus' imports us, and import ibus.common fails. 0.O from __future__ import absolute_import @@ -16,6 +16,7 @@ import logging from time import sleep + logger = logging.getLogger(__name__) @@ -46,6 +47,7 @@ bus = get_ibus_bus() return [e.name for e in bus.list_active_engines()] + def set_active_engines(engine_list): """Installs the engines in 'engine_list' into the list of active iBus engines. @@ -76,6 +78,7 @@ sleep(1) return old_engines + def set_global_input_engine(engine_name): """Set the global iBus input engine by name. diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/dash.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/dash.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/dash.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/dash.py 2012-04-12 13:21:21.000000000 +0000 @@ -29,10 +29,11 @@ """ def __init__(self): - self.controller = DashController.get_all_instances()[0] - - self._keyboard = Keyboard() super(Dash, self).__init__() + controllers = DashController.get_all_instances() + assert(len(controllers) == 1) + self.controller = controllers[0] + self._keyboard = Keyboard() @property def view(self): @@ -75,12 +76,15 @@ @property def visible(self): - """ - Is the dash visible? - """ + """Returns if the dash is currently visible""" return self.controller.visible @property + def monitor(self): + """The monitor where the dash is""" + return self.controller.monitor + + @property def search_string(self): return self.get_searchbar().search_string @@ -172,6 +176,15 @@ class LensBar(UnityIntrospectionObject): """The bar of lens icons at the bottom of the dash.""" + def get_icon_by_name(self, name): + """Get a LensBarIcon child object by it's name. For example, 'home.lens'.""" + icons = self.get_children_by_type(LensBarIcon) + for icon in icons: + if icon.name == name: + return icon + +class LensBarIcon(UnityIntrospectionObject): + """A lens icon at the bottom of the dash.""" class LensView(UnityIntrospectionObject): diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/hud.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/hud.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/hud.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/hud.py 2012-04-12 13:21:21.000000000 +0000 @@ -7,41 +7,92 @@ # by the Free Software Foundation. # -from autopilot.keybindings import KeybindingsHelper from autopilot.emulators.unity import UnityIntrospectionObject +from autopilot.emulators.unity.dash import SearchBar +from autopilot.emulators.unity.icons import HudEmbeddedIcon, HudLauncherIcon +from autopilot.keybindings import KeybindingsHelper -class HudView(UnityIntrospectionObject): - """Proxy object for the hud view child of the controller.""" - +class Hud(KeybindingsHelper): + """An emulator class that makes it easier to iteract with unity hud.""" -class HudController(UnityIntrospectionObject, KeybindingsHelper): - """Proxy object for the Unity Hud Controller.""" + def __init__(self): + super (Hud, self).__init__() + controllers = HudController.get_all_instances() + assert(len(controllers) == 1) + self.controller = controllers[0] def ensure_hidden(self): """Hides the hud if it's not already hidden.""" - if self.is_visible(): + if self.visible: self.toggle_reveal() def ensure_visible(self): """Shows the hud if it's not already showing.""" - if not self.is_visible(): + if not self.visible: self.toggle_reveal() - def is_visible(self): - return self.visible - def toggle_reveal(self, tap_delay=0.1): """Tap the 'Alt' key to toggle the hud visibility.""" self.keybinding("hud/reveal", tap_delay) - def _get_view(self): - views = self.get_children_by_type(HudView) - return views[0] if views else None + def get_embedded_icon(self): + """Returns the HUD view embedded icon or None if is not shown.""" + view = self.view + if (not view): + return None + + icons = view.get_children_by_type(HudEmbeddedIcon) + return icons[0] if icons else None + + def get_launcher_icon(self): + """Returns the HUD launcher icon""" + icons = HudLauncherIcon.get_all_instances() + assert(len(icons) == 1) + return icons[0] + + @property + def icon(self): + if self.is_locked_launcher: + return self.get_launcher_icon() + else: + return self.get_embedded_icon() + + @property + def view(self): + """Returns the HudView.""" + return self.controller.get_hud_view() + + @property + def visible(self): + """Is the Hud visible?""" + return self.controller.visible + + @property + def searchbar(self): + """Returns the searchbar attached to the hud.""" + return self.controller.get_hud_view().searchbar + + @property + def search_string(self): + """Returns the searchbars' search string.""" + return self.searchbar.search_string + + @property + def is_locked_launcher(self): + return self.controller.locked_to_launcher + + @property + def monitor(self): + return self.controller.hud_monitor + + @property + def geometry(self): + return (self.controller.x, self.controller.y, self.controller.width, self.controller.height) @property def selected_button(self): - view = self._get_view() + view = self.controller.get_hud_view() if view: return view.selected_button else: @@ -49,8 +100,29 @@ @property def num_buttons(self): - view = self._get_view() + view = self.controller.get_hud_view() if view: return view.num_buttons else: return 0 + + +class HudView(UnityIntrospectionObject): + """Proxy object for the hud view child of the controller.""" + + @property + def searchbar(self): + """Get the search bar attached to this hud view.""" + return self.get_children_by_type(SearchBar)[0] + + @property + def geometry(self): + return (self.x, self.y, self.width, self.height) + + +class HudController(UnityIntrospectionObject): + """Proxy object for the Unity Hud Controller.""" + + def get_hud_view(self): + views = self.get_children_by_type(HudView) + return views[0] if views else None diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/icons.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/icons.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/icons.py 2012-04-12 13:21:21.000000000 +0000 @@ -10,7 +10,6 @@ from autopilot.emulators.unity import UnityIntrospectionObject from autopilot.emulators.unity.quicklist import Quicklist - class SimpleLauncherIcon(UnityIntrospectionObject): """Holds information about a simple launcher icon. @@ -19,6 +18,11 @@ """ + @property + def center_position(self): + """Get the center point of an icon, returns a tuple with (x, y, z)""" + return (self.center_x, self.center_y, self.center_z) + def get_quicklist(self): """Get the quicklist for this launcher icon. @@ -29,11 +33,26 @@ matches = self.get_children_by_type(Quicklist) return matches[0] if matches else None + def is_on_monitor(self, monitor): + """Returns True if the icon is available in the defined monitor""" + if monitor >= 0 and monitor < len(self.monitors_visibility): + return self.monitors_visibility[monitor] + + return False + + def is_visible_on_monitor(self, monitor): + """Returns True if the icon is visible in the defined monitor""" + return self.visible and self.is_on_monitor(monitor) + class BFBLauncherIcon(SimpleLauncherIcon): """Represents the BFB button in the launcher.""" +class HudLauncherIcon(SimpleLauncherIcon): + """Represents the HUD button in the launcher.""" + + class BamfLauncherIcon(SimpleLauncherIcon): """Represents a launcher icon with BAMF integration.""" @@ -48,3 +67,15 @@ class DesktopLauncherIcon(SimpleLauncherIcon): """Represents an icon that may appear in the switcher.""" + + +class SoftwareCenterLauncherIcon(BamfLauncherIcon): + """Represents a launcher icon of a Software Center app.""" + + +class HudEmbeddedIcon(SimpleLauncherIcon): + """Proxy object for the hud embedded icon child of the view.""" + + @property + def geometry(self): + return (self.x, self.y, self.width, self.height) diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/launcher.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/launcher.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/launcher.py 2012-04-12 13:21:21.000000000 +0000 @@ -7,13 +7,15 @@ # by the Free Software Foundation. # +import dbus import logging from time import sleep -from autopilot.keybindings import KeybindingsHelper +from autopilot.emulators.dbus_handler import session_bus from autopilot.emulators.unity import UnityIntrospectionObject -from autopilot.emulators.unity.icons import BamfLauncherIcon, SimpleLauncherIcon +from autopilot.emulators.unity.icons import BFBLauncherIcon, BamfLauncherIcon, SimpleLauncherIcon from autopilot.emulators.X11 import Mouse, ScreenGeometry +from autopilot.keybindings import KeybindingsHelper logger = logging.getLogger(__name__) @@ -27,6 +29,10 @@ launchers = self.get_children_by_type(Launcher, monitor=monitor_num) return launchers[0] if launchers else None + def get_launchers(self): + """Return the available launchers, or None.""" + return self.get_children_by_type(Launcher) + @property def model(self): """Return the launcher model.""" @@ -37,6 +43,19 @@ def key_nav_monitor(self): return self.key_nav_launcher_monitor + def add_launcher_item_from_position(self,name,icon,icon_x,icon_y,icon_size,desktop_file,aptdaemon_task): + """ Emulate a DBus call from Software Center to pin an icon to the launcher """ + launcher_object = session_bus.get_object('com.canonical.Unity.Launcher', + '/com/canonical/Unity/Launcher') + launcher_iface = dbus.Interface(launcher_object, 'com.canonical.Unity.Launcher') + launcher_iface.AddLauncherItemFromPosition(name, + icon, + icon_x, + icon_y, + icon_size, + desktop_file, + aptdaemon_task) + class Launcher(UnityIntrospectionObject, KeybindingsHelper): """An individual launcher for a monitor.""" @@ -196,8 +215,8 @@ logger.debug("Clicking launcher icon %r on monitor %d with mouse button %d", icon, self.monitor, button) self.mouse_reveal_launcher() - target_x = icon.x + self.x - target_y = icon.y + (self.icon_size / 2) + target_x = icon.center_x + self.x + target_y = icon.center_y self._mouse.move(target_x, target_y ) self._mouse.click(button) self.move_mouse_to_right_of_launcher() @@ -254,13 +273,27 @@ class LauncherModel(UnityIntrospectionObject): """THe launcher model. Contains all launcher icons as children.""" + def get_bfb_icon(self): + icons = BFBLauncherIcon.get_all_instances() + assert(len(icons) == 1) + return icons[0] + def get_launcher_icons(self, visible_only=True): """Get a list of launcher icons in this launcher.""" if visible_only: - return self.get_children_by_type(SimpleLauncherIcon, quirk_visible=True) + return self.get_children_by_type(SimpleLauncherIcon, visible=True) else: return self.get_children_by_type(SimpleLauncherIcon) + def get_launcher_icons_for_monitor(self, monitor, visible_only=True): + """Get a list of launcher icons for provided monitor.""" + icons = [] + for icon in self.get_launcher_icons(visible_only): + if icon.is_on_monitor(monitor): + icons.append(icon) + + return icons + def get_icon_by_tooltip_text(self, tooltip_text): """Get a launcher icon given it's tooltip text. @@ -277,7 +310,21 @@ Returns None if there is no such launcher icon. """ icons = self.get_children_by_type(SimpleLauncherIcon, desktop_file=desktop_file) - return icons or None + if len(icons): + return icons[0] + + return None + + def get_icon_by_desktop_id(self, desktop_id): + """Gets a launcher icon with the specified desktop id. + + Returns None if there is no such launcher icon. + """ + icons = self.get_children_by_type(SimpleLauncherIcon, desktop_id=desktop_id) + if len(icons): + return icons[0] + + return None def num_launcher_icons(self): """Get the number of icons in the launcher model.""" diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/panel.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/panel.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/panel.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/panel.py 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,338 @@ +# -*- 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 time import sleep + +from autopilot.emulators.unity import UnityIntrospectionObject +from autopilot.emulators.X11 import Mouse, ScreenGeometry +from autopilot.keybindings import KeybindingsHelper + +logger = logging.getLogger(__name__) + + +class PanelController(UnityIntrospectionObject): + """The PanelController class.""" + + def get_panel_for_monitor(self, monitor_num): + """Return an instance of panel for the specified monitor, or None.""" + panels = self.get_children_by_type(UnityPanel, monitor=monitor_num) + assert(len(panels) == 1) + return panels[0] + + def get_active_panel(self): + """Return the active panel, or None.""" + panels = self.get_children_by_type(UnityPanel, active=True) + assert(len(panels) == 1) + return panels[0] + + def get_active_indicator(self): + for panel in self.get_panels: + active = panel.get_active_indicator() + if active: + return active + + return None + + @property + def get_panels(self): + """Return the available panels, or None.""" + return self.get_children_by_type(UnityPanel) + + +class UnityPanel(UnityIntrospectionObject, KeybindingsHelper): + """An individual panel for a monitor.""" + + def __init__(self, *args, **kwargs): + super(UnityPanel, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def __get_menu_view(self): + """Return the menu view.""" + menus = self.get_children_by_type(MenuView) + assert(len(menus) == 1) + return menus[0] + + def __get_window_buttons(self): + """Return the window buttons view.""" + buttons = self.menus.get_children_by_type(WindowButtons) + assert(len(buttons) == 1) + return buttons[0] + + def __get_grab_area(self): + """Return the panel grab area.""" + grab_areas = self.menus.get_children_by_type(GrabArea) + assert(len(grab_areas) == 1) + return grab_areas[0] + + def __get_indicators_view(self): + """Return the menu view.""" + indicators = self.get_children_by_type(Indicators) + assert(len(indicators) == 1) + return indicators[0] + + def move_mouse_below_the_panel(self): + """Places the mouse to bottom of this panel.""" + (x, y, w, h) = self.geometry + target_x = x + w / 2 + target_y = y + h + 10 + + logger.debug("Moving mouse away from panel.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_menus(self): + """Move the mouse over the menu area for this panel.""" + (x, y, w, h) = self.menus.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + # The menu view has bigger geometry than the real layout + menu_entries = self.menus.get_entries() + if len(menu_entries) > 0: + first_x = menu_entries[0].x + last_x = menu_entries[-1].x + menu_entries[-1].width / 2 + + target_x = first_x + (last_x - first_x) / 2 + + logger.debug("Moving mouse to center of menu area.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_grab_area(self): + """Move the mouse over the grab area for this panel.""" + (x, y, w, h) = self.grab_area.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of grab area.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_window_buttons(self): + """Move the mouse over the center of the window buttons area for this panel.""" + (x, y, w, h) = self.window_buttons.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of the window buttons.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_indicators(self): + """Move the mouse over the center of the indicators area for this panel.""" + (x, y, w, h) = self.indicators.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of the indicators area.") + self._mouse.move(target_x, target_y) + + def get_indicator_entries(self, visible_only=True, include_hidden_menus=False): + """Returns a list of entries for this panel including both menus and indicators""" + entries = [] + if include_hidden_menus or self.menus_shown: + entries = self.menus.get_entries() + entries += self.indicators.get_ordered_entries(visible_only) + return entries + + def get_active_indicator(self): + """Returns the indicator entry that is currently active""" + entries = self.get_indicator_entries(False, True) + entries = filter(lambda e: e.active == True, entries) + assert(len(entries) <= 1) + return entries[0] if entries else None + + def get_indicator_entry(self, entry_id): + """Returns the indicator entry for the given ID or None""" + entries = self.get_indicator_entries(False, True) + entries = filter(lambda e: e.entry_id == entry_id, entries) + assert(len(entries) <= 1) + return entries[0] if entries else None + + @property + def title(self): + return self.menus.panel_title + + @property + def desktop_is_active(self): + return self.menus.desktop_active + + @property + def menus_shown(self): + return self.active and self.menus.draw_menus + + @property + def window_buttons_shown(self): + return self.menus.draw_window_buttons + + @property + def window_buttons(self): + return self.__get_window_buttons() + + @property + def menus(self): + return self.__get_menu_view() + + @property + def grab_area(self): + return self.__get_grab_area() + + @property + def indicators(self): + return self.__get_indicators_view() + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current panel.""" + return (self.x, self.y, self.width, self.height) + + +class MenuView(UnityIntrospectionObject): + """The Menu View class.""" + + def get_entries(self): + """Return a list of menu entries""" + return self.get_children_by_type(IndicatorEntry) + + def get_menu_by_label(self, entry_label): + """Return the first indicator entry found with the given label""" + indicators = self.get_children_by_type(IndicatorEntry, label=entry_label) + return indicators[0] if indicators else None + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current menu view.""" + return (self.x, self.y, self.width, self.height) + + +class WindowButtons(UnityIntrospectionObject): + """The window buttons class""" + + def get_buttons(self, visible_only=True): + """Return a list of window buttons""" + if visible_only: + return self.get_children_by_type(WindowButton, visible=True) + else: + return self.get_children_by_type(WindowButton) + + def get_button(self, type): + buttons = self.get_children_by_type(WindowButton, type=type) + assert(len(buttons) == 1) + return buttons[0] + + @property + def visible(self): + return len(self.get_buttons()) != 0 + + @property + def close(self): + return self.get_button("Close") + + @property + def minimize(self): + return self.get_button("Minimize") + + @property + def unmaximize(self): + return self.get_button("Unmaximize") + + @property + def maximize(self): + return self.get_button("Maximize") + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current panel.""" + return (self.x, self.y, self.width, self.height) + + +class WindowButton(UnityIntrospectionObject): + """The Window WindowButton class.""" + + def __init__(self, *args, **kwargs): + super(WindowButton, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def mouse_move_to(self): + target_x = self.x + self.width / 2 + target_y = self.y + self.height / 2 + self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + + def mouse_click(self): + self.mouse_move_to() + sleep(.2) + self._mouse.click(press_duration=.1) + sleep(.01) + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the window button.""" + return (self.x, self.y, self.width, self.height) + + +class GrabArea(UnityIntrospectionObject): + """The grab area class""" + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the grab area.""" + return (self.x, self.y, self.width, self.height) + + +class Indicators(UnityIntrospectionObject): + """The Indicators View class.""" + + def get_ordered_entries(self, visible_only=True): + """Return a list of indicators, ordered by their priority""" + + if visible_only: + entries = self.get_children_by_type(IndicatorEntry, visible=True) + else: + entries = self.get_children_by_type(IndicatorEntry) + + return sorted(entries, key=lambda entry: entry.priority) + + def get_indicator_by_name_hint(self, name_hint): + """Return the IndicatorEntry with the name_hint""" + indicators = self.get_children_by_type(IndicatorEntry, name_hint=name_hint) + assert(len(indicators) == 1) + return indicators[0] + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the indicators area.""" + return (self.x, self.y, self.width, self.height) + + +class IndicatorEntry(UnityIntrospectionObject): + """The IndicatorEntry View class.""" + + def __init__(self, *args, **kwargs): + super(IndicatorEntry, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def mouse_move_to(self): + target_x = self.x + self.width / 2 + target_y = self.y + self.height / 2 + self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + + def mouse_click(self, button=1): + self.mouse_move_to() + sleep(.2) + assert(self.visible) + self._mouse.click(press_duration=.1) + sleep(.01) + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the indicator entry.""" + return (self.x, self.y, self.width, self.height) + + @property + def menu_geometry(self): + """Returns a tuple of (x,y,w,h) for the opened menu geometry.""" + return (self.menu_x, self.menu_y, self.menu_width, self.menu_height) + diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py 2012-04-12 13:21:21.000000000 +0000 @@ -9,8 +9,8 @@ import logging -from autopilot.keybindings import KeybindingsHelper from autopilot.emulators.unity import UnityIntrospectionObject +from autopilot.keybindings import KeybindingsHelper logger = logging.getLogger(__name__) diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/switcher.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/switcher.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/switcher.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/switcher.py 2012-04-12 13:21:21.000000000 +0000 @@ -10,14 +10,15 @@ import logging from time import sleep -from autopilot.keybindings import KeybindingsHelper from autopilot.emulators.unity import get_state_by_path, make_introspection_object from autopilot.emulators.X11 import Keyboard, Mouse +from autopilot.keybindings import KeybindingsHelper # 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. from autopilot.emulators.unity.icons import * + logger = logging.getLogger(__name__) @@ -136,11 +137,11 @@ return None def get_icon_name(self, index): - return self.__get_icon(index)['tooltip-text'] + return self.__get_icon(index)['tooltip_text'] def get_icon_desktop_file(self, index): try: - return self.__get_icon(index)['desktop-file'] + return self.__get_icon(index)['desktop_file'] except: return None diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/unity/workspace.py unity-5.10.0/tests/autopilot/autopilot/emulators/unity/workspace.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/unity/workspace.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/unity/workspace.py 2012-04-12 13:21:21.000000000 +0000 @@ -70,7 +70,6 @@ for i in range(downs): self.keybinding("workspace/move_down") - def _coordinates_to_vp_number(self, vx, vy): """Translate viewport coordinates to a viewport number.""" row,col = self._coordinates_to_row_col(vx, vy) diff -Nru unity-5.8.0/tests/autopilot/autopilot/emulators/X11.py unity-5.10.0/tests/autopilot/autopilot/emulators/X11.py --- unity-5.8.0/tests/autopilot/autopilot/emulators/X11.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/emulators/X11.py 2012-04-12 13:21:21.000000000 +0000 @@ -16,21 +16,27 @@ """ +import gtk.gdk import logging +import os +import subprocess from time import sleep -from Xlib import X -from Xlib import XK +from autopilot.emulators.bamf import BamfWindow +from Xlib import X, XK from Xlib.display import Display from Xlib.ext.xtest import fake_input -import gtk.gdk + _PRESSED_KEYS = [] _PRESSED_MOUSE_BUTTONS = [] _DISPLAY = Display() logger = logging.getLogger(__name__) - +def reset_display(): + global _DISPLAY + _DISPLAY = Display() + class Keyboard(object): """Wrapper around xlib to make faking keyboard input possible.""" @@ -255,10 +261,10 @@ fake_input(_DISPLAY, X.ButtonRelease, button) _DISPLAY.sync() - def click(self, button=1): + def click(self, button=1, press_duration=0.25): """Click mouse at current location.""" self.press(button) - sleep(0.25) + sleep(press_duration) self.release(button) def move(self, x, y, animate=True, rate=100, time_between_events=0.001): @@ -317,8 +323,12 @@ class ScreenGeometry: """Get details about screen geometry.""" + class BlacklistedDriverError(RuntimeError): + """Cannot set primary monitor when running drivers listed in the driver blacklist.""" + def __init__(self): self._default_screen = gtk.gdk.screen_get_default() + self._blacklisted_drivers = ["NVIDIA"] def get_num_monitors(self): """Get the number of monitors attached to the PC.""" @@ -327,6 +337,33 @@ def get_primary_monitor(self): return self._default_screen.get_primary_monitor() + def set_primary_monitor(self, monitor): + """Set `monitor` to be the primary monitor. + + `monitor` must be an integer between 0 and the number of configured monitors. + ValueError is raised if an invalid monitor is specified. + + BlacklistedDriverError is raised if your video driver does not support this. + + """ + glxinfo_out = subprocess.check_output("glxinfo") + for dri in self._blacklisted_drivers: + if dri in glxinfo_out: + raise ScreenGeometry.BlacklistedDriverError('Impossible change the primary monitor for the given driver') + + if monitor < 0 or monitor >= self.get_num_monitors(): + raise ValueError('Monitor %d is not in valid range of 0 <= monitor < %d.' % (self.get_num_monitors())) + + monitor_name = self._default_screen.get_monitor_plug_name(monitor) + + if not monitor_name: + raise ValueError('Could not get monitor name from monitor number %d.' % (monitor)) + + ret = os.spawnlp(os.P_WAIT, "xrandr", "xrandr", "--output", monitor_name, "--primary") + + if ret != 0: + raise RuntimeError('Xrandr can\'t set the primary monitor. error code: %d' % (ret)) + def get_screen_width(self): return self._default_screen.get_width() @@ -339,10 +376,20 @@ Returns a tuple containing (x,y,width,height). """ - if monitor_number >= self.get_num_monitors(): + if monitor_number < 0 or monitor_number >= self.get_num_monitors(): raise ValueError('Specified monitor number is out of range.') return tuple(self._default_screen.get_monitor_geometry(monitor_number)) + def is_rect_on_monitor(self, monitor_number, rect): + """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap.""" + + if type(rect) is not tuple or len(rect) != 4: + raise TypeError("rect must be a tuple of 4 int elements.") + + (x, y, w, h) = rect + (m_x, m_y, m_w, m_h) = self.get_monitor_geometry(monitor_number) + return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h) + def move_mouse_to_monitor(self, monitor_number): """Move the mouse to the center of the specified monitor.""" geo = self.get_monitor_geometry(monitor_number) @@ -350,3 +397,32 @@ y = geo[1] + (geo[3] / 2) #dont animate this or it might not get there due to barriers Mouse().move(x, y, False) + + def drag_window_to_monitor(self, window, monitor): + if not isinstance(window, BamfWindow): + raise TypeError("Window must be a BamfWindow") + + if window.monitor == monitor: + logger.debug("Window %r is already on monitor %d." % (window.x_id, monitor)) + return + + assert(not window.is_maximized) + (win_x, win_y, win_w, win_h) = window.geometry + (m_x, m_y, m_w, m_h) = self.get_monitor_geometry(monitor) + + logger.debug("Dragging window %r to monitor %d." % (window.x_id, monitor)) + + mouse = Mouse() + keyboard = Keyboard() + mouse.move(win_x + win_w/2, win_y + win_h/2) + keyboard.press("Alt") + mouse.press() + keyboard.release("Alt") + + # We do the movements in two steps, to reduce the risk of being + # blocked by the pointer barrier + target_x = m_x + m_w/2 + target_y = m_y + m_h/2 + mouse.move(win_x, target_y, rate=20, time_between_events=0.005) + mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + mouse.release() diff -Nru unity-5.8.0/tests/autopilot/autopilot/keybindings.py unity-5.10.0/tests/autopilot/autopilot/keybindings.py --- unity-5.8.0/tests/autopilot/autopilot/keybindings.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/keybindings.py 2012-04-12 13:21:21.000000000 +0000 @@ -56,8 +56,15 @@ "launcher/switcher/prev": "Shift+Tab", "launcher/switcher/down": "Down", "launcher/switcher/up": "Up", + # Panel + "panel/show_menus": "Alt", + "panel/open_first_menu": ('unityshell', 'panel_first_menu'), + "panel/next_indicator": "Right", + "panel/prev_indicator": "Left", # Dash: "dash/reveal": "Super", + "dash/lens/next": "Ctrl+Tab", + "dash/lens/prev": "Ctrl+Shift+Tab", # Lenses "lens_reveal/command": ("unityshell", "execute_command"), "lens_reveal/apps": "Super+a", @@ -90,7 +97,11 @@ "workspace/move_up": ("wall", "up_key"), "workspace/move_down": ("wall", "down_key"), # Window management + "window/show_desktop" : ("core", "show_desktop_key"), "window/minimize": ("core", "minimize_window_key"), + "window/maximize": ("core", "maximize_window_key"), + "window/restore": ("core", "unmaximize_window_key"), + "window/close": ("core", "close_window_key"), # expo plugin: "expo/start": ("expo", "expo_key"), "expo/cancel": "Escape", @@ -170,7 +181,7 @@ plugin.ShortDesc) if setting.Value == "Disabled": raise RuntimeError("Keybinding '%s' in compiz plugin '%s' has been disabled." % - setting.ShortDesc, plugin.ShortDesc) + (setting.ShortDesc, plugin.ShortDesc)) return _translate_compiz_keystroke_string(setting.Value) @@ -235,4 +246,4 @@ 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 + self.keybinding_tap(binding_name) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/__init__.py unity-5.10.0/tests/autopilot/autopilot/tests/__init__.py --- unity-5.8.0/tests/autopilot/autopilot/tests/__init__.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/__init__.py 2012-04-12 13:21:21.000000000 +0000 @@ -4,10 +4,11 @@ from compizconfig import Setting, Plugin +from dbus import DBusException import logging import os from StringIO import StringIO -from subprocess import call, Popen, PIPE, STDOUT +from subprocess import call, check_output, Popen, PIPE, STDOUT from tempfile import mktemp from testscenarios import TestWithScenarios from testtools import TestCase @@ -22,10 +23,12 @@ reset_logging, ) from autopilot.emulators.unity.dash import Dash +from autopilot.emulators.unity.hud import Hud from autopilot.emulators.unity.launcher import LauncherController +from autopilot.emulators.unity.panel import PanelController from autopilot.emulators.unity.switcher import Switcher from autopilot.emulators.unity.workspace import WorkspaceManager -from autopilot.emulators.X11 import Keyboard, Mouse +from autopilot.emulators.X11 import ScreenGeometry, Keyboard, Mouse, reset_display from autopilot.glibrunner import GlibRunner from autopilot.globals import (global_context, video_recording_enabled, @@ -38,7 +41,7 @@ try: - from testscenarios.scenarios import multiple_scenarios + from testscenarios.scenarios import multiply_scenarios except ImportError: from itertools import product def multiply_scenarios(*scenarios): @@ -112,7 +115,12 @@ self.addCleanup(self._tearDownUnityLogging) def _tearDownUnityLogging(self): - reset_logging() + # If unity dies, our dbus interface has gone, and reset_logging will fail + # but we still want our log, so we ignore any errors. + try: + reset_logging() + except DBusException: + pass 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) @@ -227,22 +235,38 @@ self.keyboard = Keyboard() self.mouse = Mouse() self.dash = Dash() + self.hud = Hud() + self.launcher = self._get_launcher_controller() + self.panels = self._get_panel_controller() self.switcher = Switcher() self.workspace = WorkspaceManager() - self.launcher = self._get_launcher_controller() + self.screen_geo = ScreenGeometry() self.addCleanup(self.workspace.switch_to, self.workspace.current_workspace) self.addCleanup(Keyboard.cleanup) self.addCleanup(Mouse.cleanup) - def start_app(self, app_name, files=[]): + def start_app(self, app_name, files=[], locale=None): """Start one of the known apps, and kill it on tear down. - if files is specified, start the application with the specified files. + If files is specified, start the application with the specified files. + If locale is specified, the locale will be set when the application is launched. + + The method returns the BamfApplication instance. + """ - logger.info("Starting application '%s'", app_name) + if locale: + os.putenv("LC_ALL", locale) + self.addCleanup(os.unsetenv, "LC_ALL") + logger.info("Starting application '%s' with files %r in locale %s", app_name, files, locale) + else: + logger.info("Starting application '%s' with files %r", app_name, files) + app = self.KNOWN_APPS[app_name] self.bamf.launch_application(app['desktop-file'], files) + apps = self.bamf.get_running_applications_by_desktop_file(app['desktop-file']) self.addCleanup(call, ["killall", app['process-name']]) + self.assertThat(len(apps), Equals(1)) + return apps[0] def close_all_app(self, app_name): """Close all instances of the app_name.""" @@ -260,6 +284,21 @@ apps = self.get_app_instances(app_name) return len(apps) > 0 + def call_gsettings_cmd(self, command, schema, *args): + """Set a desktop wide gsettings option + + Using the gsettings command because there's a bug with importing + from gobject introspection and pygtk2 simultaneously, and the Xlib + keyboard layout bits are very unweildy. This seems like the best + solution, even a little bit brutish. + """ + cmd = ['gsettings', command, schema] + args + # strip to remove the trailing \n. + ret = check_output(cmd, shell=True).strip() + time.sleep(1) + reset_display() + return ret + def set_unity_option(self, option_name, option_value): """Set an option in the unity compiz plugin options. @@ -274,6 +313,8 @@ """ old_value = self._set_compiz_option(plugin_name, setting_name, setting_value) self.addCleanup(self._set_compiz_option, plugin_name, setting_name, old_value) + # Allow unity time to respond to the new setting. + time.sleep(0.5) def _set_compiz_option(self, plugin_name, option_name, option_value): logger.info("Setting compiz option '%s' in plugin '%s' to %r", @@ -289,3 +330,8 @@ controllers = LauncherController.get_all_instances() self.assertThat(len(controllers), Equals(1)) return controllers[0] + + def _get_panel_controller(self): + controllers = PanelController.get_all_instances() + self.assertThat(len(controllers), Equals(1)) + return controllers[0] diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_command_lens.py unity-5.10.0/tests/autopilot/autopilot/tests/test_command_lens.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_command_lens.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_command_lens.py 2012-04-12 13:21:21.000000000 +0000 @@ -6,10 +6,9 @@ # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -from subprocess import call +from testtools.matchers import Equals from time import sleep -from autopilot.emulators.bamf import Bamf from autopilot.emulators.unity.dash import Dash from autopilot.emulators.X11 import Keyboard from autopilot.tests import AutopilotTestCase @@ -77,3 +76,17 @@ self.addCleanup(self.close_all_app, "Text Editor") app_found = self.bamf.wait_until_application_is_running("gedit.desktop", 5) self.assertTrue(app_found) + + def test_ctrl_tab_switching(self): + """Pressing Ctrl+Tab after launching command lens must switch to Home lens.""" + self.dash.reveal_command_lens() + self.keybinding("dash/lens/next") + sleep(1) + self.assertThat(self.dash.active_lens, Equals("home.lens")) + + def test_ctrl_shift_tab_switching(self): + """Pressing Ctrl+Shift+Tab after launching command lens must switch to Video lens.""" + self.dash.reveal_command_lens() + self.keybinding("dash/lens/prev") + sleep(1) + self.assertThat(self.dash.active_lens, Equals("video.lens")) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_dash.py unity-5.10.0/tests/autopilot/autopilot/tests/test_dash.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_dash.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_dash.py 2012-04-12 13:21:21.000000000 +0000 @@ -11,7 +11,6 @@ from gtk import Clipboard from testtools.matchers import Equals -from autopilot.emulators.X11 import Keyboard, Mouse from autopilot.tests import AutopilotTestCase @@ -75,6 +74,18 @@ self.keyboard.type("Hello") self.assertSearchText("Hello") +class DashMultiKeyTests(DashSearchInputTests): + def setUp(self): + def set_multi_key(): + """Binds Multi_key to caps lock""" + old_value = "\"%s\"" % self.call_gsettings_cmd('get', 'org.gnome.libgnomekbd.keyboard', '"options"') + self.addCleanup(self.call_gsettings_cmd, 'set', 'org.gnome.libgnomekbd.keyboard', '"options"', old_value) + self.call_gsettings_cmd('set', 'org.gnome.libgnomekbd.keyboard', '"options"', "\"['Compose key\tcompose:caps']\"") + + # set the multi key first so that we're not getting a new _DISPLAY while keys are held down. + set_multi_key() + super(DashMultiKeyTests, self).setUp() + def test_multi_key(self): """Pressing 'Multi_key' must not add any characters to the search.""" self.dash.reveal_application_lens() @@ -301,6 +312,15 @@ category = lens.get_focused_category() self.assertIsNot(category, None) + def test_alt_f1_disabled(self): + """This test that Alt+F1 is disabled when the dash is opened.""" + self.dash.ensure_visible() + + launcher = self.launcher.get_launcher_for_monitor(0) + launcher.key_nav_start() + + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + class DashClipboardTests(DashTestCase): """Test the Unity clipboard""" @@ -432,7 +452,7 @@ 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()): @@ -488,3 +508,23 @@ 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)) + +class DashLensBarTests(DashTestCase): + """Tests that the lensbar works well.""" + def setUp(self): + super(DashLensBarTests, self).setUp() + self.dash.ensure_visible() + self.lensbar = self.dash.view.get_lensbar() + + def test_click_inside_highlight(self): + """Lens selection should work when clicking in + the rectangle outside of the icon. + """ + app_icon = self.lensbar.get_icon_by_name(u'applications.lens') + + self.mouse.move(app_icon.x, app_icon.y) + self.mouse.click() + + sleep(1) + + self.assertEqual(self.lensbar.active_lens, u'applications.lens') diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_home_lens.py unity-5.10.0/tests/autopilot/autopilot/tests/test_home_lens.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_home_lens.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_home_lens.py 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,38 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Michal Hruby +# +# 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 time import sleep + +from autopilot.tests import AutopilotTestCase + + +class HomeLensSearchTests(AutopilotTestCase): + """Test the command lense search bahavior.""" + + def setUp(self): + super(HomeLensSearchTests, self).setUp() + + def tearDown(self): + self.dash.ensure_hidden() + super(HomeLensSearchTests, self).tearDown() + + def test_quick_run_app(self): + """Hitting enter runs an application even though a search might not have fully finished yet.""" + if self.app_is_running("Text Editor"): + self.close_all_app("Text Editor") + sleep(1) + + kb = self.keyboard + self.dash.ensure_visible() + kb.type("g") + sleep(1) + kb.type("edit", 0.1) + kb.press_and_release("Enter", 0.1) + self.addCleanup(self.close_all_app, "Text Editor") + app_found = self.bamf.wait_until_application_is_running("gedit.desktop", 5) + self.assertTrue(app_found) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_hud.py unity-5.10.0/tests/autopilot/autopilot/tests/test_hud.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_hud.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_hud.py 2012-04-12 13:21:21.000000000 +0000 @@ -1,50 +1,50 @@ # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- -# Copyright 2010 Canonical -# Author: Alex Launi +# Copyright 2012 Canonical +# Author: Alex Launi, +# Marco Trevisan # # 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, LessThan +from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan from time import sleep -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}), - ] +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.emulators.unity.icons import HudLauncherIcon +from autopilot.tests import AutopilotTestCase, multiply_scenarios +from os import remove, path + + +def _make_monitor_scenarios(): + num_monitors = ScreenGeometry().get_num_monitors() + scenarios = [] + + if num_monitors == 1: + scenarios = [('Single Monitor', {'hud_monitor': 0})] + else: + for i in range(num_monitors): + scenarios += [('Monitor %d' % (i), {'hud_monitor': i})] + + return scenarios + + +class HudTestsBase(AutopilotTestCase): 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() + super(HudTestsBase, self).setUp() def tearDown(self): self.hud.ensure_hidden() - super(HudTests, self).tearDown() - - def get_hud_controller(self): - controllers = HudController.get_all_instances() - self.assertEqual(1, len(controllers)) - return controllers[0] + super(HudTestsBase, self).tearDown() def get_num_active_launcher_icons(self): num_active = 0 for icon in self.launcher.model.get_launcher_icons(): - if icon.quirk_active and icon.quirk_visible: + if icon.active and icon.visible: num_active += 1 return num_active - def test_initially_hidden(self): - self.assertFalse(self.hud.visible) - def reveal_hud(self): self.hud.toggle_reveal() for counter in range(10): @@ -53,6 +53,15 @@ break self.assertTrue(self.hud.visible, "HUD did not appear.") + +class HudBehaviorTests(HudTestsBase): + + def setUp(self): + super(HudBehaviorTests, self).setUp() + + self.hud_monitor = self.screen_geo.get_primary_monitor() + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + def test_no_initial_values(self): self.reveal_hud() self.assertThat(self.hud.num_buttons, Equals(0)) @@ -94,6 +103,16 @@ self.keyboard.press_and_release('Up') self.assertThat(self.hud.selected_button, Equals(1)) + def test_no_reset_selected_button(self): + self.reveal_hud() + self.keyboard.type('is') + sleep(1) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Equals(2)) + # long sleep to let the service send updated results + sleep(10) + self.assertThat(self.hud.selected_button, Equals(2)) + def test_slow_tap_not_reveal_hud(self): self.hud.toggle_reveal(tap_delay=0.3) sleep(1) @@ -109,8 +128,8 @@ def test_reveal_hud_with_no_apps(self): """Hud must show even with no visible applications.""" - self.keyboard.press_and_release("Ctrl+Alt+d") - self.addCleanup(self.keyboard.press_and_release, "Ctrl+Alt+d") + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") sleep(1) self.hud.toggle_reveal() @@ -121,44 +140,11 @@ sleep(1) 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 - apps as active. - - """ - # We need an app to switch to: - self.start_app('Character Map') - # We need an application to play with - I'll use the calculator. - self.start_app('Calculator') - sleep(1) - - # before we start, make sure there's zero or one active icon: - num_active = self.get_num_active_launcher_icons() - self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") - - # reveal and hide hud several times over: - for i in range(3): - self.hud.ensure_visible() - sleep(0.5) - self.hud.ensure_hidden() - sleep(0.5) - - # click application icons for running apps in the launcher: - icon = self.launcher.model.get_icon_by_tooltip_text("Character Map") - self.launcher.get_launcher_for_monitor(0).click_launcher_icon(icon) - - # see how many apps are marked as being active: - num_active = self.get_num_active_launcher_icons() - self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!") - def test_restore_focus(self): """Ensures that once the hud is dismissed, the same application that was focused before hud invocation is refocused """ - self.start_app("Calculator") - calc = self.get_app_instances("Calculator") - self.assertThat(len(calc), Equals(1)) - calc = calc[0] + calc = self.start_app("Calculator") # first ensure that the application has started and is focused self.assertEqual(calc.is_active, True) @@ -191,7 +177,7 @@ """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']) + self.start_app('Text Editor', files=['/tmp/autopilot_gedit_undo_test_temp_file.txt'], locale='C') sleep(1) self.keyboard.type("0") @@ -202,8 +188,9 @@ sleep(1) self.keyboard.type("undo") - self.keyboard.press_and_release('Return') sleep(1) + self.keyboard.press_and_release('Return') + sleep(.5) self.keyboard.press_and_release("Ctrl+s") sleep(1) @@ -211,3 +198,302 @@ contents = open("/tmp/autopilot_gedit_undo_test_temp_file.txt").read().strip('\n') self.assertEqual("0 ", contents) + def test_disabled_alt_f1(self): + """This test shows that Alt+F1 mode is disabled for the hud.""" + self.hud.toggle_reveal() + + launcher = self.launcher.get_launcher_for_monitor(0) + launcher.key_nav_start() + + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + + def test_hud_to_dash_disabled_alt_f1(self): + """When switching from the hud to the dash alt+f1 is disabled.""" + self.hud.toggle_reveal() + sleep(1) + + self.dash.ensure_visible() + + launcher = self.launcher.get_launcher_for_monitor(0) + launcher.key_nav_start() + + self.dash.ensure_hidden() + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + + def test_hud_to_dash_has_key_focus(self): + """When switching from the hud to the dash you don't lose key focus.""" + self.hud.ensure_visible() + sleep(1) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.keyboard.type('focus1') + + self.assertEqual(self.dash.search_string, 'focus1') + + def test_dash_to_hud_has_key_focus(self): + """When switching from the dash to the hud you don't lose key focus.""" + self.dash.ensure_visible() + self.hud.ensure_visible() + sleep(1) + + self.keyboard.type('focus2') + + self.assertEqual(self.hud.search_string, 'focus2') + + def test_hud_closes_on_workspace_switch(self): + """This test shows that when you switch to another workspace the hud closes.""" + self.hud.toggle_reveal() + sleep(1) + + self.workspace.switch_to(1) + self.workspace.switch_to(2) + + +class HudLauncherInteractionsTests(HudTestsBase): + + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), + ('Launcher never hide', {'launcher_autohide': True})] + + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes) + + def setUp(self): + super(HudLauncherInteractionsTests, self).setUp() + # Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) + + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + sleep(0.5) + + def test_multiple_hud_reveal_does_not_break_launcher(self): + """Multiple Hud reveals must not cause the launcher to set multiple + apps as active. + + """ + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) + + # We need an app to switch to: + self.start_app('Character Map') + # We need an application to play with - I'll use the calculator. + self.start_app('Calculator') + sleep(1) + + # before we start, make sure there's zero or one active icon: + num_active = self.get_num_active_launcher_icons() + self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") + + # reveal and hide hud several times over: + for i in range(3): + self.hud.ensure_visible() + sleep(0.5) + self.hud.ensure_hidden() + sleep(0.5) + + # click application icons for running apps in the launcher: + icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop") + launcher.click_launcher_icon(icon) + + # see how many apps are marked as being active: + num_active = self.get_num_active_launcher_icons() + self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!") + + def test_hud_does_not_change_launcher_status(self): + """Tests if the HUD reveal keeps the launcher in the status it was""" + + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) + + launcher_shows_pre = launcher.is_showing() + sleep(.25) + + self.reveal_hud() + sleep(1) + + launcher_shows_post = launcher.is_showing() + self.assertThat(launcher_shows_pre, Equals(launcher_shows_post)) + + +class HudLockedLauncherInteractionsTests(HudTestsBase): + + scenarios = _make_monitor_scenarios() + + def setUp(self): + super(HudLockedLauncherInteractionsTests, self).setUp() + # Locked Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', 0) + + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + sleep(0.5) + + def test_hud_launcher_icon_hides_bfb(self): + """Tests that the BFB icon is hidden when the HUD launcher icon is shown""" + + hud_icon = self.hud.get_launcher_icon() + bfb_icon = self.launcher.model.get_bfb_icon() + + self.assertTrue(bfb_icon.is_visible_on_monitor(self.hud_monitor)) + self.assertFalse(hud_icon.is_visible_on_monitor(self.hud_monitor)) + sleep(.25) + + self.reveal_hud() + sleep(.5) + + self.assertTrue(hud_icon.is_visible_on_monitor(self.hud_monitor)) + self.assertFalse(bfb_icon.is_visible_on_monitor(self.hud_monitor)) + + def test_hud_desaturates_launcher_icons(self): + """Tests that the launcher icons are desaturates when HUD is open""" + + self.reveal_hud() + sleep(.5) + + for icon in self.launcher.model.get_launcher_icons_for_monitor(self.hud_monitor): + if isinstance(icon, HudLauncherIcon): + self.assertFalse(icon.desaturated) + else: + self.assertTrue(icon.desaturated) + + +class HudVisualTests(HudTestsBase): + + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), + ('Launcher never hide', {'launcher_autohide': True})] + + launcher_screen = [('Launcher on primary monitor', {'launcher_primary_only': False}), + ('Launcher on all monitors', {'launcher_primary_only': True})] + + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes, launcher_screen) + + def setUp(self): + super(HudVisualTests, self).setUp() + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) + self.set_unity_option('num_launchers', int(self.launcher_primary_only)) + self.hud_monitor_is_primary = (self.screen_geo.get_primary_monitor() == self.hud_monitor) + self.hud_locked = (not self.launcher_autohide and (not self.launcher_primary_only or self.hud_monitor_is_primary)) + sleep(0.5) + + def test_initially_hidden(self): + self.assertFalse(self.hud.visible) + + def test_hud_is_on_right_monitor(self): + """Tests if the hud is shown and fits the monitor where it should be""" + self.reveal_hud() + self.assertThat(self.hud_monitor, Equals(self.hud.monitor)) + self.assertTrue(self.screen_geo.is_rect_on_monitor(self.hud.monitor, self.hud.geometry)) + + def test_hud_geometries(self): + """Tests the HUD geometries for the given monitor and status""" + self.reveal_hud() + monitor_geo = self.screen_geo.get_monitor_geometry(self.hud_monitor) + monitor_x = monitor_geo[0] + monitor_w = monitor_geo[2] + hud_x = self.hud.geometry[0] + hud_w = self.hud.geometry[2] + + if self.hud_locked: + self.assertThat(hud_x, GreaterThan(monitor_x)) + self.assertThat(hud_x, LessThan(monitor_x + monitor_w)) + self.assertThat(hud_w, Equals(monitor_x + monitor_w - hud_x)) + else: + self.assertThat(hud_x, Equals(monitor_x)) + self.assertThat(hud_w, Equals(monitor_w)) + + def test_hud_is_locked_to_launcher(self): + """Tests if the HUD is locked to launcher as we expect or not""" + self.reveal_hud() + sleep(.25) + + self.assertThat(self.hud.is_locked_launcher, Equals(self.hud_locked)) + + def test_hud_icon_is_shown(self): + """Tests that the correct HUD icon is shown""" + self.reveal_hud() + sleep(.5) + + hud_launcher_icon = self.hud.get_launcher_icon() + hud_embedded_icon = self.hud.get_embedded_icon() + + if self.hud.is_locked_launcher: + self.assertTrue(hud_launcher_icon.is_visible_on_monitor(self.hud_monitor)) + self.assertTrue(hud_launcher_icon.active) + self.assertThat(hud_launcher_icon.monitor, Equals(self.hud_monitor)) + self.assertFalse(hud_launcher_icon.desaturated) + self.assertThat(hud_embedded_icon, Equals(None)) + else: + self.assertFalse(hud_launcher_icon.is_visible_on_monitor(self.hud_monitor)) + self.assertFalse(hud_launcher_icon.active) + self.assertThat(hud_embedded_icon, NotEquals(None)) + + def test_hud_icon_shows_the_focused_application_emblem(self): + """Tests that the correct HUD icon is shown""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.reveal_hud() + sleep(.5) + + self.assertThat(self.hud.icon.icon_name, Equals(calc.icon)) + + def test_hud_icon_shows_the_ubuntu_emblem_on_empty_desktop(self): + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") + sleep(1) + + self.reveal_hud() + sleep(.5) + + self.assertThat(path.basename(self.hud.icon.icon_name), Equals("launcher_bfb.png")) + + def test_switch_dash_hud_does_not_break_the_focused_application_emblem(self): + """Tests that the correct HUD icon is shown when switching from Dash to HUD""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.dash.ensure_visible() + self.reveal_hud() + sleep(.5) + + self.assertThat(self.hud.icon.icon_name, Equals(calc.icon)) + + def test_switch_hud_dash_does_not_break_the_focused_application_emblem(self): + """Tests that the correct HUD icon is shown when switching from HUD to Dash and back""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.reveal_hud() + self.dash.ensure_visible() + self.reveal_hud() + sleep(.5) + + self.assertThat(self.hud.icon.icon_name, Equals(calc.icon)) + + +class HudAlternativeKeybindingTests(HudTestsBase): + + def test_super_h(self): + """Test hud reveal on h.""" + self.set_unity_option("show_hud", "h") + # Don't use reveal_hud, but be explicit in the keybindings. + self.keyboard.press_and_release("Super+h") + for counter in range(10): + sleep(1) + if self.hud.visible: + break + self.assertTrue(self.hud.visible, "HUD did not appear.") + + def test_ctrl_alt_h(self): + """Test hud reveal on h.""" + self.set_unity_option("show_hud", "h") + # Don't use reveal_hud, but be explicit in the keybindings. + self.keyboard.press_and_release("Ctrl+Alt+h") + for counter in range(10): + sleep(1) + if self.hud.visible: + break + self.assertTrue(self.hud.visible, "HUD did not appear.") diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_ibus.py unity-5.10.0/tests/autopilot/autopilot/tests/test_ibus.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_ibus.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_ibus.py 2012-04-12 13:21:21.000000000 +0000 @@ -6,25 +6,22 @@ # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -"Tests to ensure unity is compatible with ibus input method." +"""Tests to ensure unity is compatible with ibus input method.""" + +from time import sleep from autopilot.emulators.ibus import ( set_active_engines, get_available_input_engines, ) -from autopilot.emulators.unity.dash import Dash -from autopilot.emulators.X11 import Keyboard from autopilot.tests import AutopilotTestCase, multiply_scenarios -from time import sleep class IBusTests(AutopilotTestCase): """Base class for IBus tests.""" def setUp(self): super(IBusTests, self).setUp() - self.kb = Keyboard() - self.dash = Dash() self._old_engines = None def tearDown(self): @@ -41,11 +38,11 @@ def activate_ibus(self): # it would be nice to be able to tell if it's currently active or not. - self.kb.press_and_release('Ctrl+Space') + self.keyboard.press_and_release('Ctrl+Space') def deactivate_ibus(self): # it would be nice to be able to tell if it's currently active or not. - self.kb.press_and_release('Ctrl+Space') + self.keyboard.press_and_release('Ctrl+Space') class IBusTestsPinyin(IBusTests): @@ -59,19 +56,32 @@ ('disk_management', {'input': 'cipan guanli ', 'result': u'\u78c1\u76d8\u7ba1\u7406'}), ] - def test_simple_input(self): + def test_simple_input_dash(self): self.activate_input_engine_or_skip("pinyin") self.dash.ensure_visible() sleep(0.5) self.activate_ibus() sleep(0.5) - self.kb.type(self.input) - dash_search_string = self.dash.get_searchbar().search_string + self.keyboard.type(self.input) + dash_search_string = self.dash.search_string self.deactivate_ibus() self.dash.ensure_hidden() self.assertEqual(self.result, dash_search_string) + def test_simple_input_hud(self): + self.activate_input_engine_or_skip("pinyin") + self.hud.ensure_visible() + sleep(0.5) + self.activate_ibus() + sleep(0.5) + self.keyboard.type(self.input) + hud_search_string = self.hud.search_string + self.deactivate_ibus() + self.hud.ensure_hidden() + + self.assertEqual(self.result, hud_search_string) + class IBusTestsHangul(IBusTests): """Tests for the Hangul(Korean) input engine.""" @@ -82,19 +92,32 @@ ('document', {'input': 'anstj ', 'result': u'\ubb38\uc11c '}), ] - def test_simple_input(self): + def test_simple_input_dash(self): self.activate_input_engine_or_skip("hangul") self.dash.ensure_visible() sleep(0.5) self.activate_ibus() sleep(0.5) - self.kb.type(self.input) - dash_search_string = self.dash.get_searchbar().search_string + self.keyboard.type(self.input) + dash_search_string = self.dash.search_string self.deactivate_ibus() self.dash.ensure_hidden() self.assertEqual(self.result, dash_search_string) + def test_simple_input_hud(self): + self.activate_input_engine_or_skip("hangul") + self.hud.ensure_visible() + sleep(0.5) + self.activate_ibus() + sleep(0.5) + self.keyboard.type(self.input) + hud_search_string = self.hud.search_string + self.deactivate_ibus() + self.hud.ensure_hidden() + + self.assertEqual(self.result, hud_search_string) + class IBusTestsAnthy(IBusTests): """Tests for the Anthy(Japanese) input engine.""" @@ -111,16 +134,100 @@ ] ) - def test_simple_input(self): + def test_simple_input_dash(self): self.activate_input_engine_or_skip("anthy") self.dash.ensure_visible() sleep(0.5) self.activate_ibus() sleep(0.5) - self.kb.type(self.input) - self.kb.press_and_release(self.commit_key) - dash_search_string = self.dash.get_searchbar().search_string + self.keyboard.type(self.input) + self.keyboard.press_and_release(self.commit_key) + dash_search_string = self.dash.search_string self.deactivate_ibus() self.dash.ensure_hidden() self.assertEqual(self.result, dash_search_string) + + def test_simple_input_hud(self): + self.activate_input_engine_or_skip("anthy") + self.hud.ensure_visible() + sleep(0.5) + self.activate_ibus() + sleep(0.5) + self.keyboard.type(self.input) + self.keyboard.press_and_release(self.commit_key) + hud_search_string = self.hud.search_string + self.deactivate_ibus() + self.hud.ensure_hidden() + + self.assertEqual(self.result, hud_search_string) + + +class IBusTestsPinyinIgnore(IBusTests): + """Tests for ignoring key events while the Pinyin input engine is active.""" + + def test_ignore_key_events_on_dash(self): + self.activate_input_engine_or_skip("pinyin") + self.dash.ensure_visible() + sleep(0.5) + self.activate_ibus() + sleep(0.5) + self.keyboard.type("cipan") + self.keyboard.press_and_release("Tab") + self.keyboard.type(" ") + dash_search_string = self.dash.get_searchbar().search_string + self.deactivate_ibus() + self.dash.ensure_hidden() + + self.assertNotEqual(" ", dash_search_string) + + def test_ignore_key_events_on_hud(self): + self.activate_input_engine_or_skip("pinyin") + self.hud.ensure_visible() + sleep(0.5) + self.keyboard.type("a") + self.activate_ibus() + sleep(0.5) + self.keyboard.type("riqi") + old_selected = self.hud.selected_button + self.keyboard.press_and_release("Down") + new_selected = self.hud.selected_button + self.deactivate_ibus() + self.hud.ensure_hidden() + + self.assertEqual(old_selected, new_selected) + + +class IBusTestsAnthyIgnore(IBusTests): + """Tests for ignoring key events while the Anthy input engine is active.""" + + def test_ignore_key_events_on_dash(self): + self.activate_input_engine_or_skip("anthy") + self.dash.ensure_visible() + sleep(0.5) + self.activate_ibus() + sleep(0.5) + self.keyboard.type("shisutemu ") + self.keyboard.press_and_release("Tab") + self.keyboard.press_and_release("Ctrl+j") + dash_search_string = self.dash.get_searchbar().search_string + self.deactivate_ibus() + self.dash.ensure_hidden() + + self.assertNotEqual("", dash_search_string) + + def test_ignore_key_events_on_hud(self): + self.activate_input_engine_or_skip("anthy") + self.hud.ensure_visible() + sleep(0.5) + self.keyboard.type("a") + self.activate_ibus() + sleep(0.5) + self.keyboard.type("hiduke") + old_selected = self.hud.selected_button + self.keyboard.press_and_release("Down") + new_selected = self.hud.selected_button + self.deactivate_ibus() + self.hud.ensure_hidden() + + self.assertEqual(old_selected, new_selected) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_launcher.py unity-5.10.0/tests/autopilot/autopilot/tests/test_launcher.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_launcher.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_launcher.py 2012-04-12 13:21:21.000000000 +0000 @@ -11,8 +11,9 @@ from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan from time import sleep -from autopilot.tests import AutopilotTestCase +from autopilot.tests import AutopilotTestCase, multiply_scenarios from autopilot.emulators.X11 import ScreenGeometry +from autopilot.emulators.unity.icons import BFBLauncherIcon logger = logging.getLogger(__name__) @@ -22,83 +23,87 @@ """ screen_geometry = ScreenGeometry() num_monitors = screen_geometry.get_num_monitors() + + # it doesn't make sense to set only_primary when we're running in a single-monitor setup. if num_monitors == 1: - return [('Single Monitor', {'launcher_num': 0})] - else: - return [('Monitor %d' % (i), {'launcher_num': i}) for i in range(num_monitors)] + return [('Single Monitor', {'launcher_monitor': 0, 'only_primary': False})] + monitor_scenarios = [('Monitor %d' % (i), {'launcher_monitor': i}) for i in range(num_monitors)] + launcher_mode_scenarios = [('launcher_on_primary', {'only_primary': True}), + ('launcher on all', {'only_primary': False})] + return multiply_scenarios(monitor_scenarios, launcher_mode_scenarios) -class ScenariodLauncherTests(AutopilotTestCase): - """A base class for all launcher tests that want to use scenarios to run on +class LauncherTestCase(AutopilotTestCase): + """A base class for all launcher tests that uses scenarios to run on each launcher (for multi-monitor setups). """ - scenarios = _make_scenarios() + def setUp(self): + super(LauncherTestCase, self).setUp() + self.screen_geo = ScreenGeometry() + self.set_unity_log_level("unity.launcher", "DEBUG") + self.set_unity_option('num_launchers', int(self.only_primary)) + self.launcher_instance = self.get_launcher() + + if self.only_primary: + try: + old_primary_screen = self.screen_geo.get_primary_monitor() + self.screen_geo.set_primary_monitor(self.launcher_monitor) + self.addCleanup(self.screen_geo.set_primary_monitor, old_primary_screen) + except ScreenGeometry.BlacklistedDriverError: + self.skipTest("Impossible to set the monitor %d as primary" % self.launcher_monitor) + + def tearDown(self): + super(LauncherTestCase, self).tearDown() + self.set_unity_log_level("unity.launcher", "INFO") + def get_launcher(self): """Get the launcher for the current scenario.""" - return self.launcher.get_launcher_for_monitor(self.launcher_num) + return self.launcher.get_launcher_for_monitor(self.launcher_monitor) +class LauncherSwitcherTests(LauncherTestCase): + """ Tests the functionality of the launcher's switcher capability""" + def setUp(self): - super(ScenariodLauncherTests, self).setUp() - # 0 means launchers on all monitors. - self.set_unity_option('num_launchers', 0) - self.set_unity_log_level("unity.launcher", "DEBUG") + super(LauncherSwitcherTests, self).setUp() + self.launcher_instance.switcher_start() + sleep(0.5) + def tearDown(self): + super(LauncherSwitcherTests, self).tearDown() + if self.launcher_instance.in_switcher_mode: + self.launcher_instance.switcher_cancel() -class LauncherTests(ScenariodLauncherTests): - """Test the launcher.""" + def test_launcher_switcher_cancel(self): + """Test that ending the launcher switcher actually works.""" + self.launcher_instance.switcher_cancel() + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) - def setUp(self): - super(LauncherTests, self).setUp() - sleep(1) + def test_launcher_switcher_cancel_resume_focus(self): + """Test that ending the launcher switcher resume the focus.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) - def test_launcher_switcher_starts_at_index_zero(self): - """Test that starting the Launcher switcher puts the keyboard focus on item 0.""" + self.launcher_instance.switcher_start() sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) + self.assertFalse(calc.is_active) + + self.launcher_instance.switcher_cancel() sleep(.5) + self.assertTrue(calc.is_active) + def test_launcher_switcher_starts_at_index_zero(self): + """Test that starting the Launcher switcher puts the keyboard focus on item 0.""" self.assertThat(self.launcher.key_nav_is_active, Equals(True)) self.assertThat(self.launcher.key_nav_is_grabbed, Equals(False)) self.assertThat(self.launcher.key_nav_selection, Equals(0)) - def test_launcher_switcher_cancel_works(self): - """Test that ending the launcher switcher actually works.""" - sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.switcher_start() - sleep(.5) - 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): + def test_launcher_switcher_next(self): """Moving to the next launcher item while switcher is activated must work.""" - sleep(.5) - launcher_instance = self.get_launcher() - 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.launcher_instance.switcher_next() + sleep(0.5) logger.info("After next, keynav selection is %d", self.launcher.key_nav_selection) # The launcher model has hidden items, so the keynav indexes do not # increase by 1 each time. This test was failing because the 2nd icon @@ -108,29 +113,14 @@ # 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): + def test_launcher_switcher_prev(self): """Moving to the previous launcher item 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_prev() - sleep(.25) + self.launcher_instance.switcher_prev() self.assertThat(self.launcher.key_nav_selection, NotEquals(0)) - def test_launcher_switcher_down_works(self): + def test_launcher_switcher_down(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_down() + self.launcher_instance.switcher_down() sleep(.25) # The launcher model has hidden items, so the keynav indexes do not # increase by 1 each time. This test was failing because the 2nd icon @@ -140,57 +130,32 @@ # 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): + def test_launcher_switcher_up(self): """Pressing the up 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_up() - sleep(.25) + self.launcher_instance.switcher_up() 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.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) - sleep(.5) - launcher_instance.switcher_next() + self.launcher_instance.switcher_next() + # sleep so that the shortcut timeout could be triggered sleep(2) - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(False)) + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(False)) def test_launcher_switcher_prev_doesnt_show_shortcuts(self): """Moving backward in launcher switcher must not show launcher shortcuts.""" - sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) - sleep(.5) - launcher_instance.switcher_next() + self.launcher_instance.switcher_prev() + # sleep so that the shortcut timeout could be triggered sleep(2) - launcher_instance.switcher_prev() - sleep(2) - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(False)) - + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(False)) def test_launcher_switcher_cycling_forward(self): """Launcher Switcher must loop through icons when cycling forwards""" - sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) - sleep(.5) - prev_icon = 0 num_icons = self.launcher.model.num_launcher_icons() logger.info("This launcher has %d icons", num_icons) for icon in range(1, num_icons): - launcher_instance.switcher_next() + self.launcher_instance.switcher_next() sleep(.25) # FIXME We can't directly check for selection/icon number equalty # since the launcher model also contains "hidden" icons that aren't @@ -199,135 +164,140 @@ prev_icon = self.launcher.key_nav_selection sleep(.5) - launcher_instance.switcher_next() + self.launcher_instance.switcher_next() self.assertThat(self.launcher.key_nav_selection, Equals(0)) def test_launcher_switcher_cycling_backward(self): """Launcher Switcher must loop through icons when cycling backwards""" - sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) - sleep(.5) - - launcher_instance.switcher_prev() + self.launcher_instance.switcher_prev() # FIXME We can't directly check for self.launcher.num_launcher_icons - 1 self.assertThat(self.launcher.key_nav_selection, GreaterThan(1)) - def test_launcher_keyboard_reveal_works(self): - """Revealing launcher with keyboard must work.""" - launcher_instance = self.get_launcher() - launcher_instance.keyboard_reveal_launcher() - self.addCleanup(launcher_instance.keyboard_unreveal_launcher) - sleep(0.5) - self.assertThat(launcher_instance.is_showing(), Equals(True)) + def test_launcher_switcher_activate_keep_focus(self): + """Activating a running launcher icon should focus it""" + calc = self.start_app("Calculator") + sleep(.5) + + self.close_all_app("Mahjongg") + mahjongg = self.start_app("Mahjongg") + self.assertTrue(mahjongg.is_active) + self.assertFalse(calc.is_active) + + self.launcher_instance.switcher_start() + + found = False + for icon in self.launcher.model.get_launcher_icons_for_monitor(self.launcher_monitor): + if (icon.tooltip_text == calc.name): + found = True + # FIXME: When releasing the keybinding another "next" is done + self.launcher_instance.switcher_prev() + self.launcher_instance.switcher_activate() + break + else: + self.launcher_instance.switcher_next() + + sleep(.5) + if not found: + self.addCleanup(self.launcher_instance.switcher_cancel) + + self.assertTrue(found) + self.assertTrue(calc.is_active) + self.assertFalse(mahjongg.is_active) + + def test_launcher_switcher_using_shorcuts(self): + """Using some other shortcut while switcher is active must cancel switcher.""" + self.keyboard.press_and_release("s") + sleep(.25) + self.keyboard.press_and_release("Escape") + sleep(.25) + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + +class LauncherShortcutTests(LauncherTestCase): + def setUp(self): + super(LauncherShortcutTests, self).setUp() + self.launcher_instance.keyboard_reveal_launcher() + sleep(2) + + def tearDown(self): + super(LauncherShortcutTests, self).tearDown() + self.launcher_instance.keyboard_unreveal_launcher() def test_launcher_keyboard_reveal_shows_shortcut_hints(self): """Launcher icons must show shortcut hints after revealing with keyboard.""" - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.keyboard_reveal_launcher() - self.addCleanup(launcher_instance.keyboard_unreveal_launcher) - sleep(1) - - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(True)) + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True)) def test_launcher_switcher_keeps_shorcuts(self): """Initiating launcher switcher after showing shortcuts must not hide shortcuts""" - sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.keyboard_reveal_launcher() - self.addCleanup(launcher_instance.keyboard_unreveal_launcher) - sleep(1) - - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) + self.addCleanup(self.launcher_instance.switcher_cancel) + self.launcher_instance.switcher_start() sleep(.5) self.assertThat(self.launcher.key_nav_is_active, Equals(True)) - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(True)) + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True)) - def test_launcher_switcher_next_and_prev_keep_shortcuts(self): - """Launcher switcher next and prev actions must keep shortcuts after they've been shown.""" + def test_launcher_switcher_next_keeps_shortcuts(self): + """Launcher switcher next action must keep shortcuts after they've been shown.""" + self.addCleanup(self.launcher_instance.switcher_cancel) + self.launcher_instance.switcher_start() sleep(.5) - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.keyboard_reveal_launcher() - self.addCleanup(launcher_instance.keyboard_unreveal_launcher) - sleep(1) - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) + self.launcher_instance.switcher_next() sleep(.5) + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True)) - launcher_instance.switcher_next() + def test_launcher_switcher_prev_keeps_shortcuts(self): + """Launcher switcher prev action must keep shortcuts after they've been shown.""" + self.addCleanup(self.launcher_instance.switcher_cancel) + self.launcher_instance.switcher_start() sleep(.5) - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(True)) - launcher_instance.switcher_prev() + self.launcher_instance.switcher_prev() sleep(.5) - self.assertThat(launcher_instance.are_shortcuts_showing(), Equals(True)) + self.assertThat(self.launcher_instance.are_shortcuts_showing(), Equals(True)) - def test_launcher_switcher_using_shorcuts(self): - """Using some other shortcut while switcher is active must cancel switcher.""" - sleep(.5) - - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.keyboard_reveal_launcher() - self.addCleanup(launcher_instance.keyboard_unreveal_launcher) - sleep(1) - launcher_instance.switcher_start() - self.addCleanup(launcher_instance.switcher_cancel) - sleep(.5) - - self.keyboard.press_and_release("s") - sleep(.25) - self.keyboard.press_and_release("Escape") - sleep(.25) +class LauncherKeyNavTests(LauncherTestCase): + """Test the launcher key navigation""" + def setUp(self): + super(LauncherKeyNavTests, self).setUp() + self.launcher_instance.key_nav_start() - self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + def tearDown(self): + super(LauncherKeyNavTests, self).tearDown() + if self.launcher.key_nav_is_active: + self.launcher_instance.key_nav_cancel() - def test_launcher_keynav_initiate_works(self): + def test_launcher_keynav_initiate(self): """Tests we can initiate keyboard navigation on the launcher.""" - launcher_instance = self.get_launcher() - sleep(.5) - launcher_instance.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) - sleep(.5) - self.assertThat(self.launcher.key_nav_is_active, Equals(True)) self.assertThat(self.launcher.key_nav_is_grabbed, Equals(True)) - def test_launcher_keynav_end_works(self): + def test_launcher_keynav_cancel(self): """Test that we can exit keynav mode.""" - launcher_instance = self.get_launcher() - sleep(.5) - launcher_instance.key_nav_start() - sleep(.5) - launcher_instance.key_nav_cancel() + self.launcher_instance.key_nav_cancel() self.assertThat(self.launcher.key_nav_is_active, Equals(False)) self.assertThat(self.launcher.key_nav_is_grabbed, Equals(False)) - def test_launcher_keynav_starts_at_index_zero(self): - """Test keynav mode starts at index 0.""" - launcher_instance = self.get_launcher() + def test_launcher_keynav_cancel_resume_focus(self): + """Test that ending the launcher keynav resume the focus.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.launcher_instance.key_nav_start() sleep(.5) - launcher_instance.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) + self.assertFalse(calc.is_active) + + self.launcher_instance.key_nav_cancel() sleep(.5) + self.assertTrue(calc.is_active) + def test_launcher_keynav_starts_at_index_zero(self): + """Test keynav mode starts at index 0.""" self.assertThat(self.launcher.key_nav_selection, Equals(0)) - def test_launcher_keynav_forward_works(self): + def test_launcher_keynav_forward(self): """Must be able to move forwards while in keynav mode.""" - launcher_instance = self.get_launcher() - sleep(.5) - launcher_instance.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) - sleep(.5) - launcher_instance.key_nav_next() + self.launcher_instance.key_nav_next() sleep(.5) # The launcher model has hidden items, so the keynav indexes do not # increase by 1 each time. This test was failing because the 2nd icon @@ -339,28 +309,16 @@ 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.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) - sleep(.5) - launcher_instance.key_nav_next() - sleep(.5) - launcher_instance.key_nav_prev() + self.launcher_instance.key_nav_next() sleep(.5) + self.launcher_instance.key_nav_prev() self.assertThat(self.launcher.key_nav_selection, Equals(0)) def test_launcher_keynav_cycling_forward(self): """Launcher keynav must loop through icons when cycling forwards""" - launcher_instance = self.get_launcher() - sleep(.5) - 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.key_nav_next() + self.launcher_instance.key_nav_next() sleep(.25) # FIXME We can't directly check for selection/icon number equalty # since the launcher model also contains "hidden" icons that aren't @@ -369,67 +327,65 @@ prev_icon = self.launcher.key_nav_selection sleep(.5) - launcher_instance.key_nav_next() + self.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.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) - sleep(.25) - - launcher_instance.key_nav_prev() + self.launcher_instance.key_nav_prev() # FIXME We can't directly check for self.launcher.num_launcher_icons - 1 self.assertThat(self.launcher.key_nav_selection, GreaterThan(1)) - - def test_launcher_keynav_can_open_quicklist(self): - """Tests that we can open a quicklist from keynav mode.""" - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - sleep(.5) - launcher_instance.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) + + def test_launcher_keynav_can_open_and_close_quicklist(self): + """Tests that we can open and close a quicklist from keynav mode.""" + self.launcher_instance.key_nav_next() sleep(.5) - launcher_instance.key_nav_next() + self.launcher_instance.key_nav_enter_quicklist() + self.assertThat(self.launcher_instance.is_quicklist_open(), Equals(True)) sleep(.5) - 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)) - - def test_launcher_keynav_can_close_quicklist(self): - """Tests that we can close a quicklist from keynav mode.""" - launcher_instance = self.get_launcher() - launcher_instance.move_mouse_to_right_of_launcher() - sleep(.5) - launcher_instance.key_nav_start() - self.addCleanup(launcher_instance.key_nav_cancel) - sleep(.5) - launcher_instance.key_nav_next() - sleep(.5) - launcher_instance.key_nav_enter_quicklist() - sleep(.5) - launcher_instance.key_nav_exit_quicklist() - - self.assertThat(launcher_instance.is_quicklist_open(), Equals(False)) + self.launcher_instance.key_nav_exit_quicklist() + self.assertThat(self.launcher_instance.is_quicklist_open(), Equals(False)) self.assertThat(self.launcher.key_nav_is_active, Equals(True)) self.assertThat(self.launcher.key_nav_is_grabbed, Equals(True)) def test_launcher_keynav_mode_toggles(self): """Tests that keynav mode toggles with Alt+F1.""" - launcher_instance = self.get_launcher() + # was initiated in setup. + self.launcher_instance.key_nav_start() + sleep(0.25) + self.assertThat(self.launcher.key_nav_is_active, Equals(False)) - launcher_instance.key_nav_start() - launcher_instance.key_nav_start() + def test_launcher_keynav_activate_keep_focus(self): + """Activating a running launcher icon should focus it""" + calc = self.start_app("Calculator") + sleep(.5) + + self.close_all_app("Mahjongg") + mahjongg = self.start_app("Mahjongg") + self.assertTrue(mahjongg.is_active) + self.assertFalse(calc.is_active) + + self.launcher_instance.key_nav_start() + + found = False + for icon in self.launcher.model.get_launcher_icons_for_monitor(self.launcher_monitor): + if (icon.tooltip_text == calc.name): + found = True + self.launcher_instance.key_nav_activate() + break + else: + self.launcher_instance.key_nav_next() - self.assertThat(self.launcher.key_nav_is_active, Equals(False)) + sleep(.5) + if not found: + self.addCleanup(self.launcher_instance.key_nav_cancel) + + self.assertTrue(found) + self.assertTrue(calc.is_active) + self.assertFalse(mahjongg.is_active) 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) @@ -439,8 +395,6 @@ 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) @@ -449,11 +403,12 @@ self.assertThat(self.launcher.key_nav_is_active, Equals(False)) -class LauncherRevealTests(ScenariodLauncherTests): +class LauncherRevealTests(LauncherTestCase): """Test the launcher reveal bahavior when in autohide mode.""" def setUp(self): super(LauncherRevealTests, self).setUp() + # these automatically reset to the original value, as implemented in AutopilotTestCase self.set_unity_option('launcher_capture_mouse', True) self.set_unity_option('launcher_hide_mode', 1) launcher = self.get_launcher() @@ -464,48 +419,207 @@ self.assertThat(launcher.hidemode, Equals(1), "Launcher did not enter auto-hide mode.") + def test_launcher_keyboard_reveal_works(self): + """Revealing launcher with keyboard must work.""" + self.addCleanup(self.launcher_instance.keyboard_unreveal_launcher) + + self.launcher_instance.keyboard_reveal_launcher() + sleep(0.5) + self.assertThat(self.launcher_instance.is_showing(), Equals(True)) + 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.mouse_reveal_launcher() - self.assertThat(launcher_instance.is_showing(), Equals(True)) + self.launcher_instance.move_mouse_to_right_of_launcher() + self.launcher_instance.mouse_reveal_launcher() + self.assertThat(self.launcher_instance.is_showing(), Equals(True)) def test_reveal_with_mouse_under_launcher(self): """Tests that the launcher hides properly if the mouse is under the launcher when it is revealed. - """ - launcher_instance = self.get_launcher() - - launcher_instance.move_mouse_over_launcher() + self.launcher_instance.move_mouse_over_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)) + self.assertThat(self.launcher_instance.is_showing(), Equals(False)) def test_reveal_does_not_hide_again(self): """Tests reveal of launchers by mouse pressure to ensure it doesn't automatically hide again. - """ - launcher_instance = self.get_launcher() - - launcher_instance.move_mouse_to_right_of_launcher() - launcher_instance.mouse_reveal_launcher() + self.launcher_instance.move_mouse_to_right_of_launcher() + self.launcher_instance.mouse_reveal_launcher() sleep(2) - self.assertThat(launcher_instance.is_showing(), Equals(True)) + self.assertThat(self.launcher_instance.is_showing(), Equals(True)) def test_launcher_does_not_reveal_with_mouse_down(self): """Launcher must not reveal if have mouse button 1 down.""" + self.screen_geo.move_mouse_to_monitor(self.launcher_instance.monitor) + self.mouse.press(1) + self.addCleanup(self.mouse.release, 1) + #FIXME: This is really bad API. it says reveal but it's expected to fail. bad bad bad!! + self.launcher_instance.mouse_reveal_launcher() + self.assertThat(self.launcher_instance.is_showing(), Equals(False)) + +class LauncherVisualTests(LauncherTestCase): + """Tests for visual aspects of the launcher (icon saturation etc.).""" + + def test_keynav_from_dash_saturates_icons(self): + """Starting super+tab switcher from the dash must resaturate launcher icons. + + Tests fix for bug #913569. + """ + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + self.dash.ensure_visible() + sleep(1) + # We can't use 'launcher_instance.switcher_start()' since it moves the mouse. + self.keybinding_hold_part_then_tap("launcher/switcher") + self.addCleanup(self.keybinding_release, "launcher/switcher") + self.addCleanup(self.keybinding, "launcher/switcher/exit") + + self.keybinding_tap("launcher/switcher/next") + for icon in self.launcher.model.get_launcher_icons(): + self.assertFalse(icon.desaturated) + + def test_opening_dash_desaturates_icons(self): + """Opening the dash must desaturate all the launcher icons.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + for icon in self.launcher.model.get_launcher_icons(): + if isinstance(icon, BFBLauncherIcon): + self.assertFalse(icon.desaturated) + else: + self.assertTrue(icon.desaturated) + + def test_opening_dash_with_mouse_over_launcher_keeps_icon_saturation(self): + """Opening dash with mouse over launcher must not desaturate icons.""" launcher_instance = self.get_launcher() - screens = ScreenGeometry() + x,y,w,h = launcher_instance.geometry + self.mouse.move(x + w/2, y + h/2) + sleep(.5) + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + for icon in self.launcher.model.get_launcher_icons(): + self.assertFalse(icon.desaturated) - screens.move_mouse_to_monitor(launcher_instance.monitor) - self.mouse.press(1) - launcher_instance.mouse_reveal_launcher() - self.assertThat(launcher_instance.is_showing(), Equals(False)) - self.mouse.release(1) + def test_mouse_over_with_dash_open_desaturates_icons(self): + """Moving mouse over launcher with dash open must saturate icons.""" + launcher_instance = self.get_launcher() + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(.5) + x,y,w,h = launcher_instance.geometry + self.mouse.move(x + w/2, y + h/2) + sleep(.5) + for icon in self.launcher.model.get_launcher_icons(): + self.assertFalse(icon.desaturated) + +class LauncherCaptureTests(AutopilotTestCase): + """Test the launchers ability to capture/not capture the mouse.""" + + screen_geo = ScreenGeometry() + + def setHideMode(self, mode): + launcher = self.launcher.get_launcher_for_monitor(0) + for counter in range(10): + sleep(1) + if launcher.hidemode == mode: + break + self.assertThat(launcher.hidemode, Equals(mode), + "Launcher did not enter revealed mode.") + + def leftMostMonitor(self): + x1, y1, width, height = self.screen_geo.get_monitor_geometry(0) + x2, y2, width, height = self.screen_geo.get_monitor_geometry(1) + + if x1 < x2: + return 0 + return 1 + + def rightMostMonitor(self): + return 1 - self.leftMostMonitor() + + def setUp(self): + super(LauncherCaptureTests, self).setUp() + self.set_unity_option('launcher_capture_mouse', True) + self.set_unity_option('launcher_hide_mode', 0) + self.set_unity_option('num_launchers', 0) + self.setHideMode(0) + + def test_launcher_captures_while_sticky_and_revealed(self): + """Tests that the launcher captures the mouse when moving between monitors + while revealed. + """ + if self.screen_geo.get_num_monitors() <= 1: + self.skipTest("Cannot run this test with a single monitor configured.") + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, GreaterThan(x - width / 2)) + + def test_launcher_not_capture_while_not_sticky_and_revealed(self): + """Tests that the launcher doesn't captures the mouse when moving between monitors + while revealed and stick is off. + """ + if self.screen_geo.get_num_monitors() <= 1: + self.skipTest("Cannot run this test with a single monitor configured.") + + self.set_unity_option('launcher_capture_mouse', False) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, Equals(x - width / 2)) + + def test_launcher_not_capture_while_not_sticky_and_hidden_moving_right(self): + """Tests that the launcher doesn't capture the mouse when moving between monitors + while hidden and sticky is off. + """ + if self.screen_geo.get_num_monitors() <= 1: + self.skipTest("Cannot run this test with a single monitor configured.") + + self.set_unity_option('launcher_hide_mode', 1) + self.set_unity_option('launcher_capture_mouse', False) + + self.setHideMode(1) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + sleep(1.5) + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, Equals(x + width * 1.5)) + + def test_launcher_capture_while_sticky_and_hidden_moving_right(self): + """Tests that the launcher captures the mouse when moving between monitors + while hidden. + """ + if self.screen_geo.get_num_monitors() <= 1: + self.skipTest("Cannot run this test with a single monitor configured.") + + self.set_unity_option('launcher_hide_mode', 1) + + self.setHideMode(1) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + sleep(1.5) + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, LessThan(x + width * 1.5)) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_panel.py unity-5.10.0/tests/autopilot/autopilot/tests/test_panel.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_panel.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_panel.py 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,1203 @@ +# -*- 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 +import os +from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan +from time import sleep + +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.emulators.bamf import BamfWindow +from autopilot.emulators.unity.panel import IndicatorEntry +from autopilot.tests import AutopilotTestCase + +logger = logging.getLogger(__name__) + +def _make_monitor_scenarios(): + num_monitors = ScreenGeometry().get_num_monitors() + scenarios = [] + + if num_monitors == 1: + scenarios = [('Single Monitor', {'panel_monitor': 0})] + else: + for i in range(num_monitors): + scenarios += [('Monitor %d' % (i), {'panel_monitor': i})] + + return scenarios + + +class PanelTestsBase(AutopilotTestCase): + + panel_monitor = 0 + + def setUp(self): + super(PanelTestsBase, self).setUp() + self.panel = self.panels.get_panel_for_monitor(self.panel_monitor) + self.panel.move_mouse_below_the_panel() + self.addCleanup(self.panel.move_mouse_below_the_panel) + + def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True): + """Opens a new instance of the requested application, ensuring + that only one window is opened. + + Returns the opened BamfWindow + + """ + self.close_all_app(app_name) + app = self.start_app(app_name, locale="C") + + wins = app.get_windows() + self.assertThat(len(wins), Equals(1)) + app_win = wins[0] + + app_win.set_focus() + self.assertTrue(app.is_active) + self.assertTrue(app_win.is_focused) + self.assertThat(app.desktop_file, Equals(app_win.application.desktop_file)) + + if move_to_monitor: + self.move_window_to_panel_monitor(app_win) + + if maximized and not app_win.is_maximized: + self.keybinding("window/maximize") + self.addCleanup(self.keybinding, "window/restore") + elif not maximized and app_win.is_maximized: + self.keybinding("window/restore") + self.addCleanup(self.keybinding, "window/maximize") + + app_win.set_focus() + sleep(.25) + + self.assertThat(app_win.is_maximized, Equals(maximized)) + + return app_win + + def move_window_to_panel_monitor(self, window, restore_position=True): + """Drags a window to another monitor, eventually restoring it before""" + if not isinstance(window, BamfWindow): + raise TypeError("Window must be a BamfWindow") + + if window.monitor == self.panel_monitor: + return + + if window.is_maximized: + self.keybinding("window/restore") + self.addCleanup(self.keybinding, "window/maximize") + sleep(.1) + + if restore_position: + self.addCleanup(self.screen_geo.drag_window_to_monitor, window, window.monitor) + + self.screen_geo.drag_window_to_monitor(window, self.panel_monitor) + sleep(.25) + self.assertThat(window.monitor, Equals(self.panel_monitor)) + + def mouse_open_indicator(self, indicator): + """This is an utility function that safely opens an indicator, + ensuring that it is closed at the end of the test and that the pointer + is moved outside the panel area (to make the panel hide the menus) + """ + if not isinstance(indicator, IndicatorEntry): + raise TypeError("Window must be a IndicatorEntry") + + indicator.mouse_click() + self.addCleanup(self.panel.move_mouse_below_the_panel) + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(.5) + self.assertTrue(indicator.active) + + +class PanelTitleTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def test_panel_title_on_empty_desktop(self): + """Test that the title is set ot default when there are no windows shown""" + self.keybinding("window/show_desktop") + # We need this sleep to give the time to showdesktop to properly resume + # the initial status without getting a false-negative result + self.addCleanup(sleep, 2) + self.addCleanup(self.keybinding, "window/show_desktop") + sleep(2) + + self.assertTrue(self.panel.desktop_is_active) + + def test_panel_title_with_restored_application(self): + """Tests the title shown in the panel with a restored application""" + calc_win = self.open_new_application_window("Calculator") + + self.assertFalse(calc_win.is_maximized) + self.assertThat(self.panel.title, Equals(calc_win.application.name)) + + def test_panel_title_with_maximized_application(self): + """Tests the title shown in the panel with a maximized application""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertTrue(text_win.is_maximized) + self.assertThat(self.panel.title, Equals(text_win.title)) + + def test_panel_title_with_maximized_window_restored_child(self): + """Tests the title shown in the panel when opening the restored child of + a maximized application + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertTrue(text_win.is_maximized) + self.assertThat(self.panel.title, Equals(text_win.title)) + + self.keyboard.press_and_release("Ctrl+h") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(.25) + self.assertThat(self.panel.title, Equals(text_win.application.name)) + + def test_panel_title_switching_active_window(self): + """Tests the title shown in the panel with a maximized application""" + # Locked Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', 0) + + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertTrue(text_win.is_maximized) + self.assertThat(self.panel.title, Equals(text_win.title)) + sleep(.25) + + calc_win = self.open_new_application_window("Calculator") + self.assertThat(self.panel.title, Equals(calc_win.application.name)) + + icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file) + launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor) + launcher.click_launcher_icon(icon) + + self.assertTrue(text_win.is_focused) + self.assertThat(self.panel.title, Equals(text_win.title)) + + def test_panel_title_updates_on_maximized_window_title_changes(self): + """Tests that the title of a maximized application updates with + window title changes""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertThat(self.panel.title, Equals(text_win.title)) + old_title = text_win.title + sleep(.25) + + text_win.set_focus() + self.keyboard.type("Unity rocks!") + self.addCleanup(os.remove, "/tmp/autopilot-awesome-test.txt") + self.keyboard.press_and_release("Ctrl+S") + sleep(.25) + self.keyboard.type("/tmp/autopilot-awesome-test.txt") + self.keyboard.press_and_release("Return") + sleep(1) + + self.assertThat(old_title, NotEquals(text_win.title)) + self.assertThat(self.panel.title, Equals(text_win.title)) + + +class PanelWindowButtonsTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def setUp(self): + super(PanelWindowButtonsTests, self).setUp() + # Locked Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', 0) + + def test_window_buttons_dont_show_on_empty_desktop(self): + """Tests that the window buttons are not shown on clean desktop""" + # We need this sleep to give the time to showdesktop to properly resume + # the initial status without getting a false-negative result + self.addCleanup(sleep, 2) + self.addCleanup(self.keybinding, "window/show_desktop") + + self.assertFalse(self.panel.window_buttons_shown) + self.panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + + def test_window_buttons_dont_show_for_restored_window(self): + """Tests that the window buttons are not shown for a restored window""" + calc_win = self.open_new_application_window("Calculator") + + self.assertFalse(self.panel.window_buttons_shown) + + self.panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + + def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self): + """Tests that the windows button arenot shown for a maximized window + when the mouse is outside the panel + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.discovery_fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_fadeout_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + + def test_window_buttons_show_for_maximized_window_on_mouse_in(self): + """Tests that the window buttons are shown when a maximized window + is focused and the mouse is over the menu-view panel areas + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + sleep(self.panel.menus.discovery_duration) + + self.panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.window_buttons_shown) + + buttons = self.panel.window_buttons.get_buttons() + self.assertThat(len(buttons), Equals(3)) + for button in buttons: + self.assertFalse(button.overlay_mode) + + def test_window_buttons_show_with_dash(self): + """Tests that the window buttons are shown when opening the dash""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(.5) + self.assertTrue(self.panel.window_buttons_shown) + + buttons = self.panel.window_buttons.get_buttons() + self.assertThat(len(buttons), Equals(3)) + for button in buttons: + self.assertTrue(button.overlay_mode) + + def test_window_buttons_show_with_hud(self): + """Tests that the window buttons are shown when opening the HUD""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(1) + self.assertTrue(self.panel.window_buttons_shown) + + buttons = self.panel.window_buttons.get_buttons() + self.assertThat(len(buttons), Equals(3)) + for button in buttons: + self.assertTrue(button.overlay_mode) + + def test_window_buttons_update_visual_state(self): + """Tests that the window button updates its visual state""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + button = self.panel.window_buttons.close + + self.assertThat(button.visual_state, Equals("normal")) + + button.mouse_move_to() + self.assertTrue(button.visible) + self.assertTrue(button.enabled) + sleep(.25) + self.assertThat(button.visual_state, Equals("prelight")) + + self.mouse.press() + self.addCleanup(self.mouse.release) + sleep(.25) + self.assertThat(button.visual_state, Equals("pressed")) + + def test_window_buttons_cancel(self): + """Tests how the buttons ignore clicks when the mouse is pressed over + them and released outside their area + """ + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + button = self.panel.window_buttons.close + + button.mouse_move_to() + self.mouse.press() + self.addCleanup(self.mouse.release) + sleep(.25) + self.panel.move_mouse_below_the_panel() + sleep(.25) + self.assertTrue(self.hud.visible) + + def test_window_buttons_close_button_works_for_window(self): + """Tests that the window button 'Close' actually closes a window""" + text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False) + self.move_window_to_panel_monitor(text_win, restore_position=False) + self.keybinding("window/maximize") + + self.panel.move_mouse_over_window_buttons() + self.panel.window_buttons.close.mouse_click() + sleep(1) + + self.assertTrue(text_win.closed) + + def test_window_buttons_close_follows_fitts_law(self): + """Tests that the 'Close' button is conform to Fitts's Law. See bug #839690""" + text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False) + self.move_window_to_panel_monitor(text_win, restore_position=False) + self.keybinding("window/maximize") + + self.panel.move_mouse_over_window_buttons() + screen = self.screen_geo.get_monitor_geometry(self.panel_monitor) + self.mouse.move(screen[0], screen[1], rate=20, time_between_events=0.005) + sleep(.5) + self.mouse.click(press_duration=.1) + sleep(1) + + self.assertTrue(text_win.closed) + + def test_window_buttons_minimize_button_works_for_window(self): + """Tests that the window button 'Minimize' actually minimizes a window""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.panel.window_buttons.minimize.mouse_click() + sleep(.5) + + self.assertTrue(text_win.is_hidden) + + icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file) + launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor) + launcher.click_launcher_icon(icon) + + def test_window_buttons_minimize_follows_fitts_law(self): + """Tests that the 'Minimize' button is conform to Fitts's Law. See bug #839690""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + button = self.panel.window_buttons.minimize + button.mouse_move_to() + target_x = button.x + button.width / 2 + target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1] + self.mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + sleep(.5) + self.mouse.click(press_duration=.1) + sleep(1) + + self.assertTrue(text_win.is_hidden) + icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file) + launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor) + launcher.click_launcher_icon(icon) + + def test_window_buttons_unmaximize_button_works_for_window(self): + """Tests that the window button 'Unmaximize' actually unmaximizes a window""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.panel.window_buttons.unmaximize.mouse_click() + sleep(.5) + + self.assertFalse(text_win.is_maximized) + self.assertTrue(text_win.is_focused) + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + + def test_window_buttons_unmaximize_follows_fitts_law(self): + """Tests that the 'Unmaximize' button is conform to Fitts's Law. See bug #839690""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + button = self.panel.window_buttons.unmaximize + button.mouse_move_to() + target_x = button.x + button.width / 2 + target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1] + self.mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + sleep(.5) + self.mouse.click(press_duration=.1) + sleep(1) + + self.assertFalse(text_win.is_maximized) + + def test_window_buttons_close_button_works_for_hud(self): + """Tests that the window 'Close' actually closes the HUD""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(.5) + + self.panel.window_buttons.close.mouse_click() + sleep(.75) + + self.assertFalse(self.hud.visible) + + def test_window_buttons_minimize_button_disabled_for_hud(self): + """Tests that the window 'Minimize' does nothing to the HUD""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(.5) + + button = self.panel.window_buttons.minimize + button.mouse_click() + sleep(.5) + + self.assertFalse(button.enabled) + self.assertTrue(self.hud.visible) + + def test_window_buttons_maximize_button_disabled_for_hud(self): + """Tests that the window 'Maximize' does nothing to the HUD""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(.5) + + button = self.panel.window_buttons.maximize + button.mouse_click() + sleep(.5) + + self.assertFalse(button.enabled) + self.assertTrue(self.hud.visible) + + def test_window_buttons_maximize_in_hud_does_not_change_dash_form_factor(self): + """Tests that clicking on the disabled 'Maximize' window button of the + HUD, really does nothing and don't touch the dash form factor. + See bug #939054 + """ + inital_form_factor = self.dash.view.form_factor + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(.5) + + self.panel.window_buttons.maximize.mouse_click() + sleep(.5) + + self.assertThat(self.dash.view.form_factor, Equals(inital_form_factor)) + + def test_window_buttons_close_button_works_for_dash(self): + """Tests that the window 'Close' actually closes the Dash""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(.5) + + self.panel.window_buttons.close.mouse_click() + sleep(.75) + + self.assertFalse(self.dash.visible) + + def test_window_buttons_minimize_button_disabled_for_dash(self): + """Tests that the 'Minimize' button is disabled for the dash""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(.5) + + button = self.panel.window_buttons.minimize + button.mouse_click() + sleep(.5) + + self.assertFalse(button.enabled) + self.assertTrue(self.dash.visible) + + def test_window_buttons_maximization_buttons_works_for_dash(self): + """Tests that the 'Maximize' and 'Unmaximize' buttons (when + both enabled) work as expected""" + self.dash.ensure_visible() + self.addCleanup(self.panel.window_buttons.close.mouse_click) + sleep(.5) + + unmaximize = self.panel.window_buttons.unmaximize + maximize = self.panel.window_buttons.maximize + netbook_dash = (self.dash.view.form_factor == "netbook") + + if netbook_dash and not unmaximize.enabled: + unmaximize.mouse_click() + sleep(.5) + self.assertThat(self.dash.view.form_factor, Equals("netbook")) + else: + if maximize.visible: + active_button = maximize + unactive_button = unmaximize + else: + active_button = unmaximize + unactive_button = maximize + + self.assertTrue(active_button.visible) + self.assertTrue(active_button.sensitive) + self.assertTrue(active_button.enabled) + self.assertFalse(unactive_button.visible) + + self.addCleanup(unactive_button.mouse_click) + active_button.mouse_click() + sleep(.5) + + self.assertTrue(unactive_button.visible) + self.assertTrue(unactive_button.sensitive) + self.assertTrue(unactive_button.enabled) + self.assertFalse(active_button.visible) + sleep(.5) + + if netbook_dash: + self.assertThat(self.dash.view.form_factor, Equals("desktop")) + else: + self.assertThat(self.dash.view.form_factor, Equals("netbook")) + + self.addCleanup(active_button.mouse_click) + unactive_button.mouse_click() + sleep(.5) + + self.assertTrue(active_button.visible) + self.assertFalse(unactive_button.visible) + + if netbook_dash: + self.assertThat(self.dash.view.form_factor, Equals("netbook")) + else: + self.assertThat(self.dash.view.form_factor, Equals("desktop")) + + def test_window_buttons_minimize_button_disabled_for_non_minimizable_windows(self): + """Tests that if a maximized window doesn't support the minimization, + then the 'Minimize' window button should be disabled. + """ + text_win = self.open_new_application_window("Text Editor") + sleep(.25) + self.keyboard.press_and_release("Ctrl+S") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + wins = text_win.application.get_windows() + self.assertThat(len(wins), Equals(2)) + for win in wins: + if win.x_id != text_win.x_id: + target_win = win + break + + target_win.set_focus() + self.assertTrue(target_win.is_focused) + self.move_window_to_panel_monitor(target_win, restore_position=False) + + self.keybinding("window/maximize") + + self.assertThat(target_win.monitor, Equals(self.panel_monitor)) + self.assertTrue(target_win.is_maximized) + + self.assertTrue(self.panel.window_buttons.close.enabled) + self.assertFalse(self.panel.window_buttons.minimize.enabled) + + def test_window_buttons_show_when_indicator_active_and_mouse_over_panel(self): + """Tests that when an indicator is opened, and the mouse goes over the + panel view, then the window buttons are revealed + """ + self.open_new_application_window("Text Editor", maximized=True) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices") + self.mouse_open_indicator(indicator) + + self.assertFalse(self.panel.window_buttons_shown) + self.panel.move_mouse_below_the_panel() + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.window_buttons_shown) + self.panel.move_mouse_over_grab_area() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.window_buttons_shown) + + def test_window_buttons_show_when_holding_show_menu_key(self): + self.open_new_application_window("Text Editor", maximized=True) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.keybinding_hold("panel/show_menus") + self.addCleanup(self.keybinding_release, "panel/show_menus") + sleep(1) + self.assertTrue(self.panel.window_buttons_shown) + + self.keybinding_release("panel/show_menus") + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.window_buttons_shown) + + +class PanelHoveringTests(PanelTestsBase): + """Tests with the mouse pointer hovering the panel area""" + + scenarios = _make_monitor_scenarios() + + def test_only_menus_show_for_restored_window_on_mouse_in(self): + """Tests that only menus of a restored window are shown only when + the mouse pointer is over the panel menu area. + """ + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + self.panel.move_mouse_over_menus() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + if self.panel.grab_area.width > 0: + self.panel.move_mouse_over_grab_area() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + self.panel.move_mouse_over_indicators() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertFalse(self.panel.menus_shown) + + def test_menus_show_for_maximized_window_on_mouse_in(self): + """Tests that menus and window buttons of a maximized window are shown + only when the mouse pointer is over the panel menu area. + """ + self.open_new_application_window("Text Editor", maximized=True) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertTrue(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + self.panel.move_mouse_over_menus() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + if self.panel.grab_area.width > 0: + self.panel.move_mouse_over_grab_area() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertTrue(self.panel.window_buttons_shown) + self.assertTrue(self.panel.menus_shown) + + self.panel.move_mouse_over_indicators() + sleep(self.panel.menus.fadeout_duration / 1000.0) + self.assertFalse(self.panel.window_buttons_shown) + self.assertFalse(self.panel.menus_shown) + + def test_hovering_indicators_open_menus(self): + """This test checks that opening an indicator entry, and then + hovering on all the others, opens them""" + self.open_new_application_window("Text Editor") + entries = self.panel.get_indicator_entries(include_hidden_menus=True) + + self.assertThat(len(entries), GreaterThan(0)) + self.mouse_open_indicator(entries[0]) + + for entry in entries: + entry.mouse_move_to() + sleep(.25) + self.assertTrue(entry.active) + self.assertThat(entry.menu_y, NotEquals(0)) + +class PanelMenuTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def test_menus_are_added_on_new_application(self): + """Tests that menus are added when a new application is opened""" + self.open_new_application_window("Calculator") + sleep(.5) + menu_entries = self.panel.menus.get_entries() + self.assertThat(len(menu_entries), Equals(3)) + + menu_view = self.panel.menus + self.assertThat(menu_view.get_menu_by_label("_Calculator"), NotEquals(None)) + self.assertThat(menu_view.get_menu_by_label("_Mode"), NotEquals(None)) + self.assertThat(menu_view.get_menu_by_label("_Help"), NotEquals(None)) + + def test_menus_are_not_shown_if_the_application_has_no_menus(self): + """Tests that if an application has no menus, then they are not + shown or added + """ + old_env = os.environ["UBUNTU_MENUPROXY"] + os.putenv("UBUNTU_MENUPROXY", "") + self.addCleanup(os.putenv, "UBUNTU_MENUPROXY", old_env) + calc_win = self.open_new_application_window("Calculator") + sleep(1) + + self.assertThat(len(self.panel.menus.get_entries()), Equals(0)) + + self.panel.move_mouse_over_grab_area() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertThat(self.panel.title, Equals(calc_win.application.name)) + + def test_menus_shows_when_new_application_is_opened(self): + """This tests the menu discovery feature on new application""" + + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + + self.assertTrue(self.panel.menus_shown) + + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + + def test_menus_dont_show_if_a_new_application_window_is_opened(self): + """This tests the menu discovery feature on new window for a know application""" + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + + self.assertTrue(self.panel.menus_shown) + + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.start_app("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertFalse(self.panel.menus_shown) + + def test_menus_dont_show_for_restored_window_on_mouse_out(self): + """Tests that menus of a restored window are not shown when + the mouse pointer is outside the panel menu area. + """ + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + + def test_menus_show_for_restored_window_on_mouse_in(self): + """Tests that menus of a restored window are shown only when + the mouse pointer is over the panel menu area. + """ + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.panel.move_mouse_over_menus() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.menus_shown) + + def test_menus_dont_show_for_maximized_window_on_mouse_out(self): + """Tests that menus of a maximized window are not shown when + the mouse pointer is outside the panel menu area. + """ + self.open_new_application_window("Text Editor", maximized=True) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + + def test_menus_show_for_maximized_window_on_mouse_in(self): + """Tests that menus of a maximized window are shown only when + the mouse pointer is over the panel menu area. + """ + self.open_new_application_window("Text Editor", maximized=True) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.panel.move_mouse_over_menus() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.menus_shown) + + def test_menus_dont_show_with_dash(self): + """Tests that menus are not showing when opening the dash""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(1) + + self.assertFalse(self.panel.menus_shown) + + def test_menus_dont_show_with_hud(self): + """Tests that menus are not showing when opening the HUD""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + sleep(1) + + self.assertFalse(self.panel.menus_shown) + + def test_menus_show_after_closing_an_entry(self): + """This test checks that opening a menu entry, and then + hovering on all the others, opens them, plus we check that + the menus are still drawn when closed""" + self.open_new_application_window("Calculator") + entries = self.panel.menus.get_entries() + + self.assertThat(len(entries), GreaterThan(0)) + self.mouse_open_indicator(entries[0]) + + for entry in entries: + entry.mouse_move_to() + sleep(.25) + self.assertTrue(entry.active) + self.assertThat(entry.menu_y, NotEquals(0)) + last_entry = entry + + last_entry.mouse_click() + sleep(.25) + self.assertFalse(last_entry.active) + self.assertThat(last_entry.menu_y, Equals(0)) + + def test_menus_show_when_indicator_active_and_mouse_over_panel(self): + """Tests that when an indicator is opened, and the mouse goes over the + panel view, then the menus are revealed + """ + self.open_new_application_window("Calculator") + indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices") + self.mouse_open_indicator(indicator) + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + self.panel.move_mouse_below_the_panel() + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + self.panel.move_mouse_over_grab_area() + sleep(self.panel.menus.fadein_duration / 1000.0) + self.assertTrue(self.panel.menus_shown) + + def test_menus_show_when_holding_show_menu_key(self): + self.open_new_application_window("Calculator") + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.keybinding_hold("panel/show_menus") + self.addCleanup(self.keybinding_release, "panel/show_menus") + sleep(1) + self.assertTrue(self.panel.menus_shown) + + self.keybinding_release("panel/show_menus") + sleep(self.panel.menus.fadeout_duration / 1000.0) + + self.assertFalse(self.panel.menus_shown) + + +class PanelIndicatorEntriesTests(PanelTestsBase): + """Tests for the indicator entries, including both menu and indicators""" + + scenarios = _make_monitor_scenarios() + + def test_menu_opens_on_click(self): + """Tests that clicking on a menu entry, opens a menu""" + self.open_new_application_window("Calculator") + sleep(.5) + + menu_entry = self.panel.menus.get_entries()[0] + self.mouse_open_indicator(menu_entry) + + self.assertTrue(menu_entry.active) + self.assertThat(menu_entry.menu_x, Equals(menu_entry.x)) + self.assertThat(menu_entry.menu_y, Equals(self.panel.height)) + + def test_menu_opens_closes_on_click(self): + """Tests that clicking on a menu entry, opens a menu, reclicking + on it closes it + """ + self.open_new_application_window("Calculator") + + menu_entry = self.panel.menus.get_entries()[0] + self.mouse_open_indicator(menu_entry) + + self.mouse.click() + sleep(.25) + self.assertFalse(menu_entry.active) + self.assertThat(menu_entry.menu_x, Equals(0)) + self.assertThat(menu_entry.menu_y, Equals(0)) + + def test_menu_closes_on_click_outside(self): + """Tests that clicking outside the menu area, closes a menu""" + self.open_new_application_window("Calculator") + + menu_entry = self.panel.menus.get_entries()[0] + self.mouse_open_indicator(menu_entry) + + self.assertTrue(menu_entry.active) + target_x = menu_entry.menu_x + menu_entry.menu_width/2 + target_y = menu_entry.menu_y + menu_entry.menu_height + 10 + self.mouse.move(target_x, target_y) + self.mouse.click() + sleep(.5) + + self.assertFalse(menu_entry.active) + self.assertThat(menu_entry.menu_x, Equals(0)) + self.assertThat(menu_entry.menu_y, Equals(0)) + + +class PanelKeyNavigationTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def test_panel_first_menu_show_works(self): + """Tests that pressing the open-menus keybinding, the first indicator + is actually opened + """ + self.open_new_application_window("Calculator") + sleep(1) + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(1) + + open_indicator = self.panel.get_active_indicator() + expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0] + self.assertThat(open_indicator, NotEquals(None)) + self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id)) + + self.keybinding("panel/open_first_menu") + sleep(.5) + self.assertThat(self.panel.get_active_indicator(), Equals(None)) + + def test_panel_menu_accelerators_work(self): + self.open_new_application_window("Calculator") + sleep(1) + self.keyboard.press_and_release("Alt+c") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(.5) + + open_indicator = self.panel.get_active_indicator() + self.assertThat(open_indicator, NotEquals(None)) + self.assertThat(open_indicator.label, Equals("_Calculator")) + + def test_panel_indicators_key_navigation_next_works(self): + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + sleep(1) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(1) + + open_indicator = self.panel.get_active_indicator() + expected_indicator = available_indicators[0] + self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id)) + sleep(.5) + + self.keybinding("panel/next_indicator") + open_indicator = self.panel.get_active_indicator() + expected_indicator = available_indicators[1] + sleep(.5) + self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id)) + + def test_panel_indicators_key_navigation_prev_works(self): + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + sleep(1) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(1) + + open_indicator = self.panel.get_active_indicator() + expected_indicator = available_indicators[0] + self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id)) + sleep(.5) + + self.keybinding("panel/prev_indicator") + open_indicator = self.panel.get_active_indicator() + expected_indicator = available_indicators[-1] + sleep(.5) + self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id)) + + def test_mouse_does_not_break_key_navigation(self): + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + sleep(1) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(1) + + available_indicators[2].mouse_move_to() + self.addCleanup(self.panel.move_mouse_below_the_panel) + sleep(.25) + self.assertTrue(available_indicators[2].active) + sleep(1) + + self.keybinding("panel/prev_indicator") + self.assertTrue(available_indicators[1].active) + + +class PanelGrabAreaTests(PanelTestsBase): + """Panel grab area tests""" + + scenarios = _make_monitor_scenarios() + + def move_mouse_over_grab_area(self): + self.panel.move_mouse_over_grab_area() + self.addCleanup(self.panel.move_mouse_below_the_panel) + sleep(.1) + + def test_unmaximize_from_grab_area_works(self): + """Tests that dragging a window down from the panel, unmaximize it""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.move_mouse_over_grab_area() + self.mouse.press() + self.panel.move_mouse_below_the_panel() + self.mouse.release() + sleep(.5) + + self.assertFalse(text_win.is_maximized) + + def test_focus_the_maximized_window_works(self): + """Tests that clicking on the grab area, put the maximized window to focus""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + sleep(.5) + self.open_new_application_window("Calculator") + self.assertFalse(text_win.is_focused) + + self.move_mouse_over_grab_area() + self.mouse.click() + sleep(.5) + + self.assertTrue(text_win.is_focused) + + def test_lower_the_maximized_window_works(self): + """Tests that middle-clicking on the panel grab area, lower the maximized window""" + calc_win = self.open_new_application_window("Calculator") + sleep(.5) + self.open_new_application_window("Text Editor", maximized=True) + self.assertFalse(calc_win.is_focused) + + self.move_mouse_over_grab_area() + self.mouse.click(2) + sleep(.5) + + self.assertTrue(calc_win.is_focused) + + +class PanelCrossMonitorsTests(PanelTestsBase): + """Multimonitor only tests""" + + def setUp(self): + super(PanelCrossMonitorsTests, self).setUp() + if self.screen_geo.get_num_monitors() < 2: + self.skipTest("This test requires a multimonitor setup") + + def test_panel_title_updates_moving_window(self): + """Tests the title shown in the panel, moving a restored window around them""" + calc_win = self.open_new_application_window("Calculator") + + prev_monitor = -1 + for monitor in range(0, self.screen_geo.get_num_monitors()): + if calc_win.monitor != monitor: + self.addCleanup(self.screen_geo.drag_window_to_monitor, calc_win, calc_win.monitor) + self.screen_geo.drag_window_to_monitor(calc_win, monitor) + sleep(.25) + + if prev_monitor >= 0: + self.assertFalse(self.panels.get_panel_for_monitor(prev_monitor).active) + + panel = self.panels.get_panel_for_monitor(monitor) + self.assertTrue(panel.active) + self.assertThat(panel.title, Equals(calc_win.application.name)) + + prev_monitor = monitor + + def test_window_buttons_dont_show_for_maximized_window_on_mouse_in(self): + """Test that window buttons are not showing when the mouse is hovering + the panel in other monitors + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + sleep(self.panel.menus.discovery_duration) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + panel.move_mouse_over_window_buttons() + sleep(self.panel.menus.fadein_duration / 1000.0) + + if self.panel_monitor == monitor: + self.assertTrue(panel.window_buttons_shown) + else: + self.assertFalse(panel.window_buttons_shown) + + def test_window_buttons_dont_show_in_other_monitors_when_dash_is_open(self): + """Test that window buttons are not showing in the panels other than + the one where the dash is opened + """ + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if self.dash.monitor == monitor: + self.assertTrue(panel.window_buttons_shown) + else: + self.assertFalse(panel.window_buttons_shown) + + def test_window_buttons_dont_show_in_other_monitors_when_hud_is_open(self): + """Test that window buttons are not showing in the panels other than + the one where the dash is opened + """ + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if self.hud.monitor == monitor: + self.assertTrue(panel.window_buttons_shown) + else: + self.assertFalse(panel.window_buttons_shown) + + def test_window_buttons_close_inactive_when_clicked_in_another_monitor(self): + """Tests that clicking on the panel area where the window buttons + are does not affect the active maximized window in another monitor. + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.close.mouse_click() + sleep(.25) + self.assertFalse(text_win.closed) + + def test_window_buttons_minimize_inactive_when_clicked_in_another_monitor(self): + """Tests that clicking on the panel area where the window buttons + are does not affect the active maximized window in another monitor. + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.minimize.mouse_click() + sleep(.25) + self.assertFalse(text_win.is_hidden) + + def test_window_buttons_unmaximize_inactive_when_clicked_in_another_monitor(self): + """Tests that clicking on the panel area where the window buttons + are does not affect the active maximized window in another monitor. + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.unmaximize.mouse_click() + sleep(.25) + self.assertTrue(text_win.is_maximized) + + def test_hovering_indicators_on_multiple_monitors(self): + """This test checks that opening an indicator entry, and then + hovering on all the others, opens them""" + text_win = self.open_new_application_window("Text Editor") + panel = self.panels.get_panel_for_monitor(text_win.monitor) + indicator = panel.indicators.get_indicator_by_name_hint("indicator-session-devices") + self.mouse_open_indicator(indicator) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + entries = panel.get_indicator_entries(include_hidden_menus=True) + self.assertThat(len(entries), GreaterThan(0)) + + for entry in entries: + entry.mouse_move_to() + sleep(.5) + + if monitor != self.panel_monitor and entry.type == "menu": + self.assertFalse(entry.active) + self.assertFalse(entry.visible) + self.assertThat(entry.menu_y, Equals(0)) + else: + self.assertTrue(entry.visible) + self.assertTrue(entry.active) + self.assertThat(entry.menu_y, NotEquals(0)) diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_quicklist.py unity-5.10.0/tests/autopilot/autopilot/tests/test_quicklist.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_quicklist.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_quicklist.py 2012-04-12 13:21:21.000000000 +0000 @@ -13,6 +13,7 @@ from autopilot.emulators.unity.quicklist import QuicklistMenuItemLabel from autopilot.tests import AutopilotTestCase + class QuicklistActionTests(AutopilotTestCase): """Tests for quicklist actions.""" diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py unity-5.10.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_shortcut_hint.py 2012-04-12 13:21:21.000000000 +0000 @@ -11,7 +11,6 @@ from autopilot.tests import AutopilotTestCase from autopilot.emulators.unity.shortcut_hint import ShortcutController -from autopilot.emulators.X11 import ScreenGeometry class BaseShortcutHintTests(AutopilotTestCase): @@ -29,9 +28,8 @@ sleep(1) def skip_if_monitor_too_small(self): - screen = ScreenGeometry(); - monitor = screen.get_primary_monitor() - monitor_geo = screen.get_monitor_geometry(monitor); + monitor = self.screen_geo.get_primary_monitor() + monitor_geo = self.screen_geo.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]; @@ -49,8 +47,7 @@ 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() + monitor = self.screen_geo.get_primary_monitor() return self.launcher.get_launcher_for_monitor(monitor) @@ -106,17 +103,6 @@ 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.""" diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_showdesktop.py unity-5.10.0/tests/autopilot/autopilot/tests/test_showdesktop.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_showdesktop.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_showdesktop.py 2012-04-12 13:21:21.000000000 +0000 @@ -9,6 +9,7 @@ from time import sleep from autopilot.emulators.unity.switcher import Switcher +from autopilot.emulators.unity.icons import DesktopLauncherIcon from autopilot.tests import AutopilotTestCase @@ -23,8 +24,8 @@ def launch_test_apps(self): """Launch character map and calculator apps.""" - self.start_app('Character Map') - self.start_app('Calculator') + self.start_app('Character Map', locale='C') + self.start_app('Calculator', locale='C') sleep(1) def test_showdesktop_hides_apps(self): @@ -32,8 +33,8 @@ self.launch_test_apps() # show desktop, verify all windows are hidden: - self.keyboard.press_and_release('Control+Alt+d') - self.addCleanup(self.keyboard.press_and_release, keys='Control+Alt+d') + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") sleep(3) open_wins = self.bamf.get_open_windows() self.assertGreaterEqual(len(open_wins), 2) @@ -46,7 +47,8 @@ self.launch_test_apps() # show desktop, verify all windows are hidden: - self.keyboard.press_and_release('Control+Alt+d') + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") sleep(3) open_wins = self.bamf.get_open_windows() self.assertGreaterEqual(len(open_wins), 2) @@ -55,7 +57,8 @@ self.assertTrue(win.is_hidden, "Window '%s' is not hidden after show desktop activated." % (win.title)) # un-show desktop, verify all windows are shown: - self.keyboard.press_and_release('Control+Alt+d') + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") sleep(3) for win in self.bamf.get_open_windows(): self.assertTrue(win.is_valid) @@ -66,7 +69,9 @@ self.launch_test_apps() # show desktop, verify all windows are hidden: - self.keyboard.press_and_release('Control+Alt+d') + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") + sleep(3) open_wins = self.bamf.get_open_windows() self.assertGreaterEqual(len(open_wins), 2) @@ -75,7 +80,7 @@ self.assertTrue(win.is_hidden, "Window '%s' is not hidden after show desktop activated." % (win.title)) # We'll un-minimise the character map - find it's launcherIcon in the launcher: - charmap_icon = self.launcher.model.get_icon_by_tooltip_text('Character Map') + charmap_icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop") if charmap_icon: self.launcher.get_launcher_for_monitor(0).click_launcher_icon(charmap_icon) else: @@ -90,7 +95,8 @@ self.assertTrue(win.is_hidden, "Window '%s' should still be hidden." % (win.title)) # hide desktop - now all windows should be visible: - self.keyboard.press_and_release('Control+Alt+d') + self.keybinding("window/show_desktop") + self.addCleanup(self.keybinding, "window/show_desktop") sleep(3) for win in self.bamf.get_open_windows(): if win.is_valid: @@ -101,21 +107,20 @@ self.launch_test_apps() # show desktop, verify all windows are hidden: - switcher = Switcher() - switcher.initiate() + self.switcher.initiate() sleep(0.5) found = False - for i in range(switcher.get_model_size()): - current_icon = switcher.current_icon + for i in range(self.switcher.get_model_size()): + current_icon = self.switcher.current_icon self.assertIsNotNone(current_icon) - if current_icon.tooltip_text == 'Show Desktop': + if isinstance(current_icon, DesktopLauncherIcon): found = True break - switcher.previous_icon() - sleep(0.5) + self.switcher.previous_icon() + sleep(0.25) self.assertTrue(found, "Could not find 'Show Desktop' entry in switcher.") - switcher.stop() - self.addCleanup(self.keyboard.press_and_release, keys='Control+Alt+d') + self.addCleanup(self.keybinding, "window/show_desktop") + self.switcher.stop() sleep(3) open_wins = self.bamf.get_open_windows() diff -Nru unity-5.8.0/tests/autopilot/autopilot/tests/test_switcher.py unity-5.10.0/tests/autopilot/autopilot/tests/test_switcher.py --- unity-5.8.0/tests/autopilot/autopilot/tests/test_switcher.py 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/autopilot/autopilot/tests/test_switcher.py 2012-04-12 13:21:21.000000000 +0000 @@ -6,12 +6,9 @@ # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -from subprocess import call from testtools.matchers import Equals, NotEquals, Contains, Not from time import sleep -from autopilot.emulators.bamf import Bamf -from autopilot.emulators.unity.switcher import Switcher from autopilot.tests import AutopilotTestCase @@ -200,6 +197,7 @@ self.assertThat(self.switcher.get_is_visible(), Equals(False)) + class SwitcherDetailsTests(AutopilotTestCase): """Test the details mode for the switcher.""" @@ -298,18 +296,18 @@ self.close_all_app('Character Map') self.workspace.switch_to(1) - self.start_app("Calculator") + calc = self.start_app("Calculator") sleep(1) self.workspace.switch_to(2) - self.start_app("Character Map") + char_map = self.start_app("Character Map") sleep(1) self.switcher.initiate() sleep(1) icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()] self.switcher.terminate() - self.assertThat(icon_names, Contains("Character Map")) - self.assertThat(icon_names, Not(Contains("Calculator"))) + self.assertThat(icon_names, Contains(char_map.name)) + self.assertThat(icon_names, Not(Contains(calc.name))) def test_switcher_all_mode_shows_all_apps(self): """Test switcher 'show_all' mode shows apps from all workspaces.""" @@ -317,18 +315,18 @@ self.close_all_app('Character Map') self.workspace.switch_to(1) - self.start_app("Calculator") + calc = self.start_app("Calculator") sleep(1) self.workspace.switch_to(2) - self.start_app("Character Map") + char_map = self.start_app("Character Map") sleep(1) self.switcher.initiate_all_mode() sleep(1) icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()] self.switcher.terminate() - self.assertThat(icon_names, Contains("Character Map")) - self.assertThat(icon_names, Contains("Calculator")) + self.assertThat(icon_names, Contains(calc.name)) + self.assertThat(icon_names, Contains(char_map.name)) def test_switcher_can_switch_to_minimised_window(self): """Switcher must be able to switch to a minimised window when there's @@ -343,7 +341,7 @@ self.start_app("Mahjongg") self.workspace.switch_to(3) - self.start_app("Mahjongg") + mahjongg = self.start_app("Mahjongg") sleep(1) self.keybinding("window/minimize") sleep(1) @@ -353,16 +351,14 @@ self.switcher.initiate() sleep(1) - while self.switcher.current_icon.tooltip_text != 'Mahjongg': + while self.switcher.current_icon.tooltip_text != mahjongg.name: self.switcher.next_icon() sleep(1) self.switcher.stop() sleep(1) - #get calculator windows - there should be only one: - mahjongg_apps = self.get_app_instances("Mahjongg") - self.assertThat(len(mahjongg_apps), Equals(1)) - wins = mahjongg_apps[0].get_windows() + #get mahjongg windows - there should be two: + wins = mahjongg.get_windows() self.assertThat(len(wins), Equals(2)) # Ideally we should be able to find the instance that is on the # current workspace and ask that one if it is hidden. diff -Nru unity-5.8.0/tests/CMakeLists.txt unity-5.10.0/tests/CMakeLists.txt --- unity-5.8.0/tests/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/CMakeLists.txt 2012-04-12 13:21:21.000000000 +0000 @@ -33,7 +33,7 @@ ) add_definitions (${CFLAGS}) -set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm") +set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lcompiz_core -lm") link_libraries (${LIBS}) set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS}) @@ -72,6 +72,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c ${UNITY_SRC}/ubus-server.cpp ) +target_link_libraries (test-unit ${LIBS}) add_dependencies (test-unit unity-core-${UNITY_API_VERSION}) add_subdirectory (test-input-remover) add_subdirectory (test-minimize-window-handler) @@ -110,6 +111,7 @@ test_service_main.c test_service_model.c test_service_model.h) + target_link_libraries(test-gtest-service ${LIBS}) add_dependencies (test-gtest-service unity-core-${UNITY_API_VERSION} gtest) @@ -124,6 +126,7 @@ test_glib_signals_utils.cpp test_glib_signals_utils.h test_glib_variant.cpp + test_desktop_utilities.cpp ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp test_indicator.cpp test_indicator_appmenu.cpp @@ -132,16 +135,15 @@ test_favorite_store_gsettings.cpp test_favorite_store_private.cpp test_home_lens.cpp + test_launcher_entry_remote.cpp test_shortcut_model.cpp test_shortcut_private.cpp test_introspection.cpp test_main_xless.cpp test_grabhandle.cpp test_unityshell_private.cpp - test_lensview_impl.cpp + test_showdesktop_handler.cpp ${UNITY_SRC}/AbstractLauncherIcon.cpp - ${UNITY_SRC}/AbstractPlacesGroup.cpp - ${UNITY_SRC}/AbstractPlacesGroup.h ${UNITY_SRC}/AbstractShortcutHint.h ${UNITY_SRC}/Animator.cpp ${UNITY_SRC}/DebugDBusInterface.cpp @@ -150,7 +152,7 @@ ${UNITY_SRC}/FavoriteStoreGSettings.cpp ${UNITY_SRC}/IconTextureSource.cpp ${UNITY_SRC}/LauncherModel.cpp - ${UNITY_SRC}/LensViewPrivate.cpp + ${UNITY_SRC}/LauncherEntryRemote.cpp ${UNITY_SRC}/FavoriteStorePrivate.cpp ${UNITY_SRC}/MockLauncherIcon.h ${UNITY_SRC}/MockShortcutHint.h @@ -161,13 +163,14 @@ ${UNITY_SRC}/Timer.cpp ${UNITY_SRC}/UnityshellPrivate.cpp ${UNITY_SRC}/WindowManager.cpp + ${UNITY_SRC}/UnityShowdesktopHandler.cpp ${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 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-layout.cpp ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-texture.cpp ) - target_link_libraries(test-gtest-xless gtest ${GMOCK_LIB} ${GMOCK_MAIN_LIB}) + target_link_libraries(test-gtest-xless gtest ${GMOCK_LIB} ${GMOCK_MAIN_LIB} ${LIBS}) add_test(UnityGTestXless test-gtest-xless) add_dependencies(test-gtest-xless unity-core-${UNITY_API_VERSION} gtest) @@ -185,7 +188,7 @@ test_ratings_filter.cpp test_results.cpp ) - target_link_libraries(test-gtest-dbus gtest) + target_link_libraries(test-gtest-dbus gtest ${LIBS}) add_test(UnityGTestDBus test-gtest-dbus) add_dependencies(test-gtest-dbus unity-core-${UNITY_API_VERSION} test-gtest-service gtest) @@ -194,30 +197,60 @@ test_dashview_impl.cpp test_texture_cache.cpp test_main.cpp + test_lensview_impl.cpp test_icon_loader.cpp + test_single_monitor_launcher_icon.cpp test_switcher_controller.cpp test_switcher_model.cpp ${UNITY_SRC}/AbstractLauncherIcon.cpp + ${UNITY_SRC}/AbstractPlacesGroup.cpp ${UNITY_SRC}/BackgroundEffectHelper.cpp + ${UNITY_SRC}/CairoBaseWindow.cpp ${UNITY_SRC}/DashViewPrivate.cpp - ${UNITY_SRC}/TextureCache.cpp + ${UNITY_SRC}/Decaymulator.cpp + ${UNITY_SRC}/DNDCollectionWindow.cpp + ${UNITY_SRC}/DndData.cpp + ${UNITY_SRC}/GeisAdapter.cpp ${UNITY_SRC}/IconLoader.cpp ${UNITY_SRC}/IconRenderer.cpp ${UNITY_SRC}/IconTextureSource.cpp ${UNITY_SRC}/Introspectable.cpp ${UNITY_SRC}/LayoutSystem.cpp + ${UNITY_SRC}/Launcher.cpp + ${UNITY_SRC}/LauncherDragWindow.cpp + ${UNITY_SRC}/LauncherEntryRemote.cpp + ${UNITY_SRC}/LauncherHideMachine.cpp + ${UNITY_SRC}/LauncherHoverMachine.cpp + ${UNITY_SRC}/LauncherIcon.cpp + ${UNITY_SRC}/LauncherModel.cpp + ${UNITY_SRC}/SimpleLauncherIcon.cpp + ${UNITY_SRC}/SingleMonitorLauncherIcon.cpp + ${UNITY_SRC}/LensViewPrivate.cpp ${UNITY_SRC}/StaticCairoText.cpp ${UNITY_SRC}/SwitcherController.cpp ${UNITY_SRC}/SwitcherModel.cpp ${UNITY_SRC}/SwitcherView.cpp ${UNITY_SRC}/Timer.cpp + ${UNITY_SRC}/Tooltip.cpp + ${UNITY_SRC}/PanelStyle.cpp + ${UNITY_SRC}/PointerBarrier.cpp + ${UNITY_SRC}/QuicklistView.cpp + ${UNITY_SRC}/QuicklistManager.cpp + ${UNITY_SRC}/QuicklistMenuItem.cpp + ${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp + ${UNITY_SRC}/QuicklistMenuItemLabel.cpp + ${UNITY_SRC}/QuicklistMenuItemRadio.cpp + ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp + ${UNITY_SRC}/SpacerLauncherIcon.cpp + ${UNITY_SRC}/TextureCache.cpp ${UNITY_SRC}/UBusWrapper.cpp ${UNITY_SRC}/UnityWindowStyle.cpp ${UNITY_SRC}/UnityWindowView.cpp ${UNITY_SRC}/ubus-server.cpp + ${UNITY_SRC}/UScreen.cpp ${UNITY_SRC}/WindowManager.cpp ) - target_link_libraries(test-gtest gtest) + target_link_libraries(test-gtest gtest ${LIBS}) add_test(UnityGTest test-gtest) add_dependencies(test-gtest unity-core-${UNITY_API_VERSION} gtest) @@ -225,6 +258,8 @@ GMOCK_LIB AND GMOCK_MAIN_LIB) +add_subdirectory (test-gesture-engine) + # # check target # @@ -234,21 +269,25 @@ set (GTEST_TEST_COMMAND ./test-gtest) set (GTEST_TEST_COMMAND_XLESS ./test-gtest-xless) set (GTEST_TEST_COMMAND_DBUS dbus-test-runner --task ./test-gtest-service --task ./test-gtest-dbus) +set (GTEST_TEST_COMMAND_GESTURE_ENGINE ./test-gesture-engine/test-gesture-engine) set (TEST_COMMAND gtester --verbose -k --g-fatal-warnings -o=${TEST_RESULT_XML} ./test-unit && ${GTEST_TEST_COMMAND} && ${GTEST_TEST_COMMAND_XLESS} - && ${GTEST_TEST_COMMAND_DBUS}) + && ${GTEST_TEST_COMMAND_GESTURE_ENGINE} + && ${GTEST_TEST_COMMAND_DBUS} + ) set (TEST_COMMAND_HEADLESS ${GTEST_TEST_COMMAND_XLESS} + && ${GTEST_TEST_COMMAND_GESTURE_ENGINE} #&& ${GTEST_TEST_COMMAND_DBUS} && echo "Warning, DBus test cases are disabled!!") if (GTEST_SRC_DIR) - add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus) - add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus) + add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gesture-engine) + add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gesture-engine) add_custom_target (check-report COMMAND ${TEST_UNIT_COMMAND} && gtester-report ${TEST_RESULT_XML} > ${TEST_RESULT_HTML}) add_custom_target (gcheck COMMAND ${DBUS_TEST_COMMAND} DEPENDS test-gtest test-gtest-xless) else (GTEST_SRC_DIR) diff -Nru unity-5.8.0/tests/test_desktop_utilities.cpp unity-5.10.0/tests/test_desktop_utilities.cpp --- unity-5.8.0/tests/test_desktop_utilities.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test_desktop_utilities.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,138 @@ +/* + * 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> + * Tim Penhey + */ + +#include + +#include +#include + +using namespace unity; +using testing::Eq; + +namespace { + +TEST(TestDesktopUtilitiesDesktopID, TestEmptyValues) +{ + std::vector empty_list; + + EXPECT_THAT(DesktopUtilities::GetDesktopID(empty_list, "/some/path/to.desktop"), + Eq("/some/path/to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(empty_list, "/some/path/to.desktop"), + Eq("/some/path/to.desktop")); + + std::vector empty_path_list; + empty_path_list.push_back(""); + + EXPECT_THAT(DesktopUtilities::GetDesktopID(empty_path_list, "/some/path/to.desktop"), + Eq("/some/path/to.desktop")); +} + +TEST(TestDesktopUtilitiesDesktopID, TestPathNeedsApplications) +{ + std::vector dirs; + + dirs.push_back("/this/path"); + dirs.push_back("/that/path/"); + + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/this/path/to.desktop"), + Eq("/this/path/to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/that/path/to.desktop"), + Eq("/that/path/to.desktop")); +} + +TEST(TestDesktopUtilitiesDesktopID, TestStripsPath) +{ + std::vector dirs; + + dirs.push_back("/this/path"); + dirs.push_back("/that/path/"); + + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/this/path/applications/to.desktop"), + Eq("to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/that/path/applications/to.desktop"), + Eq("to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/some/path/applications/to.desktop"), + Eq("/some/path/applications/to.desktop")); +} + +TEST(TestDesktopUtilitiesDesktopID, TestSubdirectory) +{ + std::vector dirs; + + dirs.push_back("/this/path"); + dirs.push_back("/that/path/"); + + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/this/path/applications/subdir/to.desktop"), + Eq("subdir-to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/that/path/applications/subdir/to.desktop"), + Eq("subdir-to.desktop")); + EXPECT_THAT(DesktopUtilities::GetDesktopID(dirs, "/this/path/applications/subdir1/subdir2/to.desktop"), + Eq("subdir1-subdir2-to.desktop")); +} + +TEST(TestDesktopUtilitiesDataDirectories, TestGetUserDataDirectory) +{ + const gchar* old_home = g_getenv("XDG_DATA_HOME"); + g_setenv("XDG_DATA_HOME", "UnityUserConfig", TRUE); + + std::string const& user_data_dir = DesktopUtilities::GetUserDataDirectory(); + + g_setenv("XDG_DATA_HOME", old_home, TRUE); + + EXPECT_THAT(user_data_dir, Eq("UnityUserConfig")); +} + +TEST(TestDesktopUtilitiesDataDirectories, TestGetSystemDataDirectory) +{ + const gchar* old_dirs = g_getenv("XDG_DATA_DIRS"); + g_setenv("XDG_DATA_DIRS", "dir1:dir2::dir3:dir4", TRUE); + + std::vector const& system_dirs = DesktopUtilities::GetSystemDataDirectories(); + + g_setenv("XDG_DATA_DIRS", old_dirs, TRUE); + + ASSERT_THAT(system_dirs.size(), Eq(4)); + EXPECT_THAT(system_dirs[0], Eq("dir1")); + EXPECT_THAT(system_dirs[1], Eq("dir2")); + EXPECT_THAT(system_dirs[2], Eq("dir3")); + EXPECT_THAT(system_dirs[3], Eq("dir4")); +} + +TEST(TestDesktopUtilitiesDataDirectories, TestGetDataDirectory) +{ + const gchar* old_dirs = g_getenv("XDG_DATA_DIRS"); + g_setenv("XDG_DATA_DIRS", "dir1:dir2::dir3:dir4", TRUE); + const gchar* old_home = g_getenv("XDG_DATA_HOME"); + g_setenv("XDG_DATA_HOME", "UnityUserConfig", TRUE); + + std::vector const& data_dirs = DesktopUtilities::GetDataDirectories(); + + g_setenv("XDG_DATA_DIRS", old_dirs, TRUE); + g_setenv("XDG_DATA_HOME", old_home, TRUE); + + ASSERT_THAT(data_dirs.size(), Eq(5)); + EXPECT_THAT(data_dirs[0], Eq("dir1")); + EXPECT_THAT(data_dirs[1], Eq("dir2")); + EXPECT_THAT(data_dirs[2], Eq("dir3")); + EXPECT_THAT(data_dirs[3], Eq("dir4")); + EXPECT_THAT(data_dirs[4], Eq("UnityUserConfig")); +} + +} // anonymous namespace diff -Nru unity-5.8.0/tests/test_favorite_store_gsettings.cpp unity-5.10.0/tests/test_favorite_store_gsettings.cpp --- unity-5.8.0/tests/test_favorite_store_gsettings.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/test_favorite_store_gsettings.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -22,22 +22,24 @@ #include #include +#include #include #define G_SETTINGS_ENABLE_BACKEND #include -#include +#include #include #include "FavoriteStore.h" #include "FavoriteStoreGSettings.h" +#include "FavoriteStorePrivate.h" #include - using namespace unity; +using testing::Eq; namespace { - + // Constant const gchar* SCHEMA_DIRECTORY = BUILDDIR"/settings"; const gchar* BASE_STORE_FILE = BUILDDIR"/settings/test-favorite-store-gsettings.store"; @@ -50,10 +52,10 @@ NULL }; const int n_base_store_favs = G_N_ELEMENTS(base_store_favs) - 1; /* NULL */ - + const std::string other_desktop = BUILDDIR"/tests/data/bzr-handle-patch.desktop"; -// Utilities +// Utilities std::string const& at(FavoriteList const& favs, int index) { FavoriteList::const_iterator iter = favs.begin(); @@ -69,20 +71,21 @@ else return (pos + suffix.size()) == value.size(); } - + // A new one of these is created for each test class TestFavoriteStoreGSettings : public testing::Test { public: glib::Object backend; - + std::unique_ptr setting_singleton_instance; + virtual void SetUp() { - // set the data directory so gsettings can find the schema + // set the data directory so gsettings can find the schema g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIRECTORY, false); glib::Error error; - glib::String contents(g_strdup_printf(BASE_STORE_CONTENTS, + glib::String contents(g_strdup_printf(BASE_STORE_CONTENTS, base_store_favs[0], base_store_favs[1], base_store_favs[2] @@ -92,16 +95,17 @@ contents.Value(), -1, error.AsOutParam()); - + ASSERT_FALSE(error); backend = g_keyfile_settings_backend_new(BASE_STORE_FILE, "/", "root"); + setting_singleton_instance.reset(new internal::FavoriteStoreGSettings(backend.RawPtr())); } virtual void TearDown() { } - + }; TEST_F(TestFavoriteStoreGSettings, TestAllocation) @@ -111,7 +115,7 @@ TEST_F(TestFavoriteStoreGSettings, TestGetFavorites) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); ASSERT_EQ(favs.size(), n_base_store_favs); @@ -119,11 +123,11 @@ EXPECT_TRUE(ends_with(at(favs, 1), base_store_favs[1])); EXPECT_TRUE(at(favs, 2) == base_store_favs[2]); } - + TEST_F(TestFavoriteStoreGSettings, TestAddFavorite) { - internal::FavoriteStoreGSettings settings(backend.Release()); - + FavoriteStore &settings = FavoriteStore::Instance(); + settings.AddFavorite(other_desktop, 0); FavoriteList const& favs = settings.GetFavorites(); ASSERT_EQ(favs.size(), n_base_store_favs + 1); @@ -132,8 +136,8 @@ TEST_F(TestFavoriteStoreGSettings, TestAddFavoritePosition) { - internal::FavoriteStoreGSettings settings(backend.Release()); - + FavoriteStore &settings = FavoriteStore::Instance(); + settings.AddFavorite(other_desktop, 2); FavoriteList const& favs = settings.GetFavorites(); ASSERT_EQ(favs.size(), n_base_store_favs + 1); @@ -142,8 +146,8 @@ TEST_F(TestFavoriteStoreGSettings,TestAddFavoriteLast) { - internal::FavoriteStoreGSettings settings(backend.Release()); - + FavoriteStore &settings = FavoriteStore::Instance(); + settings.AddFavorite(other_desktop, -1); FavoriteList const& favs = settings.GetFavorites(); ASSERT_EQ(favs.size(), n_base_store_favs + 1); @@ -152,7 +156,7 @@ TEST_F(TestFavoriteStoreGSettings,TestAddFavoriteOutOfRange) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); settings.AddFavorite(other_desktop, n_base_store_favs + 1); @@ -165,7 +169,7 @@ TEST_F(TestFavoriteStoreGSettings, TestRemoveFavorite) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); settings.RemoveFavorite(at(favs, 0)); @@ -180,7 +184,7 @@ TEST_F(TestFavoriteStoreGSettings, TestRemoveFavoriteBad) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); settings.RemoveFavorite(""); @@ -195,7 +199,7 @@ TEST_F(TestFavoriteStoreGSettings, TestMoveFavorite) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); @@ -209,7 +213,7 @@ TEST_F(TestFavoriteStoreGSettings, TestMoveFavoriteBad) { - internal::FavoriteStoreGSettings settings(backend.Release()); + FavoriteStore &settings = FavoriteStore::Instance(); FavoriteList const& favs = settings.GetFavorites(); @@ -224,27 +228,27 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalFirst) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; std::string position; bool before = false; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { signal_received = true; position = pos; before = bef; }); - + FavoriteList favs; favs.push_back(other_desktop); favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[1]); favs.push_back(base_store_favs[2]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); EXPECT_EQ(position, base_store_favs[0]); EXPECT_TRUE(before); @@ -252,27 +256,27 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalMiddle) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; std::string position; bool before = true; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { signal_received = true; position = pos; before = bef; }); - + FavoriteList favs; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[1]); favs.push_back(other_desktop); favs.push_back(base_store_favs[2]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); EXPECT_EQ(position, base_store_favs[1]); EXPECT_FALSE(before); @@ -280,27 +284,27 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEnd) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; std::string position; bool before = true; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { signal_received = true; position = pos; before = bef; }); - + FavoriteList favs; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[1]); favs.push_back(base_store_favs[2]); favs.push_back(other_desktop); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); EXPECT_EQ(position, base_store_favs[2]); EXPECT_FALSE(before); @@ -308,24 +312,24 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEmpty) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; std::string position; bool before = false; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { signal_received = true; position = pos; before = bef; }); - + FavoriteList favs; favs.push_back(other_desktop); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); EXPECT_EQ(position, ""); EXPECT_TRUE(before); @@ -333,88 +337,88 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteRemoved) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; std::string path_removed; - + settings.favorite_removed.connect([&](std::string const& path) { signal_received = true; path_removed = path; }); - + FavoriteList favs; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[2]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); EXPECT_EQ(path_removed, base_store_favs[1]); } TEST_F(TestFavoriteStoreGSettings, TestFavoriteReordered) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool signal_received = false; - + settings.reordered.connect([&]() { signal_received = true; }); - + FavoriteList favs; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[2]); favs.push_back(base_store_favs[1]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_TRUE(signal_received); - + signal_received = false; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[2]); favs.push_back(base_store_favs[1]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + ASSERT_FALSE(signal_received); } TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed1) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool added_received = false; bool removed_received = false; bool reordered_received = false; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { added_received = true; }); - + settings.favorite_removed.connect([&](std::string const& path) { removed_received = true; }); - + settings.reordered.connect([&]() { reordered_received = true; }); - + FavoriteList favs; favs.push_back(base_store_favs[0]); favs.push_back(base_store_favs[1]); favs.push_back(other_desktop); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + EXPECT_TRUE(added_received); EXPECT_TRUE(removed_received); EXPECT_FALSE(reordered_received); @@ -422,34 +426,34 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed2) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool added_received = false; bool removed_received = false; bool reordered_received = false; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { added_received = true; }); - + settings.favorite_removed.connect([&](std::string const& path) { removed_received = true; }); - + settings.reordered.connect([&]() { reordered_received = true; }); - + FavoriteList favs; favs.push_back(base_store_favs[1]); favs.push_back(other_desktop); favs.push_back(base_store_favs[0]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + EXPECT_TRUE(added_received); EXPECT_TRUE(removed_received); EXPECT_TRUE(reordered_received); @@ -457,33 +461,33 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed3) { - internal::FavoriteStoreGSettings settings(backend.RawPtr()); + FavoriteStore &settings = FavoriteStore::Instance(); bool added_received = false; bool removed_received = false; bool reordered_received = false; - + settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef) { added_received = true; }); - + settings.favorite_removed.connect([&](std::string const& path) { removed_received = true; }); - + settings.reordered.connect([&]() { reordered_received = true; }); - + FavoriteList favs; favs.push_back(base_store_favs[1]); favs.push_back(base_store_favs[0]); - settings.SaveFavorites(favs, false); - + setting_singleton_instance->SaveFavorites(favs, false); + sleep(1); - + EXPECT_FALSE(added_received); EXPECT_TRUE(removed_received); EXPECT_TRUE(reordered_received); diff -Nru unity-5.8.0/tests/test-gesture-engine/CMakeLists.txt unity-5.10.0/tests/test-gesture-engine/CMakeLists.txt --- unity-5.8.0/tests/test-gesture-engine/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/CMakeLists.txt 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,40 @@ +if (GTEST_SRC_DIR) + set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src) + + add_custom_command(OUTPUT GestureEngine.cpp GestureEngine.h UBusMessages.h + COMMAND cp ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${UNITY_SRC}/UBusMessages.h ${CMAKE_CURRENT_BINARY_DIR} + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.cpp > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.cpp + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.h > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.h + DEPENDS ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${UNITY_SRC}/UBusMessages.h + COMMENT "Copying GestureEngine source.") + + # Clean-up includes and definitions made in ../CmakeLists.txt + remove_definitions(${CFLAGS}) + set_directory_properties(PROPERTY INCLUDE_DIRECTORIES "") + # And make our own + pkg_check_modules (TEST_GESTURE_ENGINE_DEPS REQUIRED QUIET "${UNITY_PLUGIN_DEPS}") + set(TEST_GESTURE_ENGINE_CFLAGS + "-g" + "-I${CMAKE_CURRENT_SOURCE_DIR}" + "-I${CMAKE_CURRENT_BINARY_DIR}" + ${TEST_GESTURE_ENGINE_DEPS_CFLAGS} + ) + add_definitions(${TEST_GESTURE_ENGINE_CFLAGS}) + + pkg_check_modules (COMPIZ REQUIRED QUIET compiz) + link_directories (${COMPIZ_LIBDIR}) + + add_executable(test-gesture-engine + test_gesture_engine.cpp + X11_mock.cpp + GestureEngine.cpp + PluginAdapterMock.cpp + GeisAdapterMock.cpp + ubus-server-mock.cpp + ) + target_link_libraries(test-gesture-engine gtest ${TEST_GESTURE_ENGINE_DEPS_LIBRARIES} -lcompiz_core) + add_test(UnityGTestGestureEngine test-gesture-engine) + add_dependencies(test-gesture-engine gtest) + + add_custom_target (check-gesture-engine COMMAND ./test-gesture-engine DEPENDS test-gesture-engine) +endif (GTEST_SRC_DIR) diff -Nru unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/core.h unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/core.h --- unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/core.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/core.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef COMPIZ_CORE_MOCK_H +#define COMPIZ_CORE_MOCK_H + +#include + +#include +#include + +#endif diff -Nru unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/screen.h unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/screen.h --- unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/screen.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/screen.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef COMPIZ_SCREEN_MOCK_H +#define COMPIZ_SCREEN_MOCK_H + +#include +#include + +// The real CompScreen +#include + +typedef std::vector CompWindowMockVector; + +class CompScreenMock { +public: + typedef int GrabHandle; + + int width() const {return _width;} + int height() const {return _height;} + + Display *dpy() {return _dpy;} + + const CompWindowMockVector & clientList(bool stackingOrder = true) { + if (stackingOrder) + return _client_list_stacking; + else + return _client_list; + } + + Window root() {return _root;} + + GrabHandle pushGrab(Cursor cursor, const char *name) {return 0;} + void removeGrab(GrabHandle handle, CompPoint *restorePointer) {} + + Cursor invisibleCursor() {return 1;} + + int _width; + int _height; + Display *_dpy; + CompWindowMockVector _client_list; + CompWindowMockVector _client_list_stacking; + Window _root; +}; + +extern CompScreenMock *screen_mock; +extern int pointerX_mock; +extern int pointerY_mock; + +#endif + diff -Nru unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/window.h unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/window.h --- unity-5.8.0/tests/test-gesture-engine/compiz_mock/core/window.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/compiz_mock/core/window.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef COMPIZ_WINDOW_MOCK_H +#define COMPIZ_WINDOW_MOCK_H + +/* The real CompWindow */ +#include + +class CompWindowMock { +public: + CompWindowMock() : _moved(false), _maximize_count(0), _maximize_state(0) {} + + int x() const {return _geometry.x();} + int y() const {return _geometry.y();} + int width() const {return _geometry.width() + (_geometry.border()*2);} + int height() const {return _geometry.height() + (_geometry.border()*2);} + + void move(int dx, int dy, bool immediate = true) { + _moved = true; + _movement_x = dx; + _movement_y = dy; + } + + unsigned int actions () {return _actions;} + + void maximize(int state) {++_maximize_count; _maximize_state = state;} + + /* OBS: I wonder why it returns a reference */ + unsigned int &state() {return _state;} + + void grabNotify(int x, int y, unsigned int state, unsigned int mask) {} + void ungrabNotify() {} + + void syncPosition() {} + + compiz::window::Geometry &serverGeometry() {return _serverGeometry;} + + unsigned int _actions; + unsigned int _state; + compiz::window::Geometry _serverGeometry; + compiz::window::Geometry _geometry; + + bool _moved; + int _movement_x; + int _movement_y; + + int _maximize_count; + int _maximize_state; +}; + +#endif diff -Nru unity-5.8.0/tests/test-gesture-engine/GeisAdapterMock.cpp unity-5.10.0/tests/test-gesture-engine/GeisAdapterMock.cpp --- unity-5.8.0/tests/test-gesture-engine/GeisAdapterMock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/GeisAdapterMock.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#include "GeisAdapterMock.h" + +GeisAdapterMock *GeisAdapterMock::_default = nullptr; + +GeisAdapterMock& GeisAdapterMock::Instance() { + if (!_default) + { + _default = new GeisAdapterMock; + } + return *_default; +} diff -Nru unity-5.8.0/tests/test-gesture-engine/GeisAdapterMock.h unity-5.10.0/tests/test-gesture-engine/GeisAdapterMock.h --- unity-5.8.0/tests/test-gesture-engine/GeisAdapterMock.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/GeisAdapterMock.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef GEISADAPTER_MOCK_H +#define GEISADAPTER_MOCK_H + +#include +#include + +class GeisAdapterMock : public sigc::trackable +{ +public: + static GeisAdapterMock& Instance(); + + ~GeisAdapterMock() {} + + typedef struct _GeisTapData + { + int id; + int device_id; + Window window; + int touches; + int timestamp; + float focus_x; + float focus_y; + int tap_length_ms; + float position_x; + float position_y; + float bound_x1; + float bound_y1; + float bound_x2; + float bound_y2; + } GeisTapData; + + typedef struct _GeisDragData + { + int id; + int device_id; + Window window; + int touches; + int timestamp; + float focus_x; + float focus_y; + float delta_x; + float delta_y; + float velocity_x; + float velocity_y; + float position_x; + float position_y; + float bound_x1; + float bound_y1; + float bound_x2; + float bound_y2; + } GeisDragData; + + typedef struct _GeisRotateData + { + int id; + int device_id; + Window window; + int touches; + int timestamp; + float focus_x; + float focus_y; + float angle; + float angle_delta; + float angle_velocity; + float bound_x1; + float bound_y1; + float bound_x2; + float bound_y2; + } GeisRotateData; + + typedef struct _GeisPinchData + { + int id; + int device_id; + Window window; + int touches; + int timestamp; + float focus_x; + float focus_y; + float radius; + float radius_delta; + float radius_velocity; + float bound_x1; + float bound_y1; + float bound_x2; + float bound_y2; + } GeisPinchData; + + typedef struct _GeisTouchData + { + int id; + int device_id; + Window window; + int touches; + int timestamp; + float focus_x; + float focus_y; + float bound_x1; + float bound_y1; + float bound_x2; + float bound_y2; + } GeisTouchData; + + sigc::signal tap; + + sigc::signal drag_start; + sigc::signal drag_update; + sigc::signal drag_finish; + + sigc::signal rotate_start; + sigc::signal rotate_update; + sigc::signal rotate_finish; + + sigc::signal pinch_start; + sigc::signal pinch_update; + sigc::signal pinch_finish; + + sigc::signal touch_start; + sigc::signal touch_update; + sigc::signal touch_finish; + +private: + GeisAdapterMock() {} + + static GeisAdapterMock* _default; + +}; +#endif diff -Nru unity-5.8.0/tests/test-gesture-engine/PluginAdapterMock.cpp unity-5.10.0/tests/test-gesture-engine/PluginAdapterMock.cpp --- unity-5.8.0/tests/test-gesture-engine/PluginAdapterMock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/PluginAdapterMock.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#include "PluginAdapterMock.h" + +PluginAdapterMock *PluginAdapterMock::_default = 0; + +PluginAdapterMock *PluginAdapterMock::Default() { + if (!_default) { + _default = new PluginAdapterMock; + } + return _default; +} + +void PluginAdapterMock::ShowGrabHandles(CompWindowMock* window, bool use_timer) { +} diff -Nru unity-5.8.0/tests/test-gesture-engine/PluginAdapterMock.h unity-5.10.0/tests/test-gesture-engine/PluginAdapterMock.h --- unity-5.8.0/tests/test-gesture-engine/PluginAdapterMock.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/PluginAdapterMock.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef PLUGINADAPTER_MOCK_H +#define PLUGINADAPTER_MOCK_H + +#include + +class PluginAdapterMock { +public: + static PluginAdapterMock *Default(); + + void ShowGrabHandles(CompWindowMock* window, bool use_timer); + +private: + PluginAdapterMock() {} + static PluginAdapterMock* _default; +}; + +#endif diff -Nru unity-5.8.0/tests/test-gesture-engine/sed_script unity-5.10.0/tests/test-gesture-engine/sed_script --- unity-5.8.0/tests/test-gesture-engine/sed_script 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/sed_script 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,14 @@ +s||| +s|\|CompScreenMock|g +s|\|CompWindowMock|g +s|\|CompWindowMockVector|g +s|\|screen_mock|g +s|\|pointerX_mock|g +s|\|pointerY_mock|g +s|\|XSyncMock|g +s|\|XWarpPointerMock|g +s|\|XFreeCursorMock|g +s|\|XCreateFontCursorMock|g +s|\|GeisAdapterMock|g +s|\|PluginAdapterMock|g +s|\|ubus-server-mock.h|g diff -Nru unity-5.8.0/tests/test-gesture-engine/test_gesture_engine.cpp unity-5.10.0/tests/test-gesture-engine/test_gesture_engine.cpp --- unity-5.8.0/tests/test-gesture-engine/test_gesture_engine.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/test_gesture_engine.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,230 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#include +#include +#include "GestureEngine.h" + +CompScreenMock concrete_screen_mock; +CompScreenMock *screen_mock = &concrete_screen_mock; +int pointerX_mock = 0; +int pointerY_mock = 0; + +class GestureEngineTest : public ::testing::Test { + protected: + virtual void SetUp() { + screen_mock->_width = 1280; + screen_mock->_height = 1024; + + GenerateWindows(); + } + + void PerformPinch(GestureEngine &gesture_engine, float peak_radius) { + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + GeisAdapterMock::GeisTouchData touch_data; + touch_data.id = 1; + touch_data.touches = 3; + touch_data.window = 123; + touch_data.focus_x = 100; /* hits the middle window */ + touch_data.focus_y = 100; + gesture_engine.OnTouchStart(&touch_data); + + GeisAdapterMock::GeisPinchData pinch_data; + pinch_data.id = 1; + pinch_data.touches = 3; + pinch_data.window = 123; + pinch_data.focus_x = 100; /* hits the middle window */ + pinch_data.focus_y = 100; + pinch_data.radius = 1.0; + gesture_engine.OnPinchStart(&pinch_data); + + touch_data.focus_x += 10; + touch_data.focus_y += 20; + gesture_engine.OnTouchUpdate(&touch_data); + + pinch_data.focus_x += 10; + pinch_data.focus_y += 20; + pinch_data.radius = peak_radius; + gesture_engine.OnPinchUpdate(&pinch_data); + + gesture_engine.OnTouchFinish(&touch_data); + gesture_engine.OnPinchFinish(&pinch_data); + } + + private: + void GenerateWindows() { + /* remove windows from previous test */ + for (auto window : screen_mock->_client_list_stacking) { + delete window; + } + screen_mock->_client_list_stacking.clear(); + + /* and generate new ones */ + CompWindowMock *window; + + /* the root window */ + window = new CompWindowMock; + /* x, y, width, height, border */ + window->_geometry.set(0, 0, screen_mock->width(), screen_mock->height(), 0); + window->_serverGeometry = window->_geometry; + window->_actions = 0; + window->_state = 0; + screen_mock->_client_list_stacking.push_back(window); + + /* middle window */ + window = new CompWindowMock; + window->_geometry.set(10, 10, 400, 400, 0); + window->_serverGeometry = window->_geometry; + window->_actions = CompWindowActionMoveMask; + window->_state = 0; + screen_mock->_client_list_stacking.push_back(window); + + /* top-level window */ + window = new CompWindowMock; + window->_geometry.set(500, 500, 410, 410, 0); + window->_serverGeometry = window->_geometry; + window->_actions = CompWindowActionMoveMask; + window->_state = 0; + screen_mock->_client_list_stacking.push_back(window); + + screen_mock->_client_list = screen_mock->_client_list_stacking; + std::reverse(screen_mock->_client_list.begin(), + screen_mock->_client_list.end()); + } +}; + +TEST_F(GestureEngineTest, ThreeFingersDragMovesWindow) +{ + GestureEngine gestureEngine(screen_mock); + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + GeisAdapterMock::GeisTouchData touch_data; + touch_data.id = 1; + touch_data.touches = 3; + touch_data.window = 123; + touch_data.focus_x = 100; /* hits the middle window */ + touch_data.focus_y = 100; + gestureEngine.OnTouchStart(&touch_data); + + GeisAdapterMock::GeisDragData drag_data; + drag_data.id = 1; + drag_data.touches = 3; + drag_data.window = 123; + drag_data.focus_x = 100; /* hits the middle window */ + drag_data.focus_y = 100; + gestureEngine.OnDragStart(&drag_data); + + ASSERT_FALSE(middle_window->_moved); + + touch_data.focus_x += 10; + touch_data.focus_y += 20; + gestureEngine.OnTouchUpdate(&touch_data); + + drag_data.delta_x = 10; + drag_data.delta_y = 20; + drag_data.focus_x += drag_data.delta_x; + drag_data.focus_y += drag_data.delta_x; + gestureEngine.OnDragUpdate(&drag_data); + + ASSERT_TRUE(middle_window->_moved); + ASSERT_EQ(drag_data.delta_x, middle_window->_movement_x); + ASSERT_EQ(drag_data.delta_y, middle_window->_movement_y); +} + +TEST_F(GestureEngineTest, ThreeFingersDragDoesntMoveStaticWindow) +{ + GestureEngine gestureEngine(screen_mock); + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + /* can't be moved */ + middle_window->_actions = 0; + + GeisAdapterMock::GeisTouchData touch_data; + touch_data.id = 1; + touch_data.touches = 3; + touch_data.window = 123; + touch_data.focus_x = 100; /* hits the middle window */ + touch_data.focus_y = 100; + gestureEngine.OnTouchStart(&touch_data); + + GeisAdapterMock::GeisDragData drag_data; + drag_data.id = 1; + drag_data.touches = 3; + drag_data.window = 123; + drag_data.focus_x = 100; /* hits the middle window */ + drag_data.focus_y = 100; + gestureEngine.OnDragStart(&drag_data); + + ASSERT_FALSE(middle_window->_moved); + + touch_data.focus_x += 10; + touch_data.focus_y += 20; + gestureEngine.OnTouchUpdate(&touch_data); + + drag_data.delta_x = 10; + drag_data.delta_y = 20; + drag_data.focus_x += drag_data.delta_x; + drag_data.focus_y += drag_data.delta_x; + gestureEngine.OnDragUpdate(&drag_data); + + ASSERT_FALSE(middle_window->_moved); +} + +TEST_F(GestureEngineTest, ThreeFingersPinchMaximizesWindow) +{ + GestureEngine gesture_engine(screen_mock); + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + PerformPinch(gesture_engine, 2.0); + + ASSERT_EQ(1, middle_window->_maximize_count); + ASSERT_EQ(MAXIMIZE_STATE, middle_window->_maximize_state); +} + +TEST_F(GestureEngineTest, ThreeFingersPinchRestoresWindow) +{ + GestureEngine gesture_engine(screen_mock); + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + PerformPinch(gesture_engine, 0.3); + + ASSERT_EQ(1, middle_window->_maximize_count); + ASSERT_EQ(0, middle_window->_maximize_state); +} + +TEST_F(GestureEngineTest, MinimalThreeFingersPinchDoesNothing) +{ + GestureEngine gesture_engine(screen_mock); + CompWindowMock *middle_window = screen_mock->_client_list_stacking[1]; + + PerformPinch(gesture_engine, 1.1); + + ASSERT_EQ(0, middle_window->_maximize_count); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + int ret = RUN_ALL_TESTS(); + + return ret; +} diff -Nru unity-5.8.0/tests/test-gesture-engine/ubus-server-mock.cpp unity-5.10.0/tests/test-gesture-engine/ubus-server-mock.cpp --- unity-5.8.0/tests/test-gesture-engine/ubus-server-mock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/ubus-server-mock.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#include + +UBusServer default_server; + +UBusServer* ubus_server_get_default() { + return &default_server; +} + +void ubus_server_send_message(UBusServer* server, + const gchar* message, + GVariant* data) { +} diff -Nru unity-5.8.0/tests/test-gesture-engine/ubus-server-mock.h unity-5.10.0/tests/test-gesture-engine/ubus-server-mock.h --- unity-5.8.0/tests/test-gesture-engine/ubus-server-mock.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/ubus-server-mock.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef UBUS_SERVER_MOCK_H +#define UBUS_SERVER_MOCK_H + +#include +#include + +class UBusServer { +}; + +UBusServer* ubus_server_get_default(); + +void ubus_server_send_message(UBusServer* server, + const gchar* message, + GVariant* data); +#endif // UBUS_SERVER_MOCK_H diff -Nru unity-5.8.0/tests/test-gesture-engine/X11_mock.cpp unity-5.10.0/tests/test-gesture-engine/X11_mock.cpp --- unity-5.8.0/tests/test-gesture-engine/X11_mock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/X11_mock.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#include + +Cursor XCreateFontCursorMock(Display * /*display*/, unsigned int /*shape*/) { + return 1; +} + +int XFreeCursorMock(Display * /*display*/, Cursor /*cursor*/) { + return 1; +} + +int XSyncMock(Display *display, Bool discard) { + return 1; +} + +int XWarpPointerMock(Display *display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y) { + return 1; +} diff -Nru unity-5.8.0/tests/test-gesture-engine/X11_mock.h unity-5.10.0/tests/test-gesture-engine/X11_mock.h --- unity-5.8.0/tests/test-gesture-engine/X11_mock.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test-gesture-engine/X11_mock.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * 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: Daniel d'Andrada + * + */ + +#ifndef X11_MOCK_H +#define X11_MOCK_H + +#include + +Cursor XCreateFontCursorMock(Display *display, unsigned int shape); + +int XFreeCursorMock(Display *display, Cursor cursor); + +int XSyncMock(Display *display, Bool discard); + +int XWarpPointerMock(Display *display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y); + +#endif // X11_MOCK_H diff -Nru unity-5.8.0/tests/test_launcher_entry_remote.cpp unity-5.10.0/tests/test_launcher_entry_remote.cpp --- unity-5.8.0/tests/test_launcher_entry_remote.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test_launcher_entry_remote.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,389 @@ +// -*- 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 "LauncherEntryRemote.h" + +using namespace std; +using namespace unity; +using namespace testing; + +namespace +{ + +GVariant* BuildVariantParameters(std::string const& app_uri = "app_uri", + std::string const& emblem = "emblem", + bool emblem_visible = false, + long long count = 0, + bool count_visible = false, + double progress = 0.0f, + bool progress_visible = false, + bool urgent = false, + std::string const& quicklist_path = "/my/quicklist/path") +{ + GVariantBuilder b; + + g_variant_builder_init(&b, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add(&b, "{sv}", "emblem", g_variant_new_string(emblem.c_str())); + g_variant_builder_add(&b, "{sv}", "emblem-visible", g_variant_new_boolean(emblem_visible)); + g_variant_builder_add(&b, "{sv}", "count", g_variant_new_int64(count)); + g_variant_builder_add(&b, "{sv}", "count-visible", g_variant_new_boolean(count_visible)); + g_variant_builder_add(&b, "{sv}", "progress", g_variant_new_double(progress)); + g_variant_builder_add(&b, "{sv}", "progress-visible", g_variant_new_boolean(progress_visible)); + g_variant_builder_add(&b, "{sv}", "urgent", g_variant_new_boolean(urgent)); + g_variant_builder_add(&b, "{sv}", "quicklist", g_variant_new_string(quicklist_path.c_str())); + + return g_variant_new("(sa{sv})", app_uri.c_str(), &b); +} + +TEST(TestLauncherEntryRemote, DummyConstruction) +{ + LauncherEntryRemote entry("TestName", nullptr); + + EXPECT_EQ(entry.DBusName(), "TestName"); + EXPECT_TRUE(entry.AppUri().empty()); + EXPECT_TRUE(entry.Emblem().empty()); + EXPECT_EQ(entry.Count(), 0); + EXPECT_EQ(entry.Progress(), 0.0f); + EXPECT_THAT(entry.Quicklist().RawPtr(), IsNull()); + EXPECT_FALSE(entry.EmblemVisible()); + EXPECT_FALSE(entry.CountVisible()); + EXPECT_FALSE(entry.ProgressVisible()); + EXPECT_FALSE(entry.Urgent()); +} + +TEST(TestLauncherEntryRemote, Construction) +{ + LauncherEntryRemote entry("TestName", BuildVariantParameters()); + + EXPECT_EQ(entry.DBusName(), "TestName"); + EXPECT_EQ(entry.AppUri(), "app_uri"); + EXPECT_EQ(entry.Emblem(), "emblem"); + EXPECT_EQ(entry.Count(), 0); + EXPECT_EQ(entry.Progress(), 0.0f); + EXPECT_THAT(entry.Quicklist().RawPtr(), NotNull()); + EXPECT_FALSE(entry.EmblemVisible()); + EXPECT_FALSE(entry.CountVisible()); + EXPECT_FALSE(entry.ProgressVisible()); + EXPECT_FALSE(entry.Urgent()); +} + +TEST(TestLauncherEntryRemote, CustomConstruction) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + LauncherEntryRemote entry("CustomName", parameters); + + EXPECT_EQ(entry.DBusName(), "CustomName"); + EXPECT_EQ(entry.AppUri(), "Uri"); + EXPECT_EQ(entry.Emblem(), "TestEmblem"); + EXPECT_EQ(entry.Count(), 55); + EXPECT_EQ(entry.Progress(), 31.12f); + EXPECT_THAT(entry.Quicklist().RawPtr(), NotNull()); + EXPECT_TRUE(entry.EmblemVisible()); + EXPECT_TRUE(entry.CountVisible()); + EXPECT_TRUE(entry.ProgressVisible()); + EXPECT_TRUE(entry.Urgent()); +} + +TEST(TestLauncherEntryRemote, UpdateFromOther) +{ + LauncherEntryRemote entry1("Entry1", BuildVariantParameters("AppURI1")); + + ASSERT_EQ(entry1.DBusName(), "Entry1"); + ASSERT_EQ(entry1.AppUri(), "AppURI1"); + auto old_ql1 = entry1.Quicklist(); + ASSERT_THAT(old_ql1.RawPtr(), NotNull()); + + GVariant* parameters; + parameters = BuildVariantParameters("Uri2", "TestEmblem", false, 5, true, 0.12f, + true, false, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + ASSERT_EQ(entry2->AppUri(), "Uri2"); + + entry1.Update(entry2); + + EXPECT_EQ(entry1.DBusName(), "Entry2"); + EXPECT_EQ(entry1.AppUri(), "AppURI1"); + EXPECT_EQ(entry1.Emblem(), "TestEmblem"); + EXPECT_EQ(entry1.Count(), 5); + EXPECT_EQ(entry1.Progress(), 0.12f); + EXPECT_THAT(entry1.Quicklist().RawPtr(), NotNull()); + EXPECT_NE(old_ql1, entry1.Quicklist()); + EXPECT_FALSE(entry1.EmblemVisible()); + EXPECT_TRUE(entry1.CountVisible()); + EXPECT_TRUE(entry1.ProgressVisible()); + EXPECT_FALSE(entry1.Urgent()); +} + +TEST(TestLauncherEntryRemote, UpdateFromVariantIter) +{ + LauncherEntryRemote entry1("Entry1", BuildVariantParameters("AppURI1")); + + ASSERT_EQ(entry1.DBusName(), "Entry1"); + ASSERT_EQ(entry1.AppUri(), "AppURI1"); + auto old_ql1 = entry1.Quicklist(); + ASSERT_THAT(old_ql1.RawPtr(), NotNull()); + + GVariant* parameters; + parameters = BuildVariantParameters("Uri2", "TestEmblem", false, 5, true, 0.12f, + true, false, "/My/DBus/Menu/For/QL"); + + gchar* app_uri; + GVariantIter* prop_iter; + g_variant_get(parameters, "(&sa{sv})", &app_uri, &prop_iter); + entry1.Update(prop_iter); + g_variant_iter_free(prop_iter); + + EXPECT_EQ(entry1.DBusName(), "Entry1"); + EXPECT_EQ(entry1.AppUri(), "AppURI1"); + EXPECT_EQ(entry1.Emblem(), "TestEmblem"); + EXPECT_EQ(entry1.Count(), 5); + EXPECT_EQ(entry1.Progress(), 0.12f); + EXPECT_THAT(entry1.Quicklist().RawPtr(), NotNull()); + EXPECT_NE(old_ql1, entry1.Quicklist()); + EXPECT_FALSE(entry1.EmblemVisible()); + EXPECT_TRUE(entry1.CountVisible()); + EXPECT_TRUE(entry1.ProgressVisible()); + EXPECT_FALSE(entry1.Urgent()); +} + +TEST(TestLauncherEntryRemote, ChangeDBusName) +{ + LauncherEntryRemote entry("Entry", BuildVariantParameters("AppURI")); + + bool name_changed = false; + std::string old_name; + entry.dbus_name_changed.connect([&] (LauncherEntryRemote*, std::string s) { + name_changed = true; + old_name = s; + }); + + auto old_ql = entry.Quicklist(); + ASSERT_THAT(old_ql.RawPtr(), NotNull()); + ASSERT_EQ(entry.DBusName(), "Entry"); + + entry.SetDBusName("NewEntryName"); + ASSERT_EQ(entry.DBusName(), "NewEntryName"); + + EXPECT_THAT(entry.Quicklist().RawPtr(), IsNull()); + EXPECT_NE(old_ql, entry.Quicklist()); + + EXPECT_TRUE(name_changed); + EXPECT_EQ(old_name, "Entry"); +} + +TEST(TestLauncherEntryRemote, EmblemChangedSignal) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem1", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.emblem_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem2", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_EQ(entry1.Emblem(), "TestEmblem1"); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_EQ(entry1.Emblem(), "TestEmblem2"); +} + +TEST(TestLauncherEntryRemote, CountChangedSignal) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.count_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 155, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_EQ(entry1.Count(), 55); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_EQ(entry1.Count(), 155); +} + +TEST(TestLauncherEntryRemote, ProgressChangedSignal) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 0.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.progress_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_EQ(entry1.Progress(), 0.12f); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_EQ(entry1.Progress(), 31.12f); +} + +TEST(TestLauncherEntryRemote, QuicklistChangedSignal) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL1"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.quicklist_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL2"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + auto old_ql1 = entry1.Quicklist(); + ASSERT_THAT(old_ql1.RawPtr(), NotNull()); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_NE(entry1.Quicklist(), old_ql1); + EXPECT_EQ(entry1.Quicklist(), entry2->Quicklist()); +} + +TEST(TestLauncherEntryRemote, EmblemVisibilityChanged) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.emblem_visible_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", true, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_FALSE(entry1.EmblemVisible()); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_TRUE(entry1.EmblemVisible()); +} + +TEST(TestLauncherEntryRemote, CountVisibilityChanged) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, false, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.count_visible_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, true, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_FALSE(entry1.CountVisible()); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_TRUE(entry1.CountVisible()); +} + +TEST(TestLauncherEntryRemote, ProgressVisibilityChanged) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, false, 31.12f, + false, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.progress_visible_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, false, 31.12f, + true, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_FALSE(entry1.ProgressVisible()); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_TRUE(entry1.ProgressVisible()); +} + +TEST(TestLauncherEntryRemote, UrgentChanged) +{ + GVariant* parameters; + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, false, 31.12f, + false, false, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote entry1("Entry1", parameters); + + bool value_changed = false; + entry1.urgent_changed.connect([&] (LauncherEntryRemote*) { value_changed = true; }); + + parameters = BuildVariantParameters("Uri", "TestEmblem", false, 55, false, 31.12f, + false, true, "/My/DBus/Menu/For/QL"); + + LauncherEntryRemote::Ptr entry2(new LauncherEntryRemote("Entry2", parameters)); + + ASSERT_FALSE(entry1.Urgent()); + + entry1.Update(entry2); + + EXPECT_TRUE(value_changed); + EXPECT_TRUE(entry1.Urgent()); +} + +} // Namespace diff -Nru unity-5.8.0/tests/test_shortcut_model.cpp unity-5.10.0/tests/test_shortcut_model.cpp --- unity-5.8.0/tests/test_shortcut_model.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/test_shortcut_model.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -17,6 +17,7 @@ * Authored by: Andrea Azzarone */ +#include #include #include "MockShortcutHint.h" @@ -28,15 +29,15 @@ TEST(TestShortcutModel, TestConstruction) { - std::list hints; - - hints.push_back(new MockHint("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1")); - hints.push_back(new MockHint("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2")); - hints.push_back(new MockHint("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3")); - hints.push_back(new MockHint("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value4")); - + std::list hints; + + hints.push_back(std::make_shared("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1")); + hints.push_back(std::make_shared("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2")); + hints.push_back(std::make_shared("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3")); + hints.push_back(std::make_shared("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value4")); + Model model(hints); - + EXPECT_EQ(model.categories().size(), 3); EXPECT_EQ(model.hints()["Launcher"].size(), 2); EXPECT_EQ(model.hints()["Dash"].size(), 1); @@ -46,17 +47,17 @@ TEST(TestShortcutModel, TestFill) { - std::list hints; - - hints.push_back(new MockHint("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1")); - hints.push_back(new MockHint("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2")); - hints.push_back(new MockHint("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3")); - hints.push_back(new MockHint("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value 4")); - + std::list hints; + + hints.push_back(std::make_shared("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1")); + hints.push_back(std::make_shared("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2")); + hints.push_back(std::make_shared("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3")); + hints.push_back(std::make_shared("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value 4")); + Model model(hints); - + model.Fill(); - + // We cannot test CompOption here... :/ EXPECT_EQ(model.hints()["Launcher"].front()->value(), "Plugin 1-key_option_1"); EXPECT_EQ(model.hints()["Launcher"].back()->value(), "Value 2"); @@ -66,19 +67,19 @@ TEST(TestShortcutModel, TestProperty) { - std::list hints; - - hints.push_back(new MockHint("Launcher", "Prefix1", "Postfix1", "Description1", COMPIZ_KEY_OPTION, "Plugin1", "key_option1")); - + std::list hints; + + hints.push_back(std::make_shared("Launcher", "Prefix1", "Postfix1", "Description1", COMPIZ_KEY_OPTION, "Plugin1", "key_option1")); + Model model(hints); - + EXPECT_EQ(model.hints()["Launcher"].front()->category(), "Launcher"); EXPECT_EQ(model.hints()["Launcher"].front()->prefix(), "Prefix1"); EXPECT_EQ(model.hints()["Launcher"].front()->postfix(), "Postfix1"); EXPECT_EQ(model.hints()["Launcher"].front()->description(), "Description1"); EXPECT_EQ(model.hints()["Launcher"].front()->type(), COMPIZ_KEY_OPTION); EXPECT_EQ(model.hints()["Launcher"].front()->arg1(), "Plugin1"); - EXPECT_EQ(model.hints()["Launcher"].front()->arg2(), "key_option1"); + EXPECT_EQ(model.hints()["Launcher"].front()->arg2(), "key_option1"); } } // anonymouse namespace diff -Nru unity-5.8.0/tests/test_showdesktop_handler.cpp unity-5.10.0/tests/test_showdesktop_handler.cpp --- unity-5.8.0/tests/test_showdesktop_handler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test_showdesktop_handler.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,539 @@ +#include +#include +#include +#include +#include + +using namespace unity; +using ::testing::_; +using ::testing::Return; +using ::testing::Invoke; +using ::testing::InSequence; + +compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface () {} + +class MockWindowInputRemover : + public compiz::WindowInputRemoverInterface +{ + public: + + MockWindowInputRemover () + { + ON_CALL (*this, saveInput ()).WillByDefault (Return (true)); + ON_CALL (*this, removeInput ()).WillByDefault (Return (true)); + ON_CALL (*this, restoreInput ()).WillByDefault (Return (true)); + } + + MOCK_METHOD0 (saveInput, bool ()); + MOCK_METHOD0 (removeInput, bool ()); + MOCK_METHOD0 (restoreInput, bool ()); +}; + +class UnityShowdesktopHandlerTest : + public ::testing::Test +{ +public: + + ~UnityShowdesktopHandlerTest () + { + ShowdesktopHandler::animating_windows.clear (); + } + + template static typename T::Ptr makeShared () { return typename T::Ptr (new U); } + +}; + + +class MockUnityShowdesktopHandlerWindow : + public ShowdesktopHandlerWindowInterface +{ + public: + + MockUnityShowdesktopHandlerWindow () + { + ON_CALL (*this, IsOverrideRedirect ()).WillByDefault (Return (false)); + ON_CALL (*this, IsManaged ()).WillByDefault (Return (true)); + ON_CALL (*this, IsGrabbed ()).WillByDefault (Return (false)); + ON_CALL (*this, IsDesktopOrDock ()).WillByDefault (Return (false)); + ON_CALL (*this, IsSkipTaskbarOrPager ()).WillByDefault (Return (false)); + ON_CALL (*this, IsHidden ()).WillByDefault (Return (false)); + ON_CALL (*this, IsInShowdesktopMode ()).WillByDefault (Return (false)); + ON_CALL (*this, IsShaded ()).WillByDefault (Return (false)); + ON_CALL (*this, IsMinimized ()).WillByDefault (Return (false)); + + ON_CALL (*this, DoHandleAnimations (_)).WillByDefault (Return (ShowdesktopHandlerWindowInterface::PostPaintAction::Damage)); + ON_CALL (*this, GetNoCoreInstanceMask ()).WillByDefault (Return (1)); + ON_CALL (*this, GetInputRemover ()).WillByDefault (Invoke (UnityShowdesktopHandlerTest::makeShared)); + } + + MOCK_METHOD0 (DoEnableFocus, void ()); + MOCK_METHOD0 (DoDisableFocus, void ()); + MOCK_METHOD0 (IsOverrideRedirect, bool ()); + MOCK_METHOD0 (IsManaged, bool ()); + MOCK_METHOD0 (IsGrabbed, bool ()); + MOCK_METHOD0 (IsDesktopOrDock, bool ()); + MOCK_METHOD0 (IsSkipTaskbarOrPager, bool ()); + MOCK_METHOD0 (IsHidden, bool ()); + MOCK_METHOD0 (IsInShowdesktopMode, bool ()); + MOCK_METHOD0 (IsShaded, bool ()); + MOCK_METHOD0 (IsMinimized, bool ()); + MOCK_METHOD1 (DoOverrideFrameRegion, void (CompRegion &)); + MOCK_METHOD0 (DoHide, void ()); + MOCK_METHOD0 (DoNotifyHidden, void ()); + MOCK_METHOD0 (DoShow, void ()); + MOCK_METHOD0 (DoNotifyShown, void ()); + MOCK_METHOD0 (DoMoveFocusAway, void ()); + MOCK_METHOD1 (DoHandleAnimations, ShowdesktopHandlerWindowInterface::PostPaintAction (unsigned int)); + MOCK_METHOD0 (DoAddDamage, void ()); + MOCK_METHOD0 (GetNoCoreInstanceMask, unsigned int ()); + MOCK_METHOD0 (GetInputRemover, compiz::WindowInputRemoverInterface::Ptr ()); + MOCK_METHOD0 (DoDeleteHandler, void ()); +}; + +TEST_F(UnityShowdesktopHandlerTest, TestNoORWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestNoUnmanagedWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()).WillOnce (Return (false)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestNoGrabbedWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestNoDesktopOrDockWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()); + EXPECT_CALL (mMockWindow, IsDesktopOrDock ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestNoSkipTaskbarOrPagerWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()); + EXPECT_CALL (mMockWindow, IsDesktopOrDock ()); + EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndShadedWindowsNoSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()); + EXPECT_CALL (mMockWindow, IsDesktopOrDock ()); + EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()); + EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true)); + EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false)); + EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndShadedWindowsNoSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()); + EXPECT_CALL (mMockWindow, IsDesktopOrDock ()); + EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()); + EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true)); + EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (true)); + EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsOverrideRedirect ()); + EXPECT_CALL (mMockWindow, IsManaged ()); + EXPECT_CALL (mMockWindow, IsGrabbed ()); + EXPECT_CALL (mMockWindow, IsDesktopOrDock ()); + EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()); + EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true)); + EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false)); + EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (false)); + EXPECT_TRUE (ShowdesktopHandler::ShouldHide (&mMockWindow)); +} + +class MockWindowInputRemoverTestFadeOut : + public compiz::WindowInputRemoverInterface +{ + public: + + MockWindowInputRemoverTestFadeOut () + { + ON_CALL (*this, saveInput ()).WillByDefault (Return (true)); + ON_CALL (*this, removeInput ()).WillByDefault (Return (true)); + ON_CALL (*this, restoreInput ()).WillByDefault (Return (true)); + + EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true)); + } + + MOCK_METHOD0 (saveInput, bool ()); + MOCK_METHOD0 (removeInput, bool ()); + MOCK_METHOD0 (restoreInput, bool ()); +}; + +TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindow) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +class MockWindowInputRemoverTestFadeOutAlready : + public compiz::WindowInputRemoverInterface +{ + public: + + MockWindowInputRemoverTestFadeOutAlready () + { + ON_CALL (*this, saveInput ()).WillByDefault (Return (true)); + ON_CALL (*this, removeInput ()).WillByDefault (Return (true)); + ON_CALL (*this, restoreInput ()).WillByDefault (Return (true)); + } + + MOCK_METHOD0 (saveInput, bool ()); + MOCK_METHOD0 (removeInput, bool ()); + MOCK_METHOD0 (restoreInput, bool ()); +}; + +TEST_F(UnityShowdesktopHandlerTest, TestFadeOutOnHiddenDoesntHideWindow) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true)); + + mMockHandler.FadeOut (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 0); +} + +TEST_F(UnityShowdesktopHandlerTest, TestFadeOutAlreadyFadedDoesntHideWindow) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + mMockHandler.FadeOut (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +TEST_F(UnityShowdesktopHandlerTest, TestFadeInNonFadedDoesntShowWindow) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + mMockHandler.FadeIn (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 0); +} + +class MockWindowInputRemoverTestFadeOutFadeIn : + public compiz::WindowInputRemoverInterface +{ + public: + + MockWindowInputRemoverTestFadeOutFadeIn () + { + ON_CALL (*this, saveInput ()).WillByDefault (Return (true)); + ON_CALL (*this, removeInput ()).WillByDefault (Return (true)); + ON_CALL (*this, restoreInput ()).WillByDefault (Return (true)); + + EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true)); + } + + MOCK_METHOD0 (saveInput, bool ()); + MOCK_METHOD0 (removeInput, bool ()); + MOCK_METHOD0 (restoreInput, bool ()); +}; + +TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindowFadeInShowsWindow) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_CALL (mMockWindow, DoShow ()); + EXPECT_CALL (mMockWindow, DoNotifyShown ()); + + mMockHandler.FadeIn (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +TEST_F(UnityShowdesktopHandlerTest, TestAnimationPostPaintActions) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_CALL (mMockWindow, DoShow ()); + EXPECT_CALL (mMockWindow, DoNotifyShown ()); + + for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++) + { + ShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1); + + if (i == 300) + EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Wait); + else + EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Damage); + } + + mMockHandler.FadeIn (); + + for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++) + { + ShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1); + + if (i == 300) + EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Remove); + else + EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Damage); + } + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +TEST_F(UnityShowdesktopHandlerTest, TestAnimationOpacity) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_CALL (mMockWindow, DoShow ()); + EXPECT_CALL (mMockWindow, DoNotifyShown ()); + + /* The funny expectations here are to account for rounding errors that would + * otherwise make testing the code painful */ + + for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++) + { + unsigned short opacity = std::numeric_limits ::max (); + mMockHandler.PaintOpacity (opacity); + + mMockHandler.Animate (1); + + if (i == 300) + EXPECT_EQ (opacity, std::numeric_limits ::max ()); + else + { + float rem = opacity - std::numeric_limits ::max () * (1.0f - i / static_cast (ShowdesktopHandler::fade_time)); + EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f); + } + } + + mMockHandler.FadeIn (); + + for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++) + { + unsigned short opacity = std::numeric_limits ::max (); + mMockHandler.PaintOpacity (opacity); + + mMockHandler.Animate (1); + + if (i == 300) + EXPECT_EQ (opacity, std::numeric_limits ::max ()); + else + { + float rem = opacity - std::numeric_limits ::max () * (i / static_cast (ShowdesktopHandler::fade_time)); + EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f); + } + } + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +TEST_F(UnityShowdesktopHandlerTest, TestAnimationPaintMasks) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_CALL (mMockWindow, DoShow ()); + EXPECT_CALL (mMockWindow, DoNotifyShown ()); + EXPECT_CALL (mMockWindow, GetNoCoreInstanceMask ()); + + mMockHandler.Animate (ShowdesktopHandler::fade_time); + + EXPECT_EQ (mMockHandler.GetPaintMask (), 1); + + mMockHandler.FadeIn (); + + mMockHandler.Animate (ShowdesktopHandler::fade_time); + + EXPECT_EQ (mMockHandler.GetPaintMask (), 0); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} + +class MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent : + public compiz::WindowInputRemoverInterface +{ + public: + + MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent () + { + ON_CALL (*this, saveInput ()).WillByDefault (Return (true)); + ON_CALL (*this, removeInput ()).WillByDefault (Return (true)); + ON_CALL (*this, restoreInput ()).WillByDefault (Return (true)); + + InSequence s; + + EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true)); + EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true)); + } + + MOCK_METHOD0 (saveInput, bool ()); + MOCK_METHOD0 (removeInput, bool ()); + MOCK_METHOD0 (restoreInput, bool ()); +}; + +TEST_F(UnityShowdesktopHandlerTest, TestShapeEvent) +{ + MockUnityShowdesktopHandlerWindow mMockWindow; + + EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared)); + + ShowdesktopHandler mMockHandler (static_cast (&mMockWindow)); + + EXPECT_CALL (mMockWindow, IsHidden ()); + EXPECT_CALL (mMockWindow, DoHide ()); + EXPECT_CALL (mMockWindow, DoNotifyHidden ()); + + mMockHandler.FadeOut (); + + EXPECT_CALL (mMockWindow, DoShow ()); + EXPECT_CALL (mMockWindow, DoNotifyShown ()); + + mMockHandler.HandleShapeEvent (); + + mMockHandler.FadeIn (); + + EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1); +} diff -Nru unity-5.8.0/tests/test_single_monitor_launcher_icon.cpp unity-5.10.0/tests/test_single_monitor_launcher_icon.cpp --- unity-5.8.0/tests/test_single_monitor_launcher_icon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/tests/test_single_monitor_launcher_icon.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,55 @@ +// -*- 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 "SingleMonitorLauncherIcon.h" +#include "MultiMonitor.h" + +using namespace unity; +using namespace launcher; + +namespace +{ + +TEST(TestSingleMonitorLauncherIcon, Construction) +{ + SingleMonitorLauncherIcon icon(1); + + EXPECT_EQ(icon.GetMonitor(), 1); + EXPECT_TRUE(icon.IsVisibleOnMonitor(1)); + EXPECT_FALSE(icon.IsVisibleOnMonitor(0)); +} + +TEST(TestSingleMonitorLauncherIcon, MonitorVisibility) +{ + SingleMonitorLauncherIcon icon(2); + + for (int i = 0; i < max_num_monitors; ++i) + { + bool icon_visible = icon.IsVisibleOnMonitor(i); + + if (i == 2) + EXPECT_TRUE(icon_visible); + else + EXPECT_FALSE(icon_visible); + } +} + +} diff -Nru unity-5.8.0/tests/test_switcher_controller.cpp unity-5.10.0/tests/test_switcher_controller.cpp --- unity-5.8.0/tests/test_switcher_controller.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/tests/test_switcher_controller.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -19,10 +19,13 @@ */ #include +#include -#include "SwitcherController.h" #include "test_utils.h" +#include "SwitcherController.h" +#include "TimeUtil.h" + using namespace unity::switcher; @@ -39,6 +42,7 @@ , window_constructed_(false) , view_constructed_(false) , view_shown_(false) + , detail_timeout_reached_(false) {}; MockSwitcherController(unsigned int load_timeout) @@ -46,6 +50,7 @@ , window_constructed_(false) , view_constructed_(false) , view_shown_(false) + , detail_timeout_reached_(false) {}; virtual void ConstructWindow() @@ -63,14 +68,29 @@ view_shown_ = true; } + virtual gboolean OnDetailTimer() + { + detail_timeout_reached_ = true; + clock_gettime(CLOCK_MONOTONIC, &detail_timespec_); + return FALSE; + } + unsigned int GetConstructTimeout() const { return construct_timeout_; } + void FakeSelectionChange() + { + unity::launcher::AbstractLauncherIcon::Ptr icon(nullptr); + OnModelSelectionChanged(icon); + } + bool window_constructed_; bool view_constructed_; bool view_shown_; + bool detail_timeout_reached_; + struct timespec detail_timespec_; }; TEST(TestSwitcherController, Construction) @@ -103,4 +123,37 @@ EXPECT_TRUE(controller.window_constructed_); } +TEST(TestSwitcherController, InitialDetailTimeout) +{ + MockSwitcherController controller; + std::vector results; + struct timespec current; + + controller.initial_detail_timeout_length = 2000; + controller.detail_timeout_length = 20000; + clock_gettime(CLOCK_MONOTONIC, ¤t); + + controller.Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, false, results); + + Utils::WaitUntil(controller.detail_timeout_reached_, 3); + ASSERT_TRUE(controller.detail_timeout_reached_); + EXPECT_TRUE(unity::TimeUtil::TimeDelta(&controller.detail_timespec_, ¤t) >= 2000); +} + +TEST(TestSwitcherController, DetailTimeout) +{ + MockSwitcherController controller; + struct timespec current; + + controller.detail_timeout_length = 1000; + controller.initial_detail_timeout_length = 10000; + clock_gettime(CLOCK_MONOTONIC, ¤t); + + controller.FakeSelectionChange(); + + Utils::WaitUntil(controller.detail_timeout_reached_, 2); + ASSERT_TRUE(controller.detail_timeout_reached_); + EXPECT_TRUE(unity::TimeUtil::TimeDelta(&controller.detail_timespec_, ¤t) >= 1000); +} + } diff -Nru unity-5.8.0/UnityCore/CMakeLists.txt unity-5.10.0/UnityCore/CMakeLists.txt --- unity-5.8.0/UnityCore/CMakeLists.txt 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/CMakeLists.txt 2012-04-12 13:21:21.000000000 +0000 @@ -13,6 +13,7 @@ Category.h CheckOptionFilter.h DBusIndicators.h + DesktopUtilities.h FilesystemLenses.h Filter.h Filters.h @@ -50,6 +51,7 @@ Category.cpp CheckOptionFilter.cpp DBusIndicators.cpp + DesktopUtilities.cpp FilesystemLenses.cpp Filter.cpp Filters.cpp diff -Nru unity-5.8.0/UnityCore/DesktopUtilities.cpp unity-5.10.0/UnityCore/DesktopUtilities.cpp --- unity-5.8.0/UnityCore/DesktopUtilities.cpp 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/UnityCore/DesktopUtilities.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,119 @@ +// -*- 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 "DesktopUtilities.h" + +namespace unity +{ + +std::string DesktopUtilities::GetUserDataDirectory() +{ + const char* user_dir = g_get_user_data_dir(); + + if (user_dir) + return user_dir; + + // This shouldn't ever happen, but let's manually fallback to the default + const char* home = g_get_home_dir(); + + if (home) + { + const char* subdir = G_DIR_SEPARATOR_S ".local" G_DIR_SEPARATOR_S "share"; + return std::string(home).append(subdir); + } + + return ""; +} + +std::vector DesktopUtilities::GetSystemDataDirectories() +{ + const char* const* system_dirs = g_get_system_data_dirs(); + std::vector directories; + + for (unsigned int i = 0; system_dirs && system_dirs[i]; ++i) + { + if (system_dirs[i][0] != '\0') + { + std::string dir(system_dirs[i]); + directories.push_back(dir); + } + } + + return directories; +} + +std::vector DesktopUtilities::GetDataDirectories() +{ + std::vector dirs = GetSystemDataDirectories(); + std::string const& user_directory = GetUserDataDirectory(); + + dirs.push_back(user_directory); + + return dirs; +} + +std::string DesktopUtilities::GetDesktopID(std::vector const& default_paths, + std::string const& desktop_path) +{ + /* We check to see if the desktop file belongs to one of the system data + * directories. If so, then we store it's desktop id, otherwise we store + * it's full path. We're clever like that. + */ + + if (desktop_path.empty()) + return ""; + + for (auto dir : default_paths) + { + if (!dir.empty()) + { + if (dir.at(dir.length()-1) == G_DIR_SEPARATOR) + { + dir.append("applications" G_DIR_SEPARATOR_S); + } + else + { + dir.append(G_DIR_SEPARATOR_S "applications" G_DIR_SEPARATOR_S); + } + + if (desktop_path.find(dir) == 0) + { + // if we are in a subdirectory of system path, the store name should + // be subdir-filename.desktop + std::string desktop_suffix = desktop_path.substr(dir.size()); + std::replace(desktop_suffix.begin(), desktop_suffix.end(), G_DIR_SEPARATOR, '-'); + + return desktop_suffix; + } + } + } + + return desktop_path; +} + +std::string DesktopUtilities::GetDesktopID(std::string const& desktop_path) +{ + std::vector const& data_dirs = GetDataDirectories(); + return GetDesktopID(data_dirs, desktop_path); +} + +} // namespace unity diff -Nru unity-5.8.0/UnityCore/DesktopUtilities.h unity-5.10.0/UnityCore/DesktopUtilities.h --- unity-5.8.0/UnityCore/DesktopUtilities.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-5.10.0/UnityCore/DesktopUtilities.h 2012-04-12 13:21:21.000000000 +0000 @@ -0,0 +1,43 @@ +// -*- 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_DESKTOP_UTILITIES_H +#define UNITY_DESKTOP_UTILITIES_H + +#include +#include + +namespace unity +{ + +class DesktopUtilities +{ +public: + static std::string GetUserDataDirectory(); + static std::vector GetSystemDataDirectories(); + static std::vector GetDataDirectories(); + + static std::string GetDesktopID(std::string const& desktop_path); + static std::string GetDesktopID(std::vector const& default_paths, + std::string const& desktop_path); +}; + +} // namespace + +#endif diff -Nru unity-5.8.0/UnityCore/FilesystemLenses.cpp unity-5.10.0/UnityCore/FilesystemLenses.cpp --- unity-5.8.0/UnityCore/FilesystemLenses.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/FilesystemLenses.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -46,13 +46,13 @@ } // Loads data from a Lens key-file in a usable form -LensDirectoryReader::LensFileData::LensFileData(GKeyFile* file, +LensDirectoryReader::LensFileData::LensFileData(GKeyFile* file, const gchar *lens_id) : id(g_strdup(lens_id)) , domain(g_key_file_get_string(file, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL)) , dbus_name(g_key_file_get_string(file, GROUP, "DBusName", NULL)) , dbus_path(g_key_file_get_string(file, GROUP, "DBusPath", NULL)) - , name(g_strdup(g_dgettext(domain.Value(), g_key_file_get_string(file, GROUP, "Name", NULL)))) + , name(g_strdup(g_dgettext(domain.Value(), glib::String(g_key_file_get_string(file, GROUP, "Name", NULL))))) , icon(g_key_file_get_string(file, GROUP, "Icon", NULL)) , description(g_key_file_get_locale_string(file, GROUP, "Description", NULL, NULL)) , search_hint(g_key_file_get_locale_string(file, GROUP, "SearchHint", NULL, NULL)) @@ -135,7 +135,7 @@ void GetLensDataFromKeyFile(GFile* path, const char* data, gsize length); DataList GetLensData() const; void SortLensList(); - + static void OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self); static void LoadFileContentCallback(GObject* source, GAsyncResult* res, gpointer user_data); @@ -249,7 +249,7 @@ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; // self is invalid now } - + self->cancel_map_.erase(file); // If we're not waiting for any more children to load, signal that we're @@ -275,7 +275,7 @@ { glib::String id(g_path_get_basename(path.Value())); - lenses_data_.push_back(new LensFileData(key_file, id)); + lenses_data_.push_back(LensFileDataPtr(new LensFileData(key_file, id))); LOG_DEBUG(logger) << "Sucessfully loaded lens file " << path; } @@ -304,7 +304,7 @@ { //FIXME: We don't have a strict order, but alphabetical serves us well. // When we have an order/policy, please replace this. - auto sort_cb = [] (LensFileData* a, LensFileData* b) -> bool + auto sort_cb = [] (LensFileDataPtr a, LensFileDataPtr b) -> bool { if (a->id.Str() == "applications.lens") return true; diff -Nru unity-5.8.0/UnityCore/FilesystemLenses.h unity-5.10.0/UnityCore/FilesystemLenses.h --- unity-5.8.0/UnityCore/FilesystemLenses.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/FilesystemLenses.h 2012-04-12 13:21:21.000000000 +0000 @@ -52,7 +52,8 @@ }; typedef std::shared_ptr Ptr; - typedef std::vector DataList; + typedef std::shared_ptr LensFileDataPtr; + typedef std::vector DataList; LensDirectoryReader(std::string const& directory); ~LensDirectoryReader(); diff -Nru unity-5.8.0/UnityCore/HomeLens.cpp unity-5.10.0/UnityCore/HomeLens.cpp --- unity-5.8.0/UnityCore/HomeLens.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/HomeLens.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -260,6 +260,20 @@ }; /* + * Specialized ModelMerger that is reponsible for filters, currently ignores + * everything. + */ +class HomeLens::FiltersMerger : public ModelMerger +{ +public: + FiltersMerger(glib::Object target); + + void OnSourceRowAdded(DeeModel *model, DeeModelIter *iter); + void OnSourceRowRemoved(DeeModel *model, DeeModelIter *iter); + void OnSourceRowChanged(DeeModel *model, DeeModelIter *iter); +}; + +/* * Pimpl for HomeLens */ class HomeLens::Impl : public sigc::trackable @@ -278,7 +292,7 @@ HomeLens::CategoryRegistry cat_registry_; HomeLens::ResultsMerger results_merger_; HomeLens::CategoryMerger categories_merger_; - HomeLens::ModelMerger filters_merger_; + HomeLens::FiltersMerger filters_merger_; int running_searches_; glib::Object settings_; }; @@ -306,10 +320,14 @@ , priority_tag_(dee_model_register_tag(target, NULL)) {} +HomeLens::FiltersMerger::FiltersMerger(glib::Object target) + : HomeLens::ModelMerger::ModelMerger(target) +{} + HomeLens::ModelMerger::~ModelMerger() { if (row_buf_) - delete row_buf_; + g_free(row_buf_); } void HomeLens::ModelMerger::AddSource(glib::Object source) @@ -341,10 +359,6 @@ void HomeLens::ModelMerger::OnSourceRowAdded(DeeModel *model, DeeModelIter *iter) { // Default impl. does nothing. - // Note that the filters_merger_ relies on this behavior. Supporting - // filters on the home screen is possible, but *quite* tricky. - // So... - // Discard ALL the rows! } void HomeLens::ResultsMerger::OnSourceRowAdded(DeeModel *model, DeeModelIter *iter) @@ -464,6 +478,13 @@ for (unsigned int i = 0; i < n_cols_; i++) g_variant_unref(row_buf_[i]); } +void HomeLens::FiltersMerger::OnSourceRowAdded(DeeModel *model, DeeModelIter *iter) +{ + /* Supporting filters on the home screen is possible, but *quite* tricky. + * So... Discard ALL the rows! + */ +} + void HomeLens::CategoryMerger::OnSourceRowRemoved(DeeModel *model, DeeModelIter *iter) { /* We don't support removals of categories. @@ -499,6 +520,11 @@ ModelMerger::OnSourceRowRemoved(model, iter); } +void HomeLens::FiltersMerger::OnSourceRowRemoved(DeeModel *model, DeeModelIter *iter) +{ + /* We aren't adding any rows to the merged model, so nothing to do here */ +} + void HomeLens::ModelMerger::OnSourceRowChanged(DeeModel *model, DeeModelIter *iter) { DeeModelIter* target_iter; @@ -523,6 +549,11 @@ LOG_WARN(logger) << "In-line changing of results not supported in the home lens. Sorry."; } +void HomeLens::FiltersMerger::OnSourceRowChanged(DeeModel *model, DeeModelIter *iter) +{ + /* We aren't adding any rows to the merged model, so nothing to do here */ +} + void HomeLens::ModelMerger::EnsureRowBuf(DeeModel *model) { if (G_UNLIKELY (n_cols_ == 0)) @@ -827,13 +858,16 @@ * FIXME: Do the same for results? */ DeeModel* cats = categories_prop(); - DeeModelIter* cats_iter; - DeeModelIter* cats_end; - for (cats_iter = dee_model_get_first_iter(cats), cats_end = dee_model_get_last_iter(cats); - cats_iter != cats_end; - cats_iter = dee_model_next(cats, cats_iter)) + if (cats) { - categories_merger_.OnSourceRowAdded(cats, cats_iter); + DeeModelIter* cats_iter; + DeeModelIter* cats_end; + for (cats_iter = dee_model_get_first_iter(cats), cats_end = dee_model_get_last_iter(cats); + cats_iter != cats_end; + cats_iter = dee_model_next(cats, cats_iter)) + { + categories_merger_.OnSourceRowAdded(cats, cats_iter); + } } } diff -Nru unity-5.8.0/UnityCore/HomeLens.h unity-5.10.0/UnityCore/HomeLens.h --- unity-5.8.0/UnityCore/HomeLens.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/HomeLens.h 2012-04-12 13:21:21.000000000 +0000 @@ -69,6 +69,7 @@ class ModelMerger; class ResultsMerger; class CategoryMerger; + class FiltersMerger; class CategoryRegistry; Impl* pimpl; }; diff -Nru unity-5.8.0/UnityCore/Hud.cpp unity-5.10.0/UnityCore/Hud.cpp --- unity-5.8.0/UnityCore/Hud.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/Hud.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -16,7 +16,7 @@ * * Authored by: Gordon Allott */ -// +// #include "Hud.h" #include @@ -52,9 +52,9 @@ , parent_(parent) { LOG_DEBUG(logger) << "Hud init with name: " << dbus_name << "and path: " << dbus_path; - proxy_.connected.connect([&]() { - LOG_DEBUG(logger) << "Hud Connected"; - parent_->connected = true; + proxy_.connected.connect([&]() { + LOG_DEBUG(logger) << "Hud Connected"; + parent_->connected = true; }); proxy_.Connect("UpdatedQuery", sigc::mem_fun(this, &HudImpl::UpdateQueryCallback)); @@ -76,12 +76,12 @@ void HudImpl::ExecuteByKey(GVariant* key, unsigned int timestamp) { LOG_DEBUG(logger) << "Executing by Key"; - + GVariantBuilder tuple; g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(&tuple, g_variant_new_variant(key)); g_variant_builder_add_value(&tuple, g_variant_new_uint32(timestamp)); - + proxy_.Call("ExecuteQuery", g_variant_builder_end(&tuple)); } @@ -92,16 +92,16 @@ LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3"; return; } - + queries_.clear(); - + GVariant* query_key = g_variant_get_child_value(query, 2); - query_key_ = query_key; - + query_key_ = query_key; + GVariant* queries = g_variant_get_child_value(query, 1); BuildQueries(queries); g_variant_unref(queries); - + if (queries_.empty() == false) { // we now execute based off the first result @@ -122,14 +122,14 @@ // extract the information from the GVariants GVariant* target = g_variant_get_child_value(query, 0); g_variant_unref(target); - + GVariant* query_key = g_variant_get_child_value(query, 2); - query_key_ = query_key; - + query_key_ = query_key; + GVariant* queries = g_variant_get_child_value(query, 1); BuildQueries(queries); g_variant_unref(queries); - + parent_->queries_updated.emit(queries_); } @@ -145,8 +145,9 @@ // the signal GVariant* query_key = g_variant_get_child_value(query, 2); - if (g_variant_equal(query_key_, query_key)) + if (query_key_ && g_variant_equal(query_key_, query_key)) { + queries_.clear(); GVariant* queries = g_variant_get_child_value(query, 1); BuildQueries(queries); g_variant_unref(queries); @@ -164,13 +165,13 @@ glib::String completion_text; glib::String shortcut; GVariant* key = NULL; - - while (g_variant_iter_loop(&iter, "(sssssv)", + + while (g_variant_iter_loop(&iter, "(sssssv)", &formatted_text, &icon, &item_icon, &completion_text, &shortcut, &key)) { - queries_.push_back(Query::Ptr(new Query(formatted_text, + queries_.push_back(Query::Ptr(new Query(formatted_text, icon, - item_icon, + item_icon, completion_text, shortcut, key))); @@ -178,7 +179,7 @@ } void HudImpl::CloseQuery() -{ +{ if (query_key_ == NULL) { LOG_WARN(logger) << "Attempted to close the hud connection without starting it"; @@ -215,8 +216,8 @@ CloseQuery(); } - GVariant* paramaters = g_variant_new("(si)", - search_string.c_str(), + GVariant* paramaters = g_variant_new("(si)", + search_string.c_str(), request_number_of_results); pimpl_->proxy_.Call("StartQuery", paramaters, sigc::mem_fun(this->pimpl_, &HudImpl::QueryCallback)); } @@ -234,10 +235,10 @@ LOG_DEBUG(logger) << "Executing by string" << execute_string; if (pimpl_->query_key_ != NULL) { - CloseQuery(); + CloseQuery(); } - GVariant* paramaters = g_variant_new("(si)", + GVariant* paramaters = g_variant_new("(si)", execute_string.c_str(), 1); diff -Nru unity-5.8.0/UnityCore/Variant.cpp unity-5.10.0/UnityCore/Variant.cpp --- unity-5.8.0/UnityCore/Variant.cpp 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/Variant.cpp 2012-04-12 13:21:21.000000000 +0000 @@ -142,15 +142,44 @@ return *this; } -BuilderWrapper& BuilderWrapper::add(char const* name, unsigned value) +BuilderWrapper& BuilderWrapper::add(char const* name, long int value) +{ + g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value)); + return *this; +} + +BuilderWrapper& BuilderWrapper::add(char const* name, long long int value) +{ + g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value)); + return *this; +} + +BuilderWrapper& BuilderWrapper::add(char const* name, unsigned int value) { g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint32(value)); return *this; } +BuilderWrapper& BuilderWrapper::add(char const* name, long unsigned int value) +{ + g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value)); + return *this; +} + +BuilderWrapper& BuilderWrapper::add(char const* name, long long unsigned int value) +{ + g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value)); + return *this; +} + BuilderWrapper& BuilderWrapper::add(char const* name, float value) { - // floats get promoted to doubles automatically + g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value)); + return *this; +} + +BuilderWrapper& BuilderWrapper::add(char const* name, double value) +{ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value)); return *this; } diff -Nru unity-5.8.0/UnityCore/Variant.h unity-5.10.0/UnityCore/Variant.h --- unity-5.8.0/UnityCore/Variant.h 2012-03-23 11:53:16.000000000 +0000 +++ unity-5.10.0/UnityCore/Variant.h 2012-04-12 13:21:21.000000000 +0000 @@ -73,8 +73,13 @@ BuilderWrapper& add(char const* name, char const* value); BuilderWrapper& add(char const* name, std::string const& value); BuilderWrapper& add(char const* name, int value); - BuilderWrapper& add(char const* name, unsigned value); + BuilderWrapper& add(char const* name, long int value); + BuilderWrapper& add(char const* name, long long int value); + BuilderWrapper& add(char const* name, unsigned int value); + BuilderWrapper& add(char const* name, long unsigned int value); + BuilderWrapper& add(char const* name, long long unsigned int value); BuilderWrapper& add(char const* name, float value); + BuilderWrapper& add(char const* name, double value); BuilderWrapper& add(char const* name, GVariant* value); BuilderWrapper& add(nux::Rect const& value);