diff options
107 files changed, 7567 insertions, 1512 deletions
@@ -1,4 +1,7 @@ + 3v1n0 <mail@3v1n0.net>, Marco Trevisan (Treviño) <mail@3v1n0.net> + agateau <aurelien.gateau@canonical.com> Alejandro Piñeiro <apinheiro@igalia.com> + Alexandros Frantzis <alexandros.frantzis@linaro.org>, Marc Ordinas i Llopis <marc.ordinasillopis@linaro.org>, Jay Taoko <jay.taoko@canonical.com> Alex Launi <alex.launi@canonical.com> Alex Launi <alex.launi@canonical.com>, Allan LeSage <allanlesage@gmail.com> Andrea Azzarone @@ -15,6 +18,7 @@ Daniel van Vugt <vanvugt@gmail.com> David Barth <david.barth@canonical.com> David Gomes <davidrafagomes@gmail.com> + David Planella <david.planella@ubuntu.com> Didier Roche <didier.roche@canonical.com> Gordon Allott <gord.allott@canonical.com> Henri De Veene <henri.deveene@gmail.com> @@ -22,6 +26,8 @@ Jani Monoses <jani@ubuntu.com> Jason Conti <jason.conti@gmail.com> Jason Smith <jason.smith@canonical.com> + Jason Smith <jason.smith@canonical.com>, Marco Trevisan (Treviño) <mail@3v1n0.net>, Thomi Richards <thomi.richards@canonical.com> + Jason Smith <jason.smith@canonical.com>, smspillaz <sam.spilsbury@canonical.com> jassmith@gmail.com Jay Ó Broin <ismise@lavabit.com> Jay Taoko <jay.taoko@canonical.com> @@ -31,6 +37,7 @@ Marco Trevisan Marco Trevisan <mail@3v1n0.net> Marco Trevisan (Treviño) <mail@3v1n0.net> + Marco Trevisan (Treviño) <mail@3v1n0.net>, 3v1n0 <mail@3v1n0.net> Marius Gedminas <marius@gedmin.as> Michael Terry <michael.terry@canonical.com> Michael Terry <mike@mterry.name> @@ -50,11 +57,13 @@ Sam Spilsbury <sam.spilsbury@canonical.com> Sam Spilsbury <sam.spilsbury@canonical.com>, Daniel van Vugt <vanvugt@gmail.com> Sebastien Bacher <seb128@ubuntu.com> + smspillaz <sam.spilsbury@canonical.com>, Sam Spilsbury <sam.spilsbury@canonical.com> Tarmac Ted Gould <ted@gould.cx> Thomas Voß <thomas.voss@rub.de> Thomi Richards <thomir@gmail.com> Thomi Richards <thomir@gmail.com>, Alex Launi <alex.launi@canonical.com> + Thomi Richards <thomir@gmail.com>, Thomi Richards <thomi.richards@canonical.com> Tim Penhey <tim.penhey@canonical.com> Ubuntu <ubuntu@netbook> Unity Merger <unity.merger@gmail.com> diff --git a/CMakeLists.txt b/CMakeLists.txt index 66c47f12e..2c3998808 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include (cmake/Documentation.cmake) # set (PROJECT_NAME "unity") set (UNITY_MAJOR 5) -set (UNITY_MINOR 0) +set (UNITY_MINOR 2) set (UNITY_MICRO 0) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "5.0") @@ -113,7 +113,7 @@ if (BOOT_LOGGER) SET (BOOT_LOGGER_FLAG "-DENABLE_LOGGER") endif (BOOT_LOGGER) -SET (MAINTAINER_CFLAGS "-Werror -Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds") +SET (MAINTAINER_CFLAGS "-Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds") option (DISABLE_MAINTAINER_CFLAGS "Disable maintainer CFlags" OFF) if (DISABLE_MAINTAINER_CFLAGS) SET (MAINTAINER_CFLAGS "") @@ -122,7 +122,7 @@ endif (DISABLE_MAINTAINER_CFLAGS) # # Compiz Plugins # -set (UNITY_PLUGIN_DEPS "compiz;nux-2.0 >= 2.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4;atk;unity-misc >= 0.4.0;gconf-2.0;libutouch-geis;gtk+-3.0 >= 3.1;sigc++-2.0;json-glib-1.0;libnotify;gnome-desktop-3.0;gdu") +set (UNITY_PLUGIN_DEPS "compiz;nux-2.0>=2.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4;atk;unity-misc>=0.4.0;gconf-2.0;libutouch-geis;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;gnome-desktop-3.0;gdu") add_subdirectory(plugins/unityshell) add_subdirectory(plugins/gtkloader) @@ -1,3 +1,2185 @@ +2012-02-03 Didier Roche <didier.roche@canonical.com> + + welcome unity 5.2 + +2012-02-02 Andrea Azzarone <azzaronea@gmail.com> + + Constructs the shortcut view until its first needed. UNBLOCK.. Fixes: . Approved by Jason Smith. + +2012-02-02 Andrea Azzarone <azzaronea@gmail.com> + + Constructs the shortcut view until its first needed. + +2012-02-01 Jason Smith <jason.smith@canonical.com> + + Adds filtering when icon backgrounds are being scaled. + + UNBLOCK - this is a display regression.. Fixes: . Approved by Gord Allott. + +2012-02-01 Jason Smith <jason.smith@canonical.com> + + fix square icons at non-default sizes + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + UNBLOCK + + Fixes launcher reveal for some people. Fixes: . Approved by Robert Carr, Gord Allott. + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + adjust algo some more + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + tweak algo + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + implement responsiveness as a conglomerate option for changing reveal behavior + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + initialize variable + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + ooops + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + don't ever release barriers on left edge of X screen + +2012-01-31 Jason Smith <jason.smith@canonical.com> + + dont emit on event_id change as there are some bugs in the protocol still + +2012-01-31 Andrea Azzarone <azzaronea@gmail.com> + + Make sure that the dash searchbar doesn't lose the focus when clicking on an empty dash area (or an area that should not get the focus on mouse down). + + SetAccepetKeyNavFocus is already tested in trunk. + + UNBLOCK. Fixes: https://bugs.launchpad.net/bugs/919567, https://bugs.launchpad.net/bugs/923988. Approved by Mikkel Kamstrup Erlandsen. + +2012-01-31 Andrea Azzarone <azzaronea@gmail.com> + + Updates the manual test. + +2012-01-30 Andrea Azzarone <azzaronea@gmail.com> + + Fixes bug #923988. + +2012-01-27 Andrea Azzarone <azzaronea@gmail.com> + + Adds a manutal test. + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Clicking on an empty areas makes the dash search bar lose focus. + +2012-01-31 Gord Allott <gord.allott@canonical.com> + + adds definition to the launcher manual test + UNBLOCK. Fixes: . Approved by Didier Roche. + +2012-01-31 Gord Allott <gord.allott@canonical.com> + + added definition to the launcher manual-test + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + UNBLOCK + + (as didrocks requested) + + This branch implements different defaults for the edge reveal as well as capping velocities at 600 to help slower devices.. Fixes: . Approved by Thomi Richards. + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + make sure test passes every time + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + fix autopilot tests + add test to ensure launcher doesn't hide after mouse reveal + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + fix defaults + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + update defaults + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + increase smoothing a bit + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + cap max velocity + +2012-01-30 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Making the panel service to attach its menus to a MenuBar to make the new lp:light-themes to correctly draw them. + + Now we use a menubar child of an offscreen window to attach the menus to. So Cimi can recognize them and make them pink! :D + + UNBLOCK. Fixes: . Approved by Andrea Cimitan. + +2012-01-30 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Added manual test. + +2012-01-30 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelService: go back to use gtk_window_set_attached_to + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelService: we don't need anymore gtk+-3.0 3.3... + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelService: Moving to gtk_menu_attach_to_widget + + It doesn't need to get the indicator toplevel window, and is here since long time + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelService: add created menus to a menubar, to fix styling + + Idea by Cimi. + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + UNBLOCK + + Creates test for situation where mouse is under launcher, and the user presses and releases super. The launcher should hide again after all is done.. Fixes: . Approved by Neil J. Patel. + +2012-01-30 Jason Smith <jason.smith@canonical.com> + + add autopilot test for launcher hide after super keypress + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + Colorifies icons as per design spec. Fixes: . Approved by . + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + implement colorify filtering on desaturated icons to match design goals + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + . Fixes: . Approved by Thomi Richards. + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + whitespace fixes + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + get monitor properly + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + add monitor to Launcher introspection + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + fix some whitespace issues and fix spurious ranging + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + add comment to test + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + improve quicklist testing + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + make reveal test check every launcher + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + restore reveal test + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + This branch implements the following behaviors into Unity: + + - Multiple launchers per monitor + - Dash follows mouse + - Keybindings follow mouse + - Focus and raising windows is monitor aware + - Launchers are monitor and workspace aware. Fixes: . Approved by Thomi Richards, Marco Trevisan (Treviño). + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + merge multi-screen work for autopilot + +2012-01-30 Thomi Richards <thomi.richards@canonical.com> + + Screen Geometry class added to X11.py + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + fix sort test + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + fix test formatting + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + make SwitcherView and ShortcutView use the same code to render their backgrounds + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + hide shortcuts when entering key nav mode + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + add test for quicklist open/close in launcher switcher + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + make window placement algorithm aware of all launchers + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + add autopilot tests for launcher keybinding interactions + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + restore functionality so key-nav continues after closing a quicklist in alt+f1 + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + fix potential crash whel Alt+F1 is used and last_monitor is not set + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + use nullptr + +2012-01-29 Jason Smith <jason.smith@canonical.com> + + more consting + +2012-01-28 Jason Smith <jason.smith@canonical.com> + + more const's + +2012-01-28 Jason Smith <jason.smith@canonical.com> + + begin const-ification of launcher and its fellow classes + +2012-01-28 Jason Smith <jason.smith@canonical.com> + + remove unused code + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + prepare for doing some sort of progress indication + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: reimplementing some lost features to disable the switcher on key / button press. + + And also to avoid to send the cancel event if not requested. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Opps. damned bzr: removing duplicated values. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Merging with upstream. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Merging with jason changes + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + merge trunk + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + LauncherController: don't show the shortcuts if the key_nav is active. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Go back to use TYPE_BEGIN for the DesktopLauncherIcon or it will mess around with the switcher. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + AbstractLauncherIcon: reducing the priority of the desktop icon on switcher. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: Don't show the switcher if the desktop icon is the only available. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + DesktopLauncherIcon: don't set as running. + + This fix the issue that was causing an arrow indicator to show next to it. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + SwitcherView: add monitor property and use it to get the number of windows indicators to draw + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + BamfLauncherIcon: don't return window invisible windows on WindowsForMonitor + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + BamfLauncherIcon: WindowsForMonitor should take care of the viewport too. + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + Also render sheen properly for rows + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + properly calculate current monitor + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + make overlay sheen render properly in multi-monitor + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + make sure right panel goes transparent + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + ensure proper monitor gets used + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + fix issue where tooltip would pop up even when mouse wasn't over launcher + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + apply smoothing to raw pointer barrier events + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + monitor aware focus behavior + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + enable Super+Esc + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + enable looping around of super+tab and make sure that icons are always visible + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + remove dead code + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + make sure icons redraw when selection changes + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + merge trunk + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + make dash move around with mouse + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + restore feature parity with trunk, but now with MM support + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + restore alt-f1 functionality + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + restore activation with keyboard + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + restore shortcut drawing + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + remove cruft + +2012-01-26 Jason Smith <jason.smith@canonical.com> + + start responding to Super keybindings again + +2012-01-25 Jason Smith <jason.smith@canonical.com> + + Add decaymulator + +2012-01-25 Jason Smith <jason.smith@canonical.com> + + merge trunk and make options configurable + +2012-01-25 Jason Smith <jason.smith@canonical.com> + + start work to match upstream changes to pointer barrier work + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + start work of porting keynav to multi-monitor world + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + make sure we destroy launchers when we no longer need them + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + add launcher model tests + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + make alt-tab properly select based on viewport + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + fix issue where show desktop didn't show up when the switcehr is biased + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + add missing files + +2012-01-24 Jason Smith <jason.smith@canonical.com> + + merge trunk + +2012-01-23 Jason Smith <jason.smith@canonical.com> + + start tweaking in velocity (waiting for upstream changes to finalize) + +2012-01-20 Jason Smith <jason.smith@canonical.com> + + add autohide support to multi-monitor setups + +2012-01-18 Jason Smith <jason.smith@canonical.com> + + merge trunk + +2012-01-17 Jason Smith <jason.smith@canonical.com> + + port Launcher to AbstractLauncherIcon + +2012-01-17 Jason Smith <jason.smith@canonical.com> + + make sure we resize launchers appropriately when screen layout changes + +2012-01-17 Jason Smith <jason.smith@canonical.com> + + merge trunk + +2012-01-16 Jason Smith <jason.smith@canonical.com> + + make arrow indicators accurately reflect monitor counts in multi-monitor setups + +2012-01-16 Jason Smith <jason.smith@canonical.com> + + first attempt at multi-monitor launcher support + +2012-01-29 Thomi Richards <thomir@gmail.com> + + Added the PanelController to the Introspectable tree. This allows us to write AP tests for panel indicators etc. + + Fixed a bug in Introspectable which sometimes caused a crash when Unity shut down, due to the fact that Introspectable was holding stale pointers to parents.. Fixes: . Approved by Jason Smith. + +2012-01-30 Thomi Richards <thomi.richards@canonical.com> + + Fixed a few things from MP review. + +2012-01-20 Thomi Richards <thomir@gmail.com> + + Added a warning to stop people overriding Introspectable::GetChildsName() without cause. + +2012-01-20 Thomi Richards <thomir@gmail.com> + + Removed instances where people were overriding the childs name in the introspection tree for no good reason. + +2012-01-20 Thomi Richards <thomir@gmail.com> + + Shell now adds panel controller to introspection tree. + +2012-01-20 Thomi Richards <thomir@gmail.com> + + PanelController is now an introspectable object. + +2012-01-20 Thomi Richards <thomir@gmail.com> + + Fixed a bug that would cause unity to crash sometimes on exit due to Introspectable keeping stale pointers to parents. + +2012-01-27 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Improved the Super+Tab switcher making possible to escape from it using the Esc key and making the selection circular. + + This branch mostly fixes bug #919018 and bug #919019 as requested by design on recent updates of the main bug #891620. Fixes: https://bugs.launchpad.net/bugs/891620, https://bugs.launchpad.net/bugs/919018, https://bugs.launchpad.net/bugs/919019. Approved by Sam Spilsbury. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests, SuperTab: added more manual tests for circular switcher and escaping. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: ignore the Escape key when looking for shortcuts. + + This also avoids the shortcut-hint to be hidden when pressing Escape + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: don't consider the Escape key as releasing the Super key + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: add the EnableCancelAction utility function + + It allows to enable or disable the Escape action. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: Cancel the Launcher KeySwitcher on Escape and on ButtonPress + + Also now we actually use the terminate callback fuction. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Launcher: add KeySwitcherCancel function to terminate the switcher without effects + +2012-01-19 3v1n0 <mail@3v1n0.net> + + Launcher: make the Super+Tab circular. + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + Adds a testcase for 922447. Fixes: . Approved by Jason Smith. + +2012-01-28 smspillaz <sam.spilsbury@canonical.com> + + Added a case for different monitor layouts + +2012-01-27 smspillaz <sam.spilsbury@canonical.com> + + Merge lp:~unity-team/unity/unity.fix-fbo-viewport + +2012-01-27 Jason Smith <jason.smith@canonical.com> + + fix viewport calculation + +2012-01-27 Michal Hruby <michal.mhr@gmail.com> + + Coalesce results coming from the background icon loader threads, so we don't update the UI after each icon loaded.. Fixes: . Approved by Mirco Müller. + +2012-01-26 Michal Hruby <michal.mhr@gmail.com> + + Coalesce results from the IconLoader, so we don't repaint the UI after each result + +2012-01-26 Mirco Müller <mirco.mueller@ubuntu.com> + + Remaining issues for LP: #863246 (and also LP: #863240) fixed. + + See example screenshots of the after-state here: + http://people.canonical.com/~mmueller/fix-863246-863240-1.png + http://people.canonical.com/~mmueller/fix-863246-863240-2.png + http://people.canonical.com/~mmueller/fix-863246-863240-3.png + http://people.canonical.com/~mmueller/fix-863246-863240-4.png + + Alignments, margins, colors, opacities, artwork fixed for buttons, separators, outlines, text and expander-arrows. + + One glitch remaining is the separator-rendering being too thick/missing occasionally (on some systems). A solution for fixing this, is available. It's reverted in this branch, as some blending issues with this remain. But that can be added afterwards, to avoid all the other fixes being blocked on just that.. Fixes: https://bugs.launchpad.net/bugs/863246. Appoved by Andrea Azzarone, Andrea Cimitan. + +2012-01-26 Mirco Müller <mirco.mueller@ubuntu.com> + + Use unnamed namespace instead of static variable declaration + +2012-01-26 Mirco Müller <mirco.mueller@ubuntu.com> + + Tweak the outline-opacity as per request, make sure the top/bottom-padding for the ratings-widget is 12px also + +2012-01-26 Mirco Müller <mirco.mueller@ubuntu.com> + + Remove the layout debug-rects + +2012-01-26 Mirco Müller <mirco.mueller@ubuntu.com> + + Revert the separator-drawing to the Draw2DLine approach for now, make sure the filter-results text is the same size as the filter-genre caption-text + +2012-01-25 Mirco Müller <mirco.mueller@ubuntu.com> + + Don't forget about the removal of the separator when getting rid of a filter + +2012-01-25 Mirco Müller <mirco.mueller@ubuntu.com> + + Use a TextureArea as part of the filter-layout for drawing the separators between filter-categories + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Replace text-based expander-arrow with correct image-file based artwork from Design, tweak outline highlight-opacity for selected buttons + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Fix right edge alignment for all-, toggle- and multirange-buttons. + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Padding gap between adjacent filter-categories is always 12px now thus complying with the Design + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Fix vertical padding to be 12px between All-button and previous separator line + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Fix vertical padding to be 12px between All-button and first button of filters + +2012-01-23 Mirco Müller <mirco.mueller@ubuntu.com> + + Fix position of filter-expander heading, solve issue with trailing separators in filters + +2012-01-20 Mirco Müller <mirco.mueller@ubuntu.com> + + fixed all-button size, disabled debug-rects for the moment + +2012-01-19 Mirco Müller <mirco.mueller@ubuntu.com> + + Add colored debug-rectangles, remove drawing of trailing separator lines + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Add FavoriteStore external change support.. Fixes: https://bugs.launchpad.net/bugs/681503. Appoved by Mirco Müller. + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Don't pessimize prematurely. + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2012-01-18 Andrea Azzarone <azzaronea@gmail.com> + + Fix. + +2012-01-18 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2012-01-18 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Fix corner case. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Ops. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Add signals tests. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Clean up. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Add FavoriteStore external change support. + +2012-01-06 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2012-01-06 Andrea Azzarone <azzaronea@gmail.com> + + First step to fix bug #681503. + +2012-01-26 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Add support to middle-click pasting on the dash search bar. + + When the XA_PRIMARY clipboard has some content, that is pasted by middle click over the dash search bar. + This is for consistency with the rest of the system. + + I've also added the proper glib::Object support to the class.. Fixes: https://bugs.launchpad.net/bugs/842462. Appoved by Mirco Müller, Andrea Azzarone. + +2012-01-05 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry: always use glib:: namespace for casting + + To improve read-ability. + +2012-01-05 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry: some more code cleanup. + +2012-01-05 Marco Trevisan (Treviño) <mail@3v1n0.net> + + No need to initialize empty glib::Object. + +2012-01-05 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry IM shouldn't be enabled to allow paste-by-middle-click. + +2012-01-03 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Dash: added middle-click manual test. + +2012-01-03 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry: don't crash when there's no text to paste. + +2012-01-03 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry: moving to glib::Object + +2012-01-03 Marco Trevisan (Treviño) <mail@3v1n0.net> + + IMTextEntry: add support for middle-click over the dash search bar to paste content. + + When middle-clicking over the dash search bar, the XA_PRIMARY keyboard content is pasted + in the search box and the cursor position get updated. + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Window auto-maximise functionality should be disabled on monitors with a resolution above 1024 x 600.. Fixes: https://bugs.launchpad.net/bugs/797808. Appoved by Mirco Müller, Marco Biscaro. + +2012-01-18 Andrea Azzarone <azzaronea@gmail.com> + + Add a manual test. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2012-01-07 Andrea Azzarone <azzaronea@gmail.com> + + Disables window auto-maximise functionality if the monitor resolution is greater then 1024x600. + +2012-01-26 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Replace the Unity home screen tiles with a "merged lens view" where lenses can contribute any categories they see fit. + + settings: introduced a new gsettings key in the com.canonical.Unity.Dash namespace that controls the order of the results on the home screen. We should consider in a later branch having the sorting logic in FilesystemLenses also use this key (still falling back to alphabetical sorting when nothing is set). It empowers users and OEMs to override the default view on the homescreen by putting custom stuff first. + + libunity-core: Added a HomeLens class that implements Lens and Lenses interfaces. The typical use case is to add a FilesystemLenses to the HomeLens which will make it automatically merge all lenses found on the fs. In testing we implement custom Lenses instances and add those to the HomeLens in stead. + + unityshell: Removed the tiled homescreen and use a bog standard LensView to render the HomeLens in stead. Fixed a bunch of places where we assumed that Lenses' categories were always only appended to. This is no longer true with the HomeLens. Also important: Fix the SetViewType() calling semantics to the lenses when showing/hiding the dash and when switching between the lenses. + + Testing it out: + For this branch to work you need also: lp:~kamstrup/unity-lens-applications/home-lenses, lp:~kamstrup/unity-lens-files/home-lenses, and lp:~mhr3/unity-lens-music/home-lenses. Add to that latest bamf. Without these you will not see the correct results. + + To validate the results: Make sure that bringing up the dash resets the search and shows you a default view with exactly 3 categories in this order: Recent Apps, Recent Files, and Downloads. Then do a search and validate that you have exactly 3 categories in this order Applications, Files & Folders, and Music. + + Finally; launch an app that is not a favorite, then bring up the bring up the dash home screen and assert that the running app is *not* in the recent apps category (but showing in the launcher). Then close the app and bring up the dash again. The app should now show under Recent Apps. + + Design review: + Home screen without search: https://bugs.launchpad.net/unity/+bug/885738/+attachment/2690636/+files/unity-home-lens-design-review-1.png + Home screen with search: https://bugs.launchpad.net/unity/+bug/885738/+attachment/2690639/+files/unity-home-lens-design-review-2.png. Fixes: https://bugs.launchpad.net/bugs/885738, https://bugs.launchpad.net/bugs/914759. Appoved by Michal Hruby. + +2012-01-26 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-26 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Use glib::String to simplify mem management in HomeLens + +2012-01-26 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add automatic std::string conversion to glib::String + +2012-01-25 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Clear search entry when Esc is pressed - and close it if we have no search string. + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Implement search state retention policy for the home lens as specified in https://bugs.launchpad.net/unity/+bug/914759 + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Re-add unity.pot. It seems to have been removed by some freak accident in r1832 of this branch + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Remove PlacesHomeView.cpp from POTFILES.in + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Remove HomeView.{cpp,h} and PlacesHomeView.{cpp,h} now that they have been obsoleted by the HomeLens class. Check them diffstats, ma'! + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + From the review: Make the destructor for the Lens class virtual + +2012-01-24 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + From the review: Make the Model<RowAdaptor> constructors call into a shared Init() method to make sure we don't forget to initialize some of the properties (in particular one variant of the constructor wasn't setting a getter on the 'model' property) + +2012-01-23 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Revert changes to .po files + +2012-01-23 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add some tests for the category merging in HomeLens and fix a bug that it turned up (when different lenses registered cats with the same display name we screwed up the offsets) + +2012-01-23 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Some refactoring in the HomeLens tests + +2012-01-23 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add some tests to the HomeLens that actually executes a search. More in depth validation of the results to come. This required that I added some more convenience helpers to test_utils.h + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make the Lens.search_in_global properly actually writable as per declaration. We need that for tests. + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix small memleak in HomeLens. Initialize source category models up fron if they are preloaded with data. + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + More tests for HomeLens + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + More tests for HomeLens + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Start writing unit tests for the HomeLens class + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Whitespace fixes in tests/CMakeLists.txt + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Implement on-the-fly recalibration of merged category offsets if the categories are resorted in HomeLens (typically imposed by the external sorting of lenses vie the gsettings key). This fixes the crashers I was talking about earlier. They were caused by Result instaces pointing to incorrect categories + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add todo item - // FIXME: Coordinated sorting between the lens bar and home screen categories. Make void FilesystemLenses::Impl::DecrementAndCheckChildrenWaiting() use the gsettings key + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + WIP: Sort categories on the home screen according to their sorting order defined in the gsettings key "com.canonical.Unity.Dash/home-lens-ordering". + + NOTE: This required some bug fixing in LensView.cpp and there are still bugs (crashers) a plenty. Although, the initial view renders correctly, as soon as you change the search we get a crash. The problem seems to be that everything in the rendering has been written with the assumption that lenses will only ever *append* to the categories model. The HomeLens breaks this assumption (and can not even in theory be made to work that way) + +2012-01-20 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add gsettings schema com.canonical.Unity.Dash which holds a key to specify lens sorting (FIXME: how do we sort the entries in the lens bar, perhaps we should really respect those in stead?) + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Whitespace fixes in gsettings schema + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make HomeLens constructor take i18n strings so we don't have to add i18n to libunity-core. Remove some unsused variables and confusing code. Simplify setting of search_hints in the search entry now that we have a proper i18n hint. + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + W00t! Sort out the whole SetViewType mess in the dash. Sometimes we were spamming change messages other times we remained silent about important ones. + + This was one tricky one. Should be correct now. + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Implement glib::DBusProxy::IsConnected() and add some guards checking this in the unity::dash::Lens class + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Emit search_changed from HomeLens when all running global searches in normal lenses have completed + +2012-01-19 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make sure we actually set ViewType::HIDDEN when we're hiding lenses + +2012-01-18 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-18 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add another FIXME so I don't forget + +2012-01-18 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Update FIXMEs + +2012-01-18 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Don't show filters in the HomeLens + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Some simplifications and debugging + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix arguments of HomeLens::Impl::EnsureCategoryAnnotation() being inverted which resulted in a cascade of errors. + + Stricter error checking and more useful debug logging. + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Merged gord's lp:~gordallott/unity/dashview-renderer-refactoring + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Implement Activate() and Preview() for the HomeLens + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-16 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Sync with trunk + +2012-01-16 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add some TODOs for the HomeLens + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Remove a noisy debugging statement + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix a double free of a gvariant - the one we replace in the merged results model to fix the offsets into the merged category model + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix a divide-by-zero in ResultViewGrid that were spraying SIGFPEs in my general direction. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make sure we use the results models to generate category ids in all cases. We were mixing it up. This required some closure magic in order not to get out of hand logic-wise; because they enable us to capture the locals that we need in the async context. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + More elaborate debugging and erro output in HomeLens. Also fix an unsigned int "under flow" where we passed in -1. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make Lens subclassable by making GlobalSearch(), Search(), Activate(), and Preview() virtual; and override these methods in HomeLens. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Add a remark to HACKING explaining how to enable debug logging + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + The big switch! Change the HomeView to a normal LensView backed by the new HomeLens class. Segfaults a plenty. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Improve debugging statements in Lens.cpp + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix linker errors caused by missing implementations of constructors for ResultsMerger and CategoryMerger + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Wire up the (hairy) logic to merge categories and results correctly in the HomeLens + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Implement row-removed and row-changed signal handling for HomeLens::ModelMerger. + +2012-01-13 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Wire up categories- and filters models in HomeLens. Document the logic in EnsureRowBuf(). + +2012-01-12 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + WIP Start writing a ModelMerger class that will be responsible for backing the models of the HomeLens with the data from all the loaded lenses + +2012-01-12 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + WIP Start implementing a HomeLens class in UnityCore that extends the Lens class. The plan is to use it to make home screen rendering use stock lens rendering mechanisms + +2012-01-11 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Show default global search results instead of tiles in the home view. In order to get lenses up we initialize them when we're about to show. + +2012-01-11 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Fix compilation of the stand alone Dash example + +2012-01-26 3v1n0 <mail@3v1n0.net> + + Fixed the logical interaction between lp:~3v1n0/unity/super-tab-switcher and lp:~andyrock/unity/shortcut-hint as defined by design. + + Plus, some code improvements and fixed an issue that caused the shortcut hint to show when pressing Super and clicking over the BFB to show the dash. + + I'm wondering if we should avoid the same also when pressing over the workspace switcher.. Fixes: https://bugs.launchpad.net/bugs/918453. Appoved by Andrea Azzarone, Tim Penhey. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityScreen: use ubus_manager_ also to send messages. + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + ShortcutController: always use UBusWrapper (also for sending messages) + +2012-01-15 3v1n0 <mail@3v1n0.net> + + No commit message +2012-01-15 3v1n0 <mail@3v1n0.net> + + UnityScreen: fixing indentation + +2012-01-15 3v1n0 <mail@3v1n0.net> + + ShortcutController: always hide the shortcut-overlay when the dash is opened. + +2012-01-15 3v1n0 <mail@3v1n0.net> + + manual-tests: SuperTab, added test for the interaction with the overlay + +2012-01-15 3v1n0 <mail@3v1n0.net> + + ShortcutController: animators doesn't need to be dinamically allocated. + +2012-01-15 3v1n0 <mail@3v1n0.net> + + ShortcutController: use UBusWrapper to manage interests + +2012-01-15 3v1n0 <mail@3v1n0.net> + + UnityScreen: always use UBusManager + +2012-01-14 3v1n0 <mail@3v1n0.net> + + UnityScreen: disable the shortcut only if a "standard" key is pressed + + This is done not to make the overlay to show when Super+Tab is used. + We need an idle, since the overlay activation is done after handleEvent + is called. + +2012-01-14 3v1n0 <mail@3v1n0.net> + + ShortcutController: allow to be enabled and disabled, and disable it on Super-Tab + + When the launcher key-navigation is activated and the shortcut hint has + still not been shown, the shortcut hint should be disabled. + +2012-01-26 Andrea Azzarone <azzaronea@gmail.com> + + Should use GTK_IS_MENU instead GTK_MENU. Fixes: . Appoved by Michal Hruby. + +2012-01-26 Andrea Cimitan <andrea.cimitan@canonical.com> + + Fixes potential crashes + +2012-01-23 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2012-01-23 Andrea Azzarone <azzaronea@gmail.com> + + Updates test_lens.cpp + +2012-01-22 Andrea Azzarone <azzaronea@gmail.com> + + Auto selects the All button if all the CheckOptionButtons are selected. + +2012-01-25 David Planella <david.planella@ubuntu.com> + + - Change 'Rubbish Bin' to 'Trash' in the Unity shortcuts hints overlay + + From bug 920529: + + In all the software we ship in Ubuntu we use American English (en-US) messages as the source for translations. These can then be translated to any language or variant, such as British English (en-GB). + + In the Unity shortcuts hints overlay, the current message (for the want of a better name) for the place where discarded files go is "Rubbish Bin", which is the en-GB version. + + In order to be consistent with the rest of the desktop and with the translations, the original message should refer to "Trash", which can then be translated to "Rubbish Bin" in en-GB and will allow the right translation to be shown in the user's desktop for their chosen locales. + + It might seem a trivial issue, but those involved in bug 406626, its duplicates and follow-ups will remember that it's a sensitive topic.... Fixes: https://bugs.launchpad.net/bugs/920529. Appoved by John Lea, Tim Penhey. + +2012-01-23 David Planella <david.planella@ubuntu.com> + + Changed 'Rubbish Bin' to 'Trash' - the translatable messages' source locale should be en-US + +2012-01-25 Thomi Richards <thomir@gmail.com> + + Added 'Debug Unity Introspection Tree' script (duit.py). Use this to quickly discover what information is available in the introspection tree.. Fixes: . Appoved by Tim Penhey, Sam Spilsbury, Alex Launi. + +2012-01-24 Thomi Richards <thomi.richards@canonical.com> + + Now prints a more friendly message if it can't find the autopilot module. + +2012-01-24 Thomi Richards <thomi.richards@canonical.com> + + Moved duit script into tools/ folder, and made the name more explicit. + +2012-01-24 Thomi Richards <thomi.richards@canonical.com> + + PEP8 fixes. + +2012-01-23 Thomi Richards <thomi.richards@canonical.com> + + Whitespace fix. + +2012-01-23 Thomi Richards <thomi.richards@canonical.com> + + Now uses a proper font-face ;) + +2012-01-19 Thomi Richards <thomir@gmail.com> + + Finished writing the 'Debug Unity Introspection Tree' script. + +2012-01-19 Thomi Richards <thomir@gmail.com> + + Clean ups, and make node shape rounded record. + +2012-01-19 Thomi Richards <thomir@gmail.com> + + Output works. + +2012-01-19 Thomi Richards <thomir@gmail.com> + + duit now uses pydot only. + +2012-01-19 Thomi Richards <thomir@gmail.com> + + First version of duit + +2012-01-25 Brandon Schaefer <brandontschaefer@gmail.com> + + Just refactoring, and removing unused variable to clean up valgrind results. + + Covered by existing tests.. Fixes: . Appoved by Tim Penhey. + +2012-01-24 Brandon Schaefer <brandontschaefer@gmail.com> + + Changed variable name from it to icon_it because it isn't an itertor but a refrence to an icon + +2012-01-24 Brandon Schaefer <brandontschaefer@gmail.com> + + Missed removing unsued iterator + +2012-01-24 Brandon Schaefer <brandontschaefer@gmail.com> + + Changed 2 more for loops to use range based instead + +2012-01-23 Brandon Schaefer <brandontschaefer@gmail.com> + + Removed un used vars and changed for loops to use range based + +2012-01-23 Brandon Schaefer <brandontschaefer@gmail.com> + + Fixed uninitialized variables. + +2012-01-25 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + Desktop safe OpenGL ES 2.0 branch from Linaro's Graphics WG + - This branch protects OpenGL ES 2.0 specific code with a build time option (BUILD_GLES) + - The branch does not affect the runtime execution of Unity on the desktop if BUILD_GLES is not activated + + Authors: + alexandros.frantzis@linaro.org + marc.ordinasillopis@linaro.org + . Fixes: . Appoved by Jay Taoko, Jason Smith. + +2012-01-25 Jay Taoko <jay.taoko@canonical.com> + + * Merged into Unity trunk + +2012-01-24 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + Desktop safe OpenGL ES 2.0 branch from Linaro's Graphics WG + - This branch protects OpenGL ES 2.0 specific code with a build time option (BUILD_GLES) + - The branch does not affect the runtime execution of Unity on the desktop if BUILD_GLES is not activated + + Authors: + alexandros.frantzis@linaro.org + marc.ordinasillopis@linaro.org + +2012-01-24 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + GLES2: Fix gles2 compilation in unity-mt-grab-handles. + +2012-01-23 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + GLES2: Fix GLES conditional in CMakeLists.txt. + +2012-01-20 Marc Ordinas i Llopis <marc.ordinasillopis@linaro.org> + + GLES2: Make GLES2 build compile. + +2012-01-20 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + GLES2: Fixed shader header definitions in the IconRenderer port. + +2012-01-20 Marc Ordinas i Llopis <marc.ordinasillopis@linaro.org> + + GLES2: Ported changes to plugins/unityshell/src/IconRenderer.cpp. + +2012-01-20 Alexandros Frantzis <alexandros.frantzis@linaro.org> + + GLES2: Ported changes to plugins/unityshell. + +2012-01-19 Marc Ordinas i Llopis <marc.ordinasillopis@linaro.org> + + GLES2: Ported changes to files outside plugins/unityshell. + +2012-01-25 Tim Penhey <tim.penhey@canonical.com> + + Don't assign null to a std::string. Fixes: https://bugs.launchpad.net/bugs/865840. Appoved by Marco Trevisan (Treviño), Sam Spilsbury. + +2012-01-24 Tim Penhey <tim.penhey@canonical.com> + + Use the wrapper to avoid assigning null to a std::string. + +2012-01-25 Michal Hruby <michal.mhr@gmail.com> + + Move all icon loading into background gio threads. (there was mainly issue with gtk_icon_info_load_icon which is doing synchronous IO and noticeably blocks the UI when using some themes). Fixes: https://bugs.launchpad.net/bugs/828582. Appoved by Gord Allott, Sam Spilsbury. + +2012-01-23 Michal Hruby <michal.mhr@gmail.com> + + Add tests + +2012-01-19 Michal Hruby <michal.mhr@gmail.com> + + Make sure all the icon loading is done in non-main thread + +2012-01-25 Jason Smith <jason.smith@canonical.com> + + . Fixes: . Appoved by Neil J. Patel. + +2012-01-25 Jason Smith <jason.smith@canonical.com> + + fix build + +2012-01-23 Bilal Akhtar <bilalakhtar@ubuntu.com> + + This branch contains the first phase of the implementation of software-center integration with Unity. The complete spec on how it should be implemented, is located at: + https://wiki.ubuntu.com/SoftwareCenter#Learning_how_to_launch_an_application + + This branch brings the following changes: + 1) An app being installed is shown in the launcher with a tooltip "Waiting to install" + 2) A progress bar on the launcher item displays the download/install progress. + 3) When the app gets installed, the launcher items becomes usable, and the tooltip gets changed to the app name. + + Things which are still to be implemented, in the next phases: + 1) Animate the movement of the icon from the USC window to the Unity launcher. + 2) Make the launcher icon wiggle when installation is complete + 3) Stop the launcher icon from blinking when clicked in "waiting to install" state. + + In the meantime, you can merge this branch into Unity while I implement the remaining aspects + + Branch Testing instructions: + 1) Make sure Unity built from my branch is running. + 2) Get software-center from bzr branch lp:~gary-lasker/software-center/launcher-integration-lp761851 + 3) In the software center branch dir, run PYTHONPATH=. python ./software-center + 4) Make sure that in the software center View menu, "New Applications In Launcher" is CHECKED. + 5) Install a package using software-center that contains a desktop file (like gnome-color-chooser, gnome-mplayer or could be any package with a .desktop file) + 6) Watch the Unity launcher :-). Fixes: https://bugs.launchpad.net/bugs/761851. Appoved by Mikkel Kamstrup Erlandsen. + +2012-01-17 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix yet another g_strcmp0 + +2012-01-16 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Make minor changes as pointed out by Mikkel, thanks! + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix crash, icon of newly-created icon + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix persistance of launcher icons + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Major code cleanup, get progress bar to work + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Integrate SoftwareCenterLauncherIcon.* code back into the main Unity 5.0 source and fix build failures. + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix build failure + +2012-01-15 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Merge from trunk + +2011-09-05 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Massive code cleanup, still not able to solve a memory issue :( + +2011-09-05 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Use GLIbDBusProxy + +2011-09-05 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Trunkify yet again + +2011-09-04 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix some issues, thanks Neil! Still need to work out on GDBusProxy + +2011-08-19 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Merge from trunk + +2011-08-17 Bilal Akhtar <bilalakhtar@ubuntu.com> + + MEH. Fix conflicts + +2011-08-17 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Phase-1 integration complete + +2011-08-17 Bilal Akhtar <bilalakhtar@ubuntu.com> + + NEARLY THERE\! + +2011-08-17 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Get the value of Progress in the g-signal + +2011-08-16 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix segfault + +2011-08-16 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Make code less crappy, fix signals + +2011-08-14 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Listen to signals, fix properties proxy + +2011-08-10 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Can someone help me? + +2011-08-09 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix "undefined symbol" runtime error FOR GOOD + +2011-08-08 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Fix DBus property Get call. + +2011-08-08 Bilal Akhtar <bilalakhtar@ubuntu.com> + + DBussing all the way to the moon\! + +2011-08-07 Bilal Akhtar <bilalakhtar@ubuntu.com> + + Tons of underlying changes for better SC integration with Unity + +2012-01-20 Jay Taoko <jay.taoko@canonical.com> + + * Triggers a Unity build following Nux API change. Fixes: . Appoved by Jason Smith. + +2012-01-20 Jay Taoko <jay.taoko@canonical.com> + + * Trigger Unity build + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Make the launcher be aware of the window's workspace + + Fixed another part of bug #689733 that we were missing, making the launcher to count only the windows in the current workspace when drawing the left "pips". + + Also fixed the unity side of the bug #690143 to make the launcher to spread only the windows in the current workspace. + + Manual tests included.. Fixes: https://bugs.launchpad.net/bugs/689733, https://bugs.launchpad.net/bugs/690143. Appoved by . + +2012-01-20 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests: Launcher, removing old test. + +2012-01-19 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Merging again with trunk + +2012-01-15 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Merging with upstream + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests: added a test for spread windows in current workspace + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests: added test for launcher icon. + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PluginAdapter: some code cleanup + + Avoid extra computation of the VP, we already checked for that. + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + BamfLauncherIcon: spread only windows available on the current workspace. + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Merging with upstream + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + BamfLauncherIcon: show only windows on current workspace on the launcher pips + + The launcher icons should show only a number of "pips" equal to + the windows on the current workspace. + +2012-01-20 Didier Roche <didier.roche@canonical.com> + + kill any previous compiz process as it can hangs before --replace + (LP: #919132). Fixes: https://bugs.launchpad.net/bugs/919132. Appoved by Gord Allott. + +2012-01-20 Didier Roche <didier.roche@canonical.com> + + be without any mercy + +2012-01-20 Didier Roche <didier.roche@canonical.com> + + kill any previous compiz process as it can hangs before --replace (LP: #919132) + +2012-01-20 Daniel van Vugt <vanvugt@gmail.com> + + Fix SIGSEGV when a window is minimized. (LP: #918329) + + The crash was caused by 'minimizedWindows' leaking pointers to windows that had been deleted, and then later trying to dereference those pointers. The reason for the leak appears to be a reference leak in the boost::shared_ptr's to CompizMinimizedWindowHandler. Reverting to regular pointers avoids the reference leak, avoids the crash, and makes the code easier to understand (and debug). + + Detailed valgrind log showing the error: + https://bugs.launchpad.net/ubuntu/+source/unity/+bug/918329/comments/6. Fixes: https://bugs.launchpad.net/bugs/918329. Appoved by Sam Spilsbury. + +2012-01-20 Daniel van Vugt <vanvugt@gmail.com> + + Fix SIGSEGV when a window is minimized. (LP: #918329) + + The crash was caused by 'minimizedWindows' leaking pointers to windows that + had been deleted, and then later trying to dereference those pointers. The + reason for the leak appears to be a reference leak in the boost::shared_ptr's + to CompizMinimizedWindowHandler. Reverting to regular pointers avoids the + reference leak, avoids the crash, and makes the code easier to understand (and + debug). + +2012-01-19 Thomi Richards <thomir@gmail.com> + + Very small change that fixes valgrind warnings about uninitialised variables.. Fixes: . Appoved by Alex Launi. + +2012-01-19 Thomi Richards <thomir@gmail.com> + + Fixed a valgrind uninitialised variable warning. + +2012-01-19 Andrea Azzarone <azzaronea@gmail.com> + + Updates launcher icons shortcuts when removing icons from launcher.. Fixes: https://bugs.launchpad.net/bugs/914018. Appoved by Marco Biscaro. + +2012-01-10 Andrea Azzarone <azzaronea@gmail.com> + + Ops. + +2012-01-10 Andrea Azzarone <azzaronea@gmail.com> + + Update launcher shortcuts when removing icons from launcher. + +2012-01-19 Didier Roche <didier.roche@canonical.com> + + This branch does two things: + - dep on scale and wall after the discussion on bug #897697 + - alt-tab per workspace is the new default, from the design requirement. Fixes: https://bugs.launchpad.net/bugs/897697. Appoved by Sam Spilsbury. + +2012-01-19 Didier Roche <didier.roche@canonical.com> + + s/wall/expo as it's the one we wanted + +2012-01-19 Didier Roche <didier.roche@canonical.com> + + alt-tab per workspace is the new default, from the design requirement + +2012-01-19 Didier Roche <didier.roche@canonical.com> + + dep on scale and wall after the discussion on bug #897697 + +2012-01-19 Omer Akram <om26er@ubuntu.com> + + comment #27 bug 778256 + + "This bugfix got lost during the merge in revision 1361: http://bazaar.launchpad.net/~unity-team/unity/trunk/revision/1361 + It was fixed in revision 1228: http://bazaar.launchpad.net/~unity-team/unity/trunk/revision/1228 + The fix landed in June but this way it did not make it into Oneiric and is not part of the latest 5.0 release in Precise either. + Could any Ubuntu developer please check this out? It's a one liner change only.". Fixes: https://bugs.launchpad.net/bugs/778256. Appoved by Michal Hruby, Fitoschido. + +2012-01-19 Omer Akram <om26er@ubuntu.com> + + fix + +2012-01-15 Omer Akram <om26er@ubuntu.com> + + Re-apply the fix for bug 778256 which got lost in a major unity change. + +2012-01-19 Gord Allott <gord.allott@canonical.com> + + Adds alignment options in to DashStyle, only enabled for DashStyle::Button right now. Fixes: . Appoved by Mirco Müller. + +2012-01-19 Gord Allott <gord.allott@canonical.com> + + remove debugs + +2012-01-19 Gord Allott <gord.allott@canonical.com> + + enables alignment selection in DashStyle::Button + +2012-01-19 Daniel van Vugt <vanvugt@gmail.com> + + Log messages from unity should say "unity", not "glib" which is totally misleading (LP: #908004) + . Fixes: https://bugs.launchpad.net/bugs/908004. Appoved by Marco Trevisan (Treviño). + +2011-12-23 Daniel van Vugt <vanvugt@gmail.com> + + Log messages from unity should say "unity", not "glib" which is totally + misleading (LP: #908004) + +2012-01-19 Thomas Voß <thomas.voss@rub.de> + + Fixes a dependency issue for unity-mt-grab-handles. Fixes: . Appoved by . + +2012-01-19 Thomas Voß <thomas.voss@rub.de> + + Fixed dependency issue on nux-1 instead of nux-2. + +2012-01-19 Alex Launi <alex.launi@canonical.com> + + This test has been automated via an autopilot test.. Fixes: . Appoved by . + +2012-01-10 Alex Launi <alex.launi@canonical.com> + + Launcher test has been automated into an autopilot test + +2012-01-18 smspillaz <sam.spilsbury@canonical.com> + + Fixes LP bug 912682 + + glTexEnvMode was never reset to GL_REPLACE so GL_MODULE caused any texture with an alpha channel to draw without proper blending. Fixes: . Appoved by Jay Taoko. + +2012-01-19 smspillaz <sam.spilsbury@canonical.com> + + Reset the tex env mode to GL_REPLACE once we're done. Fixes LP#912682 + +2012-01-12 Sam Spilsbury <sam.spilsbury@canonical.com> + + Do gtk_init_check in unity + +2012-01-10 Sam Spilsbury <sam.spilsbury@canonical.com> + + Port to the new compiz API + +2012-01-18 Gord Allott <gord.allott@canonical.com> + + Converts the Launcher.cpp ubus handles into a ubus manager class, safer + Adds the LOCK_HIDE qurik into the hide machine, enables it when ubus calls it. Fixes: . Appoved by Jason Smith. + +2012-01-18 Gord Allott <gord.allott@canonical.com> + + fully working with LAUNCHER_HIDE_NEVER mode now + +2012-01-17 Gord Allott <gord.allott@canonical.com> + + Convert the launcher ubus work over to ubus manager and add the LOCK_HIDE quirk + +2012-01-18 Mirco Müller <mirco.mueller@ubuntu.com> + + Fourth of fifth time I fix my stuff after the stuff in trunk changed below my feet after it was approved... having a fun wasting time :/ + + "The actual unity-part of the fix for LP: #841902. It needs lp:~macslow/libunity/libunity.fix-841902 and lp:~macslow/unity-lens-music/unity-lens-music.fix-841902 to be merged first.". Fixes: . Appoved by Michal Hruby. + +2012-01-18 Mirco Müller <mirco.mueller@ubuntu.com> + + Oops + +2012-01-18 Mirco Müller <mirco.mueller@ubuntu.com> + + Fixing the the unity-part of my patch for LP: #841902 for the fourth of fifth time... after it got approved everytime before... seriously WTF + +2012-01-18 Michal Hruby <michal.mhr@gmail.com> + + Added new unity::glib::Variant class wrapping GVariant. This also fixes GVariant ref-counting issues when using std::map (or Lens::Hints, HintsMap, Filter::Properties etc.). Fixes: . Appoved by Gord Allott. + +2012-01-17 Michal Hruby <michal.mhr@gmail.com> + + Get rid of the Utils class, move the functionality to Variant + +2012-01-17 Michal Hruby <michal.mhr@gmail.com> + + Make sure Variant::GetString doesn't blow up + +2012-01-17 Michal Hruby <michal.mhr@gmail.com> + + Added unity::glib::Variant wrapper + +2012-01-17 Mirco Müller <mirco.mueller@canonical.com> + + Fixes the position, alignment, spacing and arrow-artwork for the "Filter results". See... + + http://people.canonical.com/~mmueller/fix-863240.png. Fixes: https://bugs.launchpad.net/bugs/863240. Appoved by Gord Allott. + +2012-01-17 Mirco Müller <mirco.mueller@ubuntu.com> + + Correct right gap between expander-arrow and inner Dash edge to be 14 px + +2012-01-11 Mirco Müller <mirco.mueller@canonical.com> + + Fix vertical expander-arrow position with an insane nux-layout setup + +2012-01-11 Mirco Müller <mirco.mueller@canonical.com> + + Make Filter-text follow right edge when dash is expanded to fullscreen + +2012-01-11 Mirco Müller <mirco.mueller@canonical.com> + + Add callback to expander-arrow, fix initial display of just the expander-arrow + +2012-01-11 Mirco Müller <mirco.mueller@canonical.com> + + Disabled colored debug-rectangles, make it flush to the right + +2012-01-11 Mirco Müller <mirco.mueller@canonical.com> + + First set of fixes for patching LP: #863240 + +2012-01-17 Gord Allott <gord.allott@canonical.com> + + Re-factors the dash rendering into its own OverlayRenderer class, doesn't add new code above that so should be fairly sane. . Fixes: . Appoved by Mikkel Kamstrup Erlandsen, Michal Hruby. + +2012-01-17 Gord Allott <gord.allott@canonical.com> + + merged with latest trunk, fixed kamstrupflicts + +2012-01-16 Gord Allott <gord.allott@canonical.com> + + make kamstrup happy by adding a comment on the unique pointer reasoning + +2012-01-16 Gord Allott <gord.allott@canonical.com> + + hook up the abouttoshow/hide mechanic + +2012-01-16 Gord Allott <gord.allott@canonical.com> + + integrated the OverlayRenderer class in to DashView + +2012-01-16 Gord Allott <gord.allott@canonical.com> + + merged in standalone-clients fix from trunk + +2012-01-16 Gord Allott <gord.allott@canonical.com> + + First stab at overlay renderer class + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make standalone-clients/dash actually compile. Fixes: . Appoved by Gord Allott. + +2012-01-17 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> + + Make standalone-clients/dash actually compile + +2012-01-17 Michal Hruby <michal.mhr@gmail.com> + + Dispatch search to lenses faster and add a timeout for animating the spinner (otherwise it would just flicker now).. Fixes: . Appoved by Mikkel Kamstrup Erlandsen, Mirco Müller. + +2012-01-16 Michal Hruby <michal.mhr@gmail.com> + + Be more verbose when something is wrong with a DBus call + +2012-01-16 Michal Hruby <michal.mhr@gmail.com> + + Decrease the timeout used for dispatching searches to lenses and introduce timeout which starts the spinner animation + +2012-01-16 Omer Akram <om26er@ubuntu.com> + + revert the bad looking panel branch. the real fix is still being worked on and may take a while.. its for bug 839480. Fixes: . Appoved by Andrea Azzarone. + +2012-01-16 Omer Akram <om26er@ubuntu.com> + + revert bug 839480 + +2012-01-16 Omer Akram <om26er@ubuntu.com> + + merge + +2012-01-16 Didier Roche <didier.roche@canonical.com> + + Removing unexisting file in potfiles.in. Seems enough to make it build + there. Fixes: . Appoved by Michal Hruby, Gord Allott. + +2012-01-16 Didier Roche <didier.roche@canonical.com> + + removing unexisting file from POTFILES.in + +2012-01-16 Jay Taoko <jay.taoko@canonical.com> + + * Fix Nux calls in standalone-clients test.. Fixes: . Appoved by Gord Allott. + +2012-01-15 Jay Taoko <jay.taoko@canonical.com> + + * Fix Nux calls in standalone-clients test. + +2012-01-15 3v1n0 <mail@3v1n0.net> + + Fixed bug #891620 to support the Super+Tab switcher. + + Added a new launcher key switcher that matches design bug #891620, the key bindings are set to default to Super+Tab and Super+Shift+Tab by default, but they can be changed from compiz settings. + + I've added some new functions to Launcher to manage the KeySwitcher and others to share the code between the switcher and the key navigation.. Fixes: https://bugs.launchpad.net/bugs/891620. Appoved by . + +2012-01-14 3v1n0 <mail@3v1n0.net> + + Merging with upstream. + +2012-01-13 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Super+Tab manual-test: fixed a typo. + +2012-01-13 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Updated the manual test + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests: Added test for Super-Tab switcher + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + UnityAccesibile: register interest for launcher on key-switcher. + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Launcher: added UBUS support for KeySwitcher. + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Launcher: add SelectPreviousIcon() and SelectNextIcon() to factorize code + + This code can be shared both by the key navigation and by the Super+Tab + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + unityshell: launcher swticher code cleanup. + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + SuperTab, rename it to Launcher Key Switcher, as the keybinding can change + +2012-01-07 Marco Trevisan (Treviño) <mail@3v1n0.net> + + unityshell, Launcher: add first support for Super+Tab launcher switcher + + This is a first draft, but working super+tab swtiching, it allows + to select windows from the launcher and to activate them when releasing + the defined keybinding. + +2012-01-13 Andrea Azzarone <azzaronea@gmail.com> + + Display a shortcut hints overlay during the super key pressing. + + It includes two unit tests and a standalone test. + + Mockup: https://launchpadlibrarian.net/85352653/Super_key_shutcuts_overlay.png + Branch: http://ubuntuone.com/7cqBbWAbvXTRCT4ySFj7z4 + + Visual diff: http://ubuntuone.com/014zDKCoxaQYmtm8mS5pp8 + + Keep in mind that something is different because the shortcuts values are not hardcoded.. Fixes: https://bugs.launchpad.net/bugs/855532. Appoved by Marco Trevisan (Treviño), John Lea, Tim Penhey. + +2012-01-13 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Center it in the screen. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Close the dash on super press. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Add COMPIZ_MOUSE_OPTION + +2011-12-19 Andrea Azzarone <azzaronea@gmail.com> + + Uses proper case for shortcut hints. Tests it too. + +2011-12-16 Andrea Azzarone <azzaronea@gmail.com> + + Try to make it as pixel perfect as possible. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Ops. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Updates shortcut hints list. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Show the shortcut in the primary monitor with the right alignment. Don't show the overlay if it doesn't fit in the monitor. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Fixes padding. + +2011-12-13 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-13 Andrea Azzarone <azzaronea@gmail.com> + + Hide the shortcuts overlay when a key is pressed. + +2011-12-13 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-11 Andrea Azzarone <azzaronea@gmail.com> + + Fix typo. + +2011-12-10 Andrea Azzarone <azzaronea@gmail.com> + + Updates the shortcuts window if a shortcut option changes. + +2011-12-10 Andrea Azzarone <azzaronea@gmail.com> + + Fix standalone test. + +2011-12-10 Andrea Azzarone <azzaronea@gmail.com> + + Add a quick fade in/out animation. + +2011-12-09 Andrea Azzarone <azzaronea@gmail.com> + + Layout processing is slown, so it doesn't create the shortcut overlay every single time. + +2011-12-09 Andrea Azzarone <azzaronea@gmail.com> + + Add bold to the titles. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + Unregister dbus interest after controller destruction. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + Jay's work merged. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + Fixes FixShortcutFormat and fixes it. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + Const const const. + +2011-12-08 Andrea Azzarone <azzaronea@gmail.com> + + First draft of a function to fix shortcut format. + +2011-12-07 Andrea Azzarone <azzaronea@gmail.com> + + Moves ctor and copy ctor in the abstract class. + +2011-12-07 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-05 Andrea Azzarone <azzaronea@gmail.com> + + First draft of a shortcuts hint overlay... + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Since the bug LP: #863246 states so many issues, I'm splitting up the work into a series of branches/fixes. This first part corrects pixel-grid alignment of selected/unselected button-outlines, opacity-values (outline, filling) and vertical and horizontal spacing between buttons. + + Here are a few screenshots/screencast showing this first set of improvements: + + http://people.canonical.com/~mmueller/fix-863246-part-1.png + http://people.canonical.com/~mmueller/fix-863246-part-4.png + http://people.canonical.com/~mmueller/fix-863246-part-5.ogv. Fixes: https://bugs.launchpad.net/bugs/863246. Appoved by Andrea Azzarone. + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Jenkins reported conflicts... merged with branch again and solved conflicts... *sigh³* + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Fixed the vertical and horizontal spacing between buttons to comply with the design + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Fix pixel-grid alignment of curved parts of the multi-range widgets outline + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + more value tweaking of opacities to fit the design + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Fix pixel-grid alignment of selected/unselected button-outline, corrected outline color-opacity according to design + +2012-01-12 Mirco Müller <mirco.mueller@canonical.com> + + Align outline of selected multirange-widget elements to pixel-grid + +2012-01-12 Mirco Müller <mirco.mueller@canonical.com> + + Fixed the pixel-grid alignment of the outline of the unselected multirange-widget/buttons + +2012-01-13 Andrea Azzarone <azzaronea@gmail.com> + + Dash filters fixes.. Fixes: https://bugs.launchpad.net/bugs/838901, https://bugs.launchpad.net/bugs/841864, https://bugs.launchpad.net/bugs/841870. Appoved by Tim Penhey, Michal Hruby. + +2012-01-11 Andrea Azzarone <azzaronea@gmail.com> + + Keep in consideration collapsed property. + +2012-01-10 Andrea Azzarone <azzaronea@gmail.com> + + Strips trailing spaces. + +2012-01-10 Andrea Azzarone <azzaronea@gmail.com> + + Makes the FilterWidget inherit from nux::View. + +2012-01-09 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2012-01-09 Andrea Azzarone <azzaronea@gmail.com> + + Uses dash style json file to disable prelight state. + +2011-12-20 Andrea Azzarone <azzaronea@gmail.com> + + Uses nux::ObjectPtr in FilterExpanderLabel + +2011-12-20 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Adds manual tests. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Style fixes. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + Fix rating stars padding. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Merge trunk. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Fixes #841870. Don't use SetVisibile on a Layout, nux doesn't like it. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Fixes. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Add FilterAllButton class too. + +2011-12-15 Andrea Azzarone <azzaronea@gmail.com> + + Fixes "All" button behaviour. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Updates dash filters coding style. + +2011-12-14 Andrea Azzarone <azzaronea@gmail.com> + + Merge lp:~yeganeh/unity/fix-for-838901 + +2011-10-06 Zaid Yeganeh <zaid.yeganeh@gmail.com> + + [unityshell] Removed the 'prelight' state that is used on mouse overs + + modified: + plugins/unityshell/src/FilterBasicButton.cpp + plugins/unityshell/src/FilterBasicButton.h + +2012-01-13 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Making unity be aware of user-invisible windows, and manage them correctly. + + Fixed bug #784804, but after a discussion with Jason I followed his guidelines to get the things fixed. + Basically now user-invisible windows (i.e. the ones with the skip-taskbar flag) are ignored by unity unless they don't belong to a sticky application. In that case the application is shown as running, but clicking on it makes the application to run a new instance (while the alt+tab allows to select the user-invisible windows). + When an application as both user visible and invisible windows, clicking on the launcher icon or the alt+tab gives priority to the visible windows when bringing them to focus, while when closing all the visible windows, the application is hidden from launcher and alt+tab unless it's sticky (and in this case it behaves as explained above). + Also the user-invisible windows, never increment the count of the running windows (i.e. the launcher "pips"). + + Read more cases in the provided manual-tests. + + This branch also fixes the management of the urgent windows, that with some latest commits were not managed anymore as they should (now they get again priority when the parent application is focused).. Fixes: https://bugs.launchpad.net/bugs/784804. Appoved by Mirco Müller. + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-tests: added test for UserInvisibleWindows + +2012-01-06 Marco Trevisan (Treviño) <mail@3v1n0.net> + + BamfLauncherIcon: manage user-invisible windows + + Windows that have the skip-taskbar flag shouldn't be managed by + unity unless there's another user-visible window of the given application + mapped or the application is pinned. + + Also, when performing a click over a launcher icon, if it has currently + opened only non-visible windows, the application is launched, otherwise + we give priority to the user visible windows bringing to focus just them + (this doesn't happen in the case of the Alt+Tab). + + When an application with user-invisible windows is closed, we show it + on the launcher only if that is pinned. + +2012-01-13 Marco Trevisan (Treviño) <mail@3v1n0.net> + + Update the top panel title with the current alt+tab focused application title. + + Fixed bug #855516, using ubus messages to make the switcher notify of events.. Fixes: https://bugs.launchpad.net/bugs/855516, https://bugs.launchpad.net/bugs/913889. Appoved by Mirco Müller. + +2012-01-12 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: added the "paranoia"-checks ;) + +2012-01-10 Marco Trevisan (Treviño) <mail@3v1n0.net> + + manual-test: added Panel manual test for Alt+Tab interaction + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: set the show-now delay to the previous value. + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: set show_now as disactive when showing the switcher. + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: reduce the risk of not hiding the menus. + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: update the mouse position when the switcher has been hidden + + Since the switcher grabs the pointer, we need to update the mouse position + to check if the the pointer is over the panel or not. + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: Never shows menus or window buttons when the switcher is showing + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: use a vector instead of signal guint values to save ubus interests + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + PanelMenuView: be aware of the switcher status and update the title on switcher changes + + This fixes bug #855516, making the Alt+Tab switcher to update the unity + panel title. + +2012-01-08 Marco Trevisan (Treviño) <mail@3v1n0.net> + + SwitcherController: send new UBusMessages when switcher changes visibility or selection + + So clients can easily get what's happening on the switcher without + using class signals. + +2012-01-13 Mirco Müller <mirco.mueller@canonical.com> + + Changed rendering of filling of Dash's search-bar according to design-suggestion... http://people.canonical.com/~mmueller/fix-913717.png. Fixes: https://bugs.launchpad.net/bugs/913717. Appoved by John Lea, Andrea Cimitan, Andrea Azzarone. + +2012-01-12 Mirco Müller <mirco.mueller@canonical.com> + + Fix color/opacity of Dash's search-bar filling. Fix LP: #913717 + +2012-01-12 agateau <aurelien.gateau@canonical.com> + + Release\ 5.0.0 + 2012-01-11 Marco Trevisan (Treviño) <mail@3v1n0.net> Fixed bug #914251, local variables should be passed by value. diff --git a/UnityCore/CMakeLists.txt b/UnityCore/CMakeLists.txt index 3b0d5140b..0242eecab 100644 --- a/UnityCore/CMakeLists.txt +++ b/UnityCore/CMakeLists.txt @@ -21,6 +21,7 @@ set (CORE_HEADERS GLibSignal-inl.h GLibWrapper.h GLibWrapper-inl.h + Hud.h HomeLens.h IndicatorEntry.h Indicator.h @@ -54,6 +55,7 @@ set (CORE_SOURCES GLibDBusProxy.cpp GLibSignal.cpp GLibWrapper.cpp + Hud.cpp HomeLens.cpp Indicator.cpp IndicatorEntry.cpp diff --git a/UnityCore/GLibDBusProxy.cpp b/UnityCore/GLibDBusProxy.cpp index 1cafe872c..bf77b0b08 100644 --- a/UnityCore/GLibDBusProxy.cpp +++ b/UnityCore/GLibDBusProxy.cpp @@ -141,11 +141,7 @@ void DBusProxy::Impl::OnNameAppeared(GDBusConnection* connection, gpointer impl) { DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl); - LOG_DEBUG(logger) << self->name_ << " appeared"; - - self->connected_ = true; - self->owner_->connected.emit(); } void DBusProxy::Impl::OnNameVanished(GDBusConnection* connection, diff --git a/UnityCore/Hud.cpp b/UnityCore/Hud.cpp new file mode 100644 index 000000000..d938d80a3 --- /dev/null +++ b/UnityCore/Hud.cpp @@ -0,0 +1,255 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ +// +#include "Hud.h" + +#include <gio/gio.h> +#include <glib.h> +#include <NuxCore/Logger.h> +#include "GLibWrapper.h" +#include "GLibDBusProxy.h" + +#include "config.h" + +#include <sigc++/bind.h> + +namespace unity +{ +namespace hud +{ + +namespace +{ +nux::logging::Logger logger("unity.hud.hud"); +const int request_number_of_results = 6; +} + +// Impl classes +class HudImpl +{ +public: + HudImpl(std::string const& dbus_name, + std::string const& dbus_path, + Hud *parent) + : query_key_(NULL) + , proxy_(dbus_name, dbus_path, "com.canonical.hud") + , 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_.Connect("UpdatedQuery", sigc::mem_fun(this, &HudImpl::UpdateQueryCallback)); + } + + void QueryCallback(GVariant* data); + void UpdateQueryCallback(GVariant* data); + void BuildQueries(GVariant* query_array); + void ExecuteByKey(GVariant* key, unsigned int timestamp); + void ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp); + void CloseQuery(); + + GVariant* query_key_; + Hud::Queries queries_; + glib::DBusProxy proxy_; + Hud* parent_; +}; + +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)); +} + +void HudImpl::ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp) +{ + if (g_variant_n_children(query) < 3) + { + 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; + + 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 + ExecuteByKey(queries_.front()->key, timestamp); + CloseQuery(); + } +} + +void HudImpl::QueryCallback(GVariant* query) +{ + if (g_variant_n_children(query) < 3) + { + LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3"; + return; + } + queries_.clear(); + + // 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; + + GVariant* queries = g_variant_get_child_value(query, 1); + BuildQueries(queries); + g_variant_unref(queries); + + parent_->queries_updated.emit(queries_); +} + +void HudImpl::UpdateQueryCallback(GVariant* query) +{ + if (g_variant_n_children(query) < 3) + { + LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3"; + return; + } + // as we are expecting an update, we want to check + // and make sure that we are the actual receivers of + // the signal + + GVariant* query_key = g_variant_get_child_value(query, 2); + if (g_variant_equal(query_key_, query_key)) + { + GVariant* queries = g_variant_get_child_value(query, 1); + BuildQueries(queries); + g_variant_unref(queries); + } +} + +void HudImpl::BuildQueries(GVariant* query_array) +{ + GVariantIter iter; + g_variant_iter_init(&iter, query_array); + glib::String formatted_text; + glib::String icon; + glib::String item_icon; + glib::String completion_text; + glib::String shortcut; + GVariant* key = NULL; + + 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, + icon, + item_icon, + completion_text, + shortcut, + key))); + } +} + +void HudImpl::CloseQuery() +{ + if (query_key_ == NULL) + { + LOG_WARN(logger) << "Attempted to close the hud connection without starting it"; + } + else + { + GVariant* paramaters = g_variant_new("(v)", query_key_); + proxy_.Call("CloseQuery", paramaters); + g_variant_unref(query_key_); + query_key_ = NULL; + queries_.clear(); + } +} + + +Hud::Hud(std::string const& dbus_name, + std::string const& dbus_path) + : connected(false) + , pimpl_(new HudImpl(dbus_name, dbus_path, this)) +{ + pimpl_->parent_ = this; +} + +Hud::~Hud() +{ + delete pimpl_; +} + +void Hud::RequestQuery(std::string const& search_string) +{ + LOG_DEBUG(logger) << "Getting Query: " << search_string; + if (pimpl_->query_key_ != NULL) + { + CloseQuery(); + } + + 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)); +} + + +void Hud::ExecuteQuery(Query::Ptr query, unsigned int timestamp) +{ + LOG_DEBUG(logger) << "Executing query: " << query->formatted_text; + pimpl_->ExecuteByKey(query->key, timestamp); +} + +void Hud::ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp) +{ + //Does a search then executes the result based on that search + LOG_DEBUG(logger) << "Executing by string" << execute_string; + if (pimpl_->query_key_ != NULL) + { + CloseQuery(); + } + + GVariant* paramaters = g_variant_new("(si)", + execute_string.c_str(), + 1); + + auto functor = sigc::mem_fun(this->pimpl_, &HudImpl::ExecuteQueryByStringCallback); + + pimpl_->proxy_.Call("StartQuery", paramaters, sigc::bind(functor, timestamp)); +} + +void Hud::CloseQuery() +{ + //Send close hint to the hud + pimpl_->CloseQuery(); +} + +} +} diff --git a/UnityCore/Hud.h b/UnityCore/Hud.h new file mode 100644 index 000000000..01acdf666 --- /dev/null +++ b/UnityCore/Hud.h @@ -0,0 +1,127 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef UNITY_HUD_H +#define UNITY_HUD_H + +#include <deque> +#include <string> +#include <memory> +#include <NuxCore/Property.h> +#include <glib/gvariant.h> + +namespace unity +{ +namespace hud +{ + + +class Query +{ +public: + typedef std::shared_ptr<Query> Ptr; + + Query(std::string const& formatted_text_, std::string const& icon_name_, + std::string const& item_icon_, std::string const& completion_text_, + std::string const& shortcut_, GVariant* key_) + : formatted_text(formatted_text_) + , icon_name(icon_name_) + , item_icon(item_icon_) + , completion_text(completion_text_) + , shortcut(shortcut_) + , key(key_) + { + g_variant_ref(key); + } + + ~Query() + { + g_variant_unref(key); + } + + Query(const Query &rhs); + Query& operator=(Query); + + std::string formatted_text; // Pango formatted text + std::string icon_name; // icon name using standard lookups + std::string item_icon; // Future API + std::string completion_text; // Non formatted text f or completion + std::string shortcut; // Shortcut key + GVariant *key; +}; + + +class HudImpl; +class Hud +{ +public: + typedef std::shared_ptr<Hud> Ptr; + typedef std::deque<Query::Ptr> Queries; + + /* + * Constructor for the hud + * \param dbus_name string that specifies the name of the hud service + * \param dbus_path string that specifies the path of the hud service + */ + Hud(std::string const& dbus_name, + std::string const& dbus_path); + + ~Hud(); + + Hud(const Hud &rhs); + Hud& operator=(Hud); + + nux::Property<std::string> target; + nux::Property<bool> connected; + + /* + * Queries the service for new suggestions, will fire off the + * suggestion_search_finished signal when the suggestions are returned + */ + void RequestQuery(std::string const& search_string); + + /* + * Executes a Query + */ + void ExecuteQuery(Query::Ptr query, unsigned int timestamp); + + /* + * Executes a query that returns from a search, + * Implicitly calls CloseQuery(); + */ + void ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp); + + /* + * Closes the query connection, call when the hud closes + */ + void CloseQuery(); + + /* + * Returns a deque of Query types when the service provides them + */ + sigc::signal<void, Queries> queries_updated; + +private: + HudImpl *pimpl_; +}; + +} +} + +#endif /* UNITY_HUD_H */ diff --git a/manual-tests/Hud.txt b/manual-tests/Hud.txt new file mode 100644 index 000000000..9975bee38 --- /dev/null +++ b/manual-tests/Hud.txt @@ -0,0 +1,57 @@ +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 + +Hud Search +----------- +This test makes sure that the hud will search and activate items. + +#. Ensure the devices indicator is present +#. Tap Alt +#. Type "system" to search for the "System settings..." item in the devices indicator +#. Press return to activate the search query. + +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. + + +Hud Key-Navigation +----------- +This test ensures the hud key navigation is intact + +#. Ensure the messaging indicator is present +#. Tap Alt +#. Type "Message" to search for items from the messaging indicator +#. Press down twice +#. Press return + +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. + + +Hud Dismiss +---------- +This test ensures that the hud is dismissable + +#. Tap Alt +#. Type "test" +#. Press escape +#. Click anywhere on the screen that is not the hud interface + +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. + diff --git a/manual-tests/Launcher.txt b/manual-tests/Launcher.txt index f76203941..92af6f5a8 100644 --- a/manual-tests/Launcher.txt +++ b/manual-tests/Launcher.txt @@ -8,17 +8,17 @@ in multiple workspaces. #. Start on a fresh login #. Run an application -#. Run another instance of this application and keep it on the initial workspace -#. Run another instance of this application and move it no another workspaces +#. Run another instance (window) of this application and keep it on the initial workspace +#. Run another instance (window) of this application and move it to another workspace #. Go back to the initial workspace Outcome - The Launcher icon "pips" should reflect the number of windows in the current - workspace, so when showing the "initial" workspace the launcher icon should + The Launcher icon "pips" (indicators) should reflect the number of windows in the + current workspace, so when showing the "initial" workspace the launcher icon should have 2 "pips", when moving to the second workspace (where there's only 1 window) - the launcher application icon should show 1 pip. + the launcher application icon should have a left filled arrow. When moving to a workspace where there are no windows, the launcher icon should - use an empty arrow as left indicator. + use an empty (non filled) arrow as left indicator (despite the number of opened windows). Test Launcher Spread with Windows in multiple workspaces @@ -41,3 +41,46 @@ Outcome When moving to a workspace where there are no window o the given application, clicking on its launcher icon should bring to focus the last focused window in the last used workspace. + +Test Alt+F1 KeyNavMode Mouse Works +------------------------------- +This test shows that the mouse still works normally while keynav mode is active. + +#. Press Alt+F1 to enter keynav mode +#. Using the mouse perform a normal action (such as dragging a window) + +Outcome + The keynav mode exits, along with the mouse performing the normal action + the user expects. Such as highlighting text, moving a window, clicking out + of keynav mode, or clicking on a launcher icon. All these actions should + also exit the keynav mode. + +Test Alt+F1 KeyNavMode Shortcuts +----------------------------- +This test shows that all the shortcuts work and also exits from keynav mode. + +#. Press Alt+F1 to enter keynav mode +#. Press Super + a +#. Press Esc +#. Press Alt+F1 +#. Press Alt + Tab +#. Press Alt+F1 +#. Press Ctrl + Alt + t + +Outcome + The first shortcut opens the dash app lens, which it should open it and quit the + nav mode. The second shortcut switches between applications. The last one will open + a new terminal. This is to show all SUPER, ALT, and CTRL shortcuts work; while + closing the keynav mode. + +Test Alt+F1 NavMode Quicklist Click Exit +---------------------------------------- +This Test shows that clicking on a quicklist option quits keynav mode. + +#. Press Alt+F1 to enter keynav mode +#. Press Right arrow +#. Click on any option + +Outcome + No matter what option you click will exit keynav mode. + diff --git a/plugins/unity-mt-grab-handles/CMakeLists.txt b/plugins/unity-mt-grab-handles/CMakeLists.txt index 71dabcb73..9e5a65f4a 100644 --- a/plugins/unity-mt-grab-handles/CMakeLists.txt +++ b/plugins/unity-mt-grab-handles/CMakeLists.txt @@ -2,4 +2,4 @@ find_package (Compiz REQUIRED) include (CompizPlugin) -compiz_plugin (unitymtgrabhandles PKGDEPS nux-2.0 >= 2.0.0 PLUGINDEPS composite opengl CFLAGSADD -std=c++0x) +compiz_plugin (unitymtgrabhandles PKGDEPS nux-2.0>=2.0.0 PLUGINDEPS composite opengl CFLAGSADD -std=c++0x) diff --git a/plugins/unityshell/resources/close_dash.png b/plugins/unityshell/resources/close_dash.png Binary files differindex 876d39e41..3925bda11 100644 --- a/plugins/unityshell/resources/close_dash.png +++ b/plugins/unityshell/resources/close_dash.png diff --git a/plugins/unityshell/resources/close_dash_prelight.png b/plugins/unityshell/resources/close_dash_prelight.png Binary files differindex 876d39e41..2d6233509 100644 --- a/plugins/unityshell/resources/close_dash_prelight.png +++ b/plugins/unityshell/resources/close_dash_prelight.png diff --git a/plugins/unityshell/resources/close_dash_pressed.png b/plugins/unityshell/resources/close_dash_pressed.png Binary files differindex 90c1f7e89..bdcc40787 100644 --- a/plugins/unityshell/resources/close_dash_pressed.png +++ b/plugins/unityshell/resources/close_dash_pressed.png diff --git a/plugins/unityshell/resources/maximize_dash.png b/plugins/unityshell/resources/maximize_dash.png Binary files differindex a9102870c..6c48f11da 100644 --- a/plugins/unityshell/resources/maximize_dash.png +++ b/plugins/unityshell/resources/maximize_dash.png diff --git a/plugins/unityshell/resources/maximize_dash_prelight.png b/plugins/unityshell/resources/maximize_dash_prelight.png Binary files differindex b9ce8f341..05d4d4653 100644 --- a/plugins/unityshell/resources/maximize_dash_prelight.png +++ b/plugins/unityshell/resources/maximize_dash_prelight.png diff --git a/plugins/unityshell/resources/maximize_dash_pressed.png b/plugins/unityshell/resources/maximize_dash_pressed.png Binary files differindex 739d07a02..a1b26e20d 100644 --- a/plugins/unityshell/resources/maximize_dash_pressed.png +++ b/plugins/unityshell/resources/maximize_dash_pressed.png diff --git a/plugins/unityshell/resources/minimize_dash.png b/plugins/unityshell/resources/minimize_dash.png Binary files differindex c934104d0..05352beca 100644 --- a/plugins/unityshell/resources/minimize_dash.png +++ b/plugins/unityshell/resources/minimize_dash.png diff --git a/plugins/unityshell/resources/minimize_dash_prelight.png b/plugins/unityshell/resources/minimize_dash_prelight.png Binary files differindex c934104d0..05352beca 100644 --- a/plugins/unityshell/resources/minimize_dash_prelight.png +++ b/plugins/unityshell/resources/minimize_dash_prelight.png diff --git a/plugins/unityshell/resources/minimize_dash_pressed.png b/plugins/unityshell/resources/minimize_dash_pressed.png Binary files differindex c934104d0..05352beca 100644 --- a/plugins/unityshell/resources/minimize_dash_pressed.png +++ b/plugins/unityshell/resources/minimize_dash_pressed.png diff --git a/plugins/unityshell/resources/unmaximize_dash.png b/plugins/unityshell/resources/unmaximize_dash.png Binary files differindex 133e7058b..9cd411bea 100644 --- a/plugins/unityshell/resources/unmaximize_dash.png +++ b/plugins/unityshell/resources/unmaximize_dash.png diff --git a/plugins/unityshell/resources/unmaximize_dash_prelight.png b/plugins/unityshell/resources/unmaximize_dash_prelight.png Binary files differindex 133e7058b..2b836fd14 100644 --- a/plugins/unityshell/resources/unmaximize_dash_prelight.png +++ b/plugins/unityshell/resources/unmaximize_dash_prelight.png diff --git a/plugins/unityshell/resources/unmaximize_dash_pressed.png b/plugins/unityshell/resources/unmaximize_dash_pressed.png Binary files differindex f2bdc3a9f..ad305cb04 100644 --- a/plugins/unityshell/resources/unmaximize_dash_pressed.png +++ b/plugins/unityshell/resources/unmaximize_dash_pressed.png diff --git a/plugins/unityshell/src/AbstractIconRenderer.h b/plugins/unityshell/src/AbstractIconRenderer.h index 8571ecec6..cf78dd2df 100644 --- a/plugins/unityshell/src/AbstractIconRenderer.h +++ b/plugins/unityshell/src/AbstractIconRenderer.h @@ -23,7 +23,7 @@ #include <Nux/Nux.h> #include <boost/shared_ptr.hpp> -#include "AbstractLauncherIcon.h" +#include "IconTextureSource.h" namespace unity { @@ -68,7 +68,7 @@ public: { } - launcher::AbstractLauncherIcon* icon; + IconTextureSource* icon; nux::Point3 render_center; nux::Point3 logical_center; nux::Color colorify; diff --git a/plugins/unityshell/src/AbstractLauncherIcon.h b/plugins/unityshell/src/AbstractLauncherIcon.h index c84f6cc7e..527edbfba 100644 --- a/plugins/unityshell/src/AbstractLauncherIcon.h +++ b/plugins/unityshell/src/AbstractLauncherIcon.h @@ -34,6 +34,7 @@ #include "DndData.h" #include "Introspectable.h" #include "LauncherEntryRemote.h" +#include "IconTextureSource.h" namespace unity { @@ -72,7 +73,7 @@ public: int monitor; }; -class AbstractLauncherIcon : public nux::InitiallyUnownedObject, public debug::Introspectable +class AbstractLauncherIcon : public ui::IconTextureSource, public debug::Introspectable { public: @@ -113,15 +114,6 @@ public: QUIRK_LAST, } Quirk; - enum TransformIndex - { - TRANSFORM_TILE, - TRANSFORM_IMAGE, - TRANSFORM_HIT_AREA, - TRANSFORM_GLOW, - TRANSFORM_EMBLEM, - }; - virtual ~AbstractLauncherIcon() {} nux::Property<std::string> tooltip_text; @@ -144,8 +136,6 @@ public: virtual void SaveCenter() = 0; - virtual std::vector<nux::Vector4> & GetTransform(TransformIndex index, int monitor) = 0; - virtual void Activate(ActionArg arg) = 0; virtual void OpenInstance(ActionArg arg) = 0; @@ -170,7 +160,7 @@ public: virtual unsigned long long SwitcherPriority() = 0; - virtual bool GetQuirk(Quirk quirk) = 0; + virtual bool GetQuirk(Quirk quirk) const = 0; virtual void SetQuirk(Quirk quirk, bool value) = 0; @@ -180,16 +170,8 @@ public: virtual IconType Type() = 0; - virtual nux::Color BackgroundColor() = 0; - - virtual nux::Color GlowColor() = 0; - virtual const gchar* RemoteUri() = 0; - virtual nux::BaseTexture* TextureForSize(int size) = 0; - - virtual nux::BaseTexture* Emblem() = 0; - virtual std::list<DbusmenuMenuitem*> Menus() = 0; virtual nux::DndAction QueryAcceptDrop(unity::DndData& dnd_data) = 0; diff --git a/plugins/unityshell/src/BamfLauncherIcon.cpp b/plugins/unityshell/src/BamfLauncherIcon.cpp index cd4a120e0..12149053e 100644 --- a/plugins/unityshell/src/BamfLauncherIcon.cpp +++ b/plugins/unityshell/src/BamfLauncherIcon.cpp @@ -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 <http://www.gnu.org/licenses/>. * * Authored by: Jason Smith <jason.smith@canonical.com> + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include <Nux/Nux.h> @@ -23,13 +24,13 @@ #include "BamfLauncherIcon.h" #include "FavoriteStore.h" #include "Launcher.h" +#include "MultiMonitor.h" #include "WindowManager.h" #include "UBusMessages.h" #include "ubus-server.h" #include <glib/gi18n-lib.h> #include <gio/gdesktopappinfo.h> -#include <libindicator/indicator-desktop-shortcuts.h> #include <UnityCore/GLibWrapper.h> #include <UnityCore/Variant.h> @@ -39,24 +40,140 @@ namespace unity namespace launcher { -struct _ShortcutData +BamfLauncherIcon::BamfLauncherIcon(BamfApplication* app) + : SimpleLauncherIcon() + , _bamf_app(app, glib::AddRef()) + , _dnd_hovered(false) + , _dnd_hover_timer(0) + , _supported_types_filled(false) + , _fill_supported_types_id(0) + , _window_moved_id(0) { - BamfLauncherIcon* self; - IndicatorDesktopShortcuts* shortcuts; - char* nick; -}; -typedef struct _ShortcutData ShortcutData; -static void shortcut_data_destroy(ShortcutData* data) + auto bamf_view = glib::object_cast<BamfView>(_bamf_app); + + glib::String icon(bamf_view_get_icon(bamf_view)); + + tooltip_text = BamfName(); + icon_name = icon.Str(); + SetIconType(TYPE_APPLICATION); + + if (IsSticky()) + SetQuirk(QUIRK_VISIBLE, true); + else + SetQuirk(QUIRK_VISIBLE, bamf_view_user_visible(bamf_view)); + + SetQuirk(QUIRK_ACTIVE, bamf_view_is_active(bamf_view)); + SetQuirk(QUIRK_RUNNING, bamf_view_is_running(bamf_view)); + + glib::SignalBase* sig; + + sig = new glib::Signal<void, BamfView*, BamfView*>(bamf_view, "child-added", + [&] (BamfView*, BamfView*) { + EnsureWindowState(); + UpdateMenus(); + UpdateIconGeometries(GetCenters()); + }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*, BamfView*>(bamf_view, "child-removed", + [&] (BamfView*, BamfView*) { EnsureWindowState(); }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "urgent-changed", + [&] (BamfView*, gboolean urgent) { + SetQuirk(QUIRK_URGENT, urgent); + }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "active-changed", + [&] (BamfView*, gboolean active) { + SetQuirk(QUIRK_ACTIVE, active); + }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "running-changed", + [&] (BamfView*, gboolean running) { + SetQuirk(QUIRK_RUNNING, running); + if (running) + { + EnsureWindowState(); + UpdateIconGeometries(GetCenters()); + } + }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*, gboolean>(bamf_view, "user-visible-changed", + [&] (BamfView*, gboolean visible) { + if (!IsSticky()) + SetQuirk(QUIRK_VISIBLE, visible); + }); + _gsignals.Add(sig); + + sig = new glib::Signal<void, BamfView*>(bamf_view, "closed", + [&] (BamfView*) { + if (!IsSticky()) + Remove(); + }); + _gsignals.Add(sig); + + WindowManager::Default()->window_minimized.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMinimized)); + WindowManager::Default()->window_moved.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMoved)); + WindowManager::Default()->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState)); + WindowManager::Default()->terminate_expo.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState)); + + EnsureWindowState(); + UpdateMenus(); + UpdateDesktopFile(); + + // hack + SetProgress(0.0f); + + // Calls when there are no higher priority events pending to the default main loop. + _fill_supported_types_id = g_idle_add([] (gpointer data) -> gboolean { + static_cast<BamfLauncherIcon*>(data)->FillSupportedTypes(); + return false; + }, this); +} + +BamfLauncherIcon::~BamfLauncherIcon() { - g_object_unref(data->shortcuts); - g_free(data->nick); - g_slice_free(ShortcutData, data); + g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()), + g_quark_from_static_string("unity-seen"), + GINT_TO_POINTER(0)); + + if (_fill_supported_types_id != 0) + g_source_remove(_fill_supported_types_id); + + if (_window_moved_id != 0) + g_source_remove(_window_moved_id); + + if (_dnd_hover_timer != 0) + g_source_remove(_dnd_hover_timer); } -static void shortcut_activated(DbusmenuMenuitem* _sender, guint timestamp, gpointer userdata) +bool BamfLauncherIcon::IsSticky() const { - ShortcutData* data = (ShortcutData*)userdata; - indicator_desktop_shortcuts_nick_exec(data->shortcuts, data->nick); + return bamf_view_is_sticky(BAMF_VIEW(_bamf_app.RawPtr())); +} + +bool BamfLauncherIcon::IsVisible() const +{ + return GetQuirk(QUIRK_VISIBLE); +} + +bool BamfLauncherIcon::IsActive() const +{ + return GetQuirk(QUIRK_ACTIVE); +} + +bool BamfLauncherIcon::IsRunning() const +{ + return GetQuirk(QUIRK_RUNNING); +} + +bool BamfLauncherIcon::IsUrgent() const +{ + return GetQuirk(QUIRK_URGENT); } void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) @@ -64,14 +181,11 @@ void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) SimpleLauncherIcon::ActivateLauncherIcon(arg); bool scaleWasActive = WindowManager::Default()->IsScaleActive(); GList *l; - BamfView *view; - bool active, running, user_visible; - active = bamf_view_is_active(BAMF_VIEW(m_App)); - running = bamf_view_is_running(BAMF_VIEW(m_App)); - user_visible = running; + bool active = IsActive(); + bool user_visible = IsRunning(); - if (arg.target && OwnsWindow (arg.target)) + if (arg.target && OwnsWindow(arg.target)) { WindowManager::Default()->Activate(arg.target); return; @@ -83,28 +197,32 @@ void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) if (arg.source != ActionArg::SWITCHER) { - user_visible = bamf_view_user_visible(BAMF_VIEW(m_App)); + auto bamf_view = glib::object_cast<BamfView>(_bamf_app); + user_visible = bamf_view_user_visible(bamf_view); bool any_visible = false; - for (l = bamf_view_get_children(BAMF_VIEW(m_App)); l; l = l->next) + GList *children = bamf_view_get_children(bamf_view); + + for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; + + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); - if (BAMF_IS_WINDOW(view)) + if (!any_visible && WindowManager::Default()->IsWindowOnCurrentDesktop(xid)) { - Window xid = bamf_window_get_xid(BAMF_WINDOW(view)); + any_visible = true; + } - if (!any_visible && WindowManager::Default()->IsWindowOnCurrentDesktop(xid)) - { - any_visible = true; - } - if (active && !WindowManager::Default()->IsWindowMapped(xid)) - { - active = false; - } + if (active && !WindowManager::Default()->IsWindowMapped(xid)) + { + active = false; } } + g_list_free(children); + if (!any_visible) active = false; } @@ -117,7 +235,7 @@ void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) * 5) Spread is active -> Spread de-activated, and fall through */ - if (!running || (running && !user_visible)) // #1 above + if (!IsRunning() || (IsRunning() && !user_visible)) // #1 above { if (GetQuirk(QUIRK_STARTING)) return; @@ -164,142 +282,26 @@ void BamfLauncherIcon::ActivateLauncherIcon(ActionArg arg) } if (arg.source != ActionArg::SWITCHER) - ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, NULL); -} - -BamfLauncherIcon::BamfLauncherIcon(BamfApplication* app) - : SimpleLauncherIcon() - , _supported_types_filled(false) - , _fill_supported_types_id(0) -{ - _cached_desktop_file = NULL; - _cached_name = NULL; - m_App = app; - _remote_uri = 0; - _dnd_hover_timer = 0; - _dnd_hovered = false; - _desktop_file_monitor = NULL; - _menu_desktop_shortcuts = NULL; - _on_desktop_file_changed_handler_id = 0; - _window_moved_id = 0; - glib::String icon(bamf_view_get_icon(BAMF_VIEW(m_App))); - - tooltip_text = BamfName(); - icon_name = icon.Str(); - SetIconType(TYPE_APPLICATION); - - if (bamf_view_is_sticky(BAMF_VIEW(m_App))) - SetQuirk(QUIRK_VISIBLE, true); - else - SetQuirk(QUIRK_VISIBLE, bamf_view_user_visible(BAMF_VIEW(m_App))); - - SetQuirk(QUIRK_ACTIVE, bamf_view_is_active(BAMF_VIEW(m_App))); - SetQuirk(QUIRK_RUNNING, bamf_view_is_running(BAMF_VIEW(m_App))); - - g_signal_connect(app, "child-removed", (GCallback) &BamfLauncherIcon::OnChildRemoved, this); - g_signal_connect(app, "child-added", (GCallback) &BamfLauncherIcon::OnChildAdded, this); - g_signal_connect(app, "urgent-changed", (GCallback) &BamfLauncherIcon::OnUrgentChanged, this); - g_signal_connect(app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this); - g_signal_connect(app, "active-changed", (GCallback) &BamfLauncherIcon::OnActiveChanged, this); - g_signal_connect(app, "user-visible-changed", (GCallback) &BamfLauncherIcon::OnUserVisibleChanged, this); - g_signal_connect(app, "closed", (GCallback) &BamfLauncherIcon::OnClosed, this); - - g_object_ref(m_App); - - EnsureWindowState(); - UpdateMenus(); - - UpdateDesktopFile(); - - WindowManager::Default()->window_minimized.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMinimized)); - WindowManager::Default()->window_moved.connect(sigc::mem_fun(this, &BamfLauncherIcon::OnWindowMoved)); - WindowManager::Default()->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState)); - WindowManager::Default()->terminate_expo.connect(sigc::mem_fun(this, &BamfLauncherIcon::EnsureWindowState)); - // hack - SetProgress(0.0f); - - // Calls when there are no higher priority events pending to the default main loop. - _fill_supported_types_id = g_idle_add((GSourceFunc)FillSupportedTypes, this); - + ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, nullptr); } -BamfLauncherIcon::~BamfLauncherIcon() -{ - g_object_set_qdata(G_OBJECT(m_App), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(0)); - - // We might not have created the menu items yet - for (auto it = _menu_clients.begin(); it != _menu_clients.end(); it++) - { - g_object_unref(G_OBJECT(it->second)); - } - - if (_menu_items.find("Pin") != _menu_items.end()) - { - g_signal_handler_disconnect(G_OBJECT(_menu_items["Pin"]), - _menu_callbacks["Pin"]); - } - - if (_menu_items.find("Quit") != _menu_items.end()) - { - g_signal_handler_disconnect(G_OBJECT(_menu_items["Quit"]), - _menu_callbacks["Quit"]); - } - - for (auto it = _menu_items.begin(); it != _menu_items.end(); it++) - { - g_object_unref(G_OBJECT(it->second)); - } - - for (auto it = _menu_items_extra.begin(); it != _menu_items_extra.end(); it++) - { - g_object_unref(G_OBJECT(it->second)); - } - - if (G_IS_OBJECT(_menu_desktop_shortcuts)) - g_object_unref(G_OBJECT(_menu_desktop_shortcuts)); - - if (_on_desktop_file_changed_handler_id != 0) - g_signal_handler_disconnect(G_OBJECT(_desktop_file_monitor), - _on_desktop_file_changed_handler_id); - - if (_fill_supported_types_id != 0) - g_source_remove(_fill_supported_types_id); - - if (_window_moved_id != 0) - g_source_remove(_window_moved_id); - - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildRemoved, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnChildAdded, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUrgentChanged, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnRunningChanged, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnActiveChanged, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnUserVisibleChanged, this); - g_signal_handlers_disconnect_by_func(m_App, (void*) &BamfLauncherIcon::OnClosed, this); - - g_object_unref(m_App); - g_object_unref(_desktop_file_monitor); - - g_free(_cached_desktop_file); - g_free(_cached_name); -} - -std::vector<Window> BamfLauncherIcon::Windows () +std::vector<Window> BamfLauncherIcon::Windows() { std::vector<Window> results; GList* children, *l; - BamfView* view; WindowManager *wm = WindowManager::Default(); - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); - if (BAMF_IS_WINDOW(view)) - { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (wm->IsWindowMapped(xid)) - results.push_back ((Window) xid); + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + + if (wm->IsWindowMapped(xid)) + { + results.push_back(xid); } } @@ -307,24 +309,26 @@ std::vector<Window> BamfLauncherIcon::Windows () return results; } -std::vector<Window> BamfLauncherIcon::WindowsForMonitor (int monitor) +std::vector<Window> BamfLauncherIcon::WindowsForMonitor(int monitor) { std::vector<Window> results; GList* children, *l; - BamfView* view; - WindowManager *wm = WindowManager::Default (); + WindowManager *wm = WindowManager::Default(); - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); - if (BAMF_IS_WINDOW(view) && bamf_window_get_monitor(BAMF_WINDOW(view)) == monitor) + if (!BAMF_IS_WINDOW(l->data)) + continue; + + auto window = static_cast<BamfWindow*>(l->data); + if (bamf_window_get_monitor(window) == monitor) { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); - bool user_visible = bamf_view_user_visible(view); + guint32 xid = bamf_window_get_xid(window); + bool user_visible = bamf_view_user_visible(reinterpret_cast<BamfView*>(window)); if (user_visible && wm->IsWindowMapped(xid) && wm->IsWindowOnCurrentDesktop(xid)) - results.push_back ((Window) xid); + results.push_back(xid); } } @@ -332,18 +336,20 @@ std::vector<Window> BamfLauncherIcon::WindowsForMonitor (int monitor) return results; } -std::string BamfLauncherIcon::NameForWindow (Window window) +std::string BamfLauncherIcon::NameForWindow(Window window) { std::string result; GList* children, *l; - BamfView* view; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); - if (BAMF_IS_WINDOW(view) && (Window) bamf_window_get_xid(BAMF_WINDOW(view)) == window) + if (!BAMF_IS_WINDOW(l->data)) + continue; + + if (bamf_window_get_xid(static_cast<BamfWindow*>(l->data)) == window) { + auto view = static_cast<BamfView*>(l->data); result = glib::String(bamf_view_get_name(view)).Str(); break; } @@ -364,11 +370,12 @@ void BamfLauncherIcon::OnWindowMinimized(guint32 xid) void BamfLauncherIcon::OnWindowMoved(guint32 moved_win) { + if (!OwnsWindow(moved_win)) + return; + if (_window_moved_id != 0) g_source_remove(_window_moved_id); - _window_moved_xid = moved_win; - _window_moved_id = g_timeout_add(250, [] (gpointer data) -> gboolean { BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data); @@ -378,116 +385,99 @@ void BamfLauncherIcon::OnWindowMoved(guint32 moved_win) }, this); } -bool BamfLauncherIcon::IsSticky() -{ - return bamf_view_is_sticky(BAMF_VIEW(m_App)); -} - void BamfLauncherIcon::UpdateDesktopFile() { - char* filename = NULL; - filename = (char*) bamf_application_get_desktop_file(m_App); + const char* filename = bamf_application_get_desktop_file(_bamf_app); - if (filename != NULL && g_strcmp0(_cached_desktop_file, filename) != 0) + if (filename != nullptr && filename[0] != '\0' && _desktop_file != filename) { - if (_cached_desktop_file != NULL) - g_free(_cached_desktop_file); - - _cached_desktop_file = g_strdup(filename); + _desktop_file = filename; // add a file watch to the desktop file so that if/when the app is removed // we can remove ourself from the launcher and when it's changed // we can update the quicklist. if (_desktop_file_monitor) - { - if (_on_desktop_file_changed_handler_id != 0) - g_signal_handler_disconnect(G_OBJECT(_desktop_file_monitor), - _on_desktop_file_changed_handler_id); - g_object_unref(_desktop_file_monitor); - } + _gsignals.Disconnect(_desktop_file_monitor, "changed"); - GFile* desktop_file = g_file_new_for_path(DesktopFile()); + glib::Object<GFile> desktop_file(g_file_new_for_path(_desktop_file.c_str())); _desktop_file_monitor = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE, - NULL, NULL); - g_file_monitor_set_rate_limit (_desktop_file_monitor, 1000); - _on_desktop_file_changed_handler_id = g_signal_connect(_desktop_file_monitor, - "changed", - G_CALLBACK(&BamfLauncherIcon::OnDesktopFileChanged), - this); + nullptr, nullptr); + g_file_monitor_set_rate_limit(_desktop_file_monitor, 1000); + + auto sig = new glib::Signal<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(_desktop_file_monitor, "changed", + [&] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent event_type) { + switch (event_type) + { + case G_FILE_MONITOR_EVENT_DELETED: + UnStick(); + break; + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + UpdateDesktopQuickList(); + break; + default: + break; + } + }); + _gsignals.Add(sig); } } -const char* BamfLauncherIcon::DesktopFile() +std::string BamfLauncherIcon::DesktopFile() { UpdateDesktopFile(); - return _cached_desktop_file; + return _desktop_file; } -const char* BamfLauncherIcon::BamfName() +std::string BamfLauncherIcon::BamfName() const { - gchar* name = bamf_view_get_name(BAMF_VIEW(m_App)); - - if (name == NULL) - name = g_strdup(""); - - if (_cached_name != NULL) - g_free(_cached_name); - - _cached_name = name; - - return _cached_name; + glib::String name(bamf_view_get_name(BAMF_VIEW(_bamf_app.RawPtr()))); + return name.Str(); } void BamfLauncherIcon::AddProperties(GVariantBuilder* builder) { - SimpleLauncherIcon::AddProperties(builder); + LauncherIcon::AddProperties(builder); + + g_variant_builder_add(builder, "{sv}", "desktop-file", g_variant_new_string(DesktopFile().c_str())); GList* children, *l; - BamfView* view; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + 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) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - xids[i++] = g_variant_new_uint32(bamf_window_get_xid(BAMF_WINDOW(view))); - } + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + xids[i++] = g_variant_new_uint32(xid); } g_list_free(children); - unity::variant::BuilderWrapper(builder) - .add("sticky", IsSticky()) - .add("desktop-file",DesktopFile()) - .add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i)); + g_variant_builder_add(builder, "{sv}", "xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i)); + g_variant_builder_add(builder, "{sv}", "sticky", g_variant_new_boolean(IsSticky())); } -bool BamfLauncherIcon::OwnsWindow(Window w) +bool BamfLauncherIcon::OwnsWindow(Window xid) const { GList* children, *l; - BamfView* view; bool owns = false; - if (!w) return owns; + if (!xid) + return owns; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) + if (bamf_window_get_xid(static_cast<BamfWindow*>(l->data)) == xid) { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); - - if (xid == w) - { - owns = true; - break; - } + owns = true; + break; } } @@ -497,49 +487,40 @@ bool BamfLauncherIcon::OwnsWindow(Window w) void BamfLauncherIcon::OpenInstanceWithUris(std::set<std::string> uris) { - GDesktopAppInfo* appInfo; - GError* error = NULL; - - appInfo = g_desktop_app_info_new_from_filename(DesktopFile()); + glib::Error error; + glib::Object<GDesktopAppInfo> desktopInfo(g_desktop_app_info_new_from_filename(DesktopFile().c_str())); + auto appInfo = glib::object_cast<GAppInfo>(desktopInfo); - if (g_app_info_supports_uris(G_APP_INFO(appInfo))) + if (g_app_info_supports_uris(appInfo)) { - GList* list = NULL; + GList* list = nullptr; for (auto it : uris) list = g_list_prepend(list, g_strdup(it.c_str())); - g_app_info_launch_uris(G_APP_INFO(appInfo), list, NULL, &error); + g_app_info_launch_uris(appInfo, list, nullptr, &error); g_list_free_full(list, g_free); } - else if (g_app_info_supports_files(G_APP_INFO(appInfo))) + else if (g_app_info_supports_files(appInfo)) { - GList* list = NULL, *l; + GList* list = nullptr; for (auto it : uris) { GFile* file = g_file_new_for_uri(it.c_str()); list = g_list_prepend(list, file); } - g_app_info_launch(G_APP_INFO(appInfo), list, NULL, &error); - for (l = list; l; l = l->next) - g_object_unref(G_FILE(list->data)); - - g_list_free(list); + g_app_info_launch(appInfo, list, nullptr, &error); + g_list_free_full(list, g_object_unref); } else { - g_app_info_launch(G_APP_INFO(appInfo), NULL, NULL, &error); + g_app_info_launch(appInfo, nullptr, nullptr, &error); } - g_object_unref(appInfo); - if (error) - { - g_warning("%s\n", error->message); - g_error_free(error); - } + g_warning("%s\n", error.Message().c_str()); UpdateQuirkTime(QUIRK_STARTING); } @@ -548,60 +529,59 @@ void BamfLauncherIcon::OpenInstanceLauncherIcon(ActionArg arg) { std::set<std::string> empty; OpenInstanceWithUris(empty); - ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, NULL); + ubus_server_send_message(ubus_server_get_default(), UBUS_LAUNCHER_ACTION_DONE, nullptr); } void BamfLauncherIcon::Focus(ActionArg arg) { GList* children, *l; - BamfView* view; bool any_urgent = false; bool any_visible = false; bool any_user_visible = false; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); std::vector<Window> windows; /* get the list of windows */ for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - Window xid = bamf_window_get_xid(BAMF_WINDOW(view)); - bool urgent = bamf_view_is_urgent(view); - bool user_visible = bamf_view_user_visible(view); + auto view = static_cast<BamfView*>(l->data); - if (any_urgent) - { - if (urgent) - windows.push_back(xid); - } - else if (any_user_visible && !urgent) - { - if (user_visible) - windows.push_back(xid); - } - else - { - if (urgent || user_visible) - { - windows.clear(); - any_visible = false; - any_urgent = (any_urgent || urgent); - any_user_visible = (any_user_visible || user_visible); - } + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + bool urgent = bamf_view_is_urgent(view); + bool user_visible = bamf_view_user_visible(view); + if (any_urgent) + { + if (urgent) windows.push_back(xid); - } - - if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid) && - WindowManager::Default()->IsWindowVisible(xid)) + } + else if (any_user_visible && !urgent) + { + if (user_visible) + windows.push_back(xid); + } + else + { + if (urgent || user_visible) { - any_visible = true; + windows.clear(); + any_visible = false; + any_urgent = (any_urgent || urgent); + any_user_visible = (any_user_visible || user_visible); } + + windows.push_back(xid); + } + + if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid) && + WindowManager::Default()->IsWindowVisible(xid)) + { + any_visible = true; } } g_list_free(children); @@ -628,24 +608,21 @@ void BamfLauncherIcon::Focus(ActionArg arg) bool BamfLauncherIcon::Spread(bool current_desktop, int state, bool force) { - BamfView* view; GList* children, *l; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); WindowManager* wm = WindowManager::Default(); std::vector<Window> windowList; for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); - if (!current_desktop || (current_desktop && wm->IsWindowOnCurrentDesktop(xid))) - { - windowList.push_back((Window) xid); - } + if (!current_desktop || (current_desktop && wm->IsWindowOnCurrentDesktop(xid))) + { + windowList.push_back(xid); } } @@ -653,63 +630,22 @@ bool BamfLauncherIcon::Spread(bool current_desktop, int state, bool force) return WindowManager::Default()->ScaleWindowGroup(windowList, state, force); } -void BamfLauncherIcon::OnClosed(BamfView* view, gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - - if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App))) - self->Remove(); -} - -void BamfLauncherIcon::OnUserVisibleChanged(BamfView* view, gboolean visible, - gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - - if (!bamf_view_is_sticky(BAMF_VIEW(self->m_App))) - self->SetQuirk(QUIRK_VISIBLE, visible); -} - -void BamfLauncherIcon::OnRunningChanged(BamfView* view, gboolean running, - gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - self->SetQuirk(QUIRK_RUNNING, running); - - if (running) - { - self->EnsureWindowState(); - self->UpdateIconGeometries(self->GetCenters()); - } -} - -void BamfLauncherIcon::OnActiveChanged(BamfView* view, gboolean active, gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - self->SetQuirk(QUIRK_ACTIVE, active); -} - -void BamfLauncherIcon::OnUrgentChanged(BamfView* view, gboolean urgent, gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - self->SetQuirk(QUIRK_URGENT, urgent); -} - void BamfLauncherIcon::EnsureWindowState() { GList* children, *l; - std::vector<bool> monitors; monitors.resize(max_num_monitors); - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { if (!BAMF_IS_WINDOW(l->data)) continue; - Window xid = bamf_window_get_xid(BAMF_WINDOW(l->data)); - int monitor = bamf_window_get_monitor(BAMF_WINDOW(l->data)); + auto window = static_cast<BamfWindow*>(l->data); + Window xid = bamf_window_get_xid(window); + int monitor = bamf_window_get_monitor(window); + if (monitor >= 0 && WindowManager::Default()->IsWindowOnCurrentDesktop(xid)) monitors[monitor] = true; } @@ -717,37 +653,18 @@ void BamfLauncherIcon::EnsureWindowState() for (int i = 0; i < max_num_monitors; i++) SetWindowVisibleOnMonitor(monitors[i], i); - g_list_free(children); -} - -void BamfLauncherIcon::OnChildAdded(BamfView* view, BamfView* child, gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - self->EnsureWindowState(); - self->UpdateMenus(); - self->UpdateIconGeometries(self->GetCenters()); + needs_redraw.emit(this); - self->needs_redraw.emit(self); -} - -void BamfLauncherIcon::OnChildRemoved(BamfView* view, BamfView* child, gpointer data) -{ - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - self->EnsureWindowState(); - - self->needs_redraw.emit(self); + g_list_free(children); } void BamfLauncherIcon::UpdateDesktopQuickList() { - IndicatorDesktopShortcuts* desktop_shortcuts; GKeyFile* keyfile; - GError* error = NULL; - const char *desktop_file; - - desktop_file = DesktopFile(); + glib::Error error; + std::string const& desktop_file = DesktopFile(); - if (!desktop_file || g_strcmp0(desktop_file, "") == 0) + if (desktop_file.empty()) return; // check that we have the X-Ayatana-Desktop-Shortcuts flag @@ -755,58 +672,49 @@ void BamfLauncherIcon::UpdateDesktopQuickList() // and not report errors when it can't find the key. // so FIXME when ted is around keyfile = g_key_file_new(); - g_key_file_load_from_file(keyfile, desktop_file, G_KEY_FILE_NONE, &error); + g_key_file_load_from_file(keyfile, desktop_file.c_str(), G_KEY_FILE_NONE, &error); - if (error != NULL) + if (error) { - g_warning("Could not load desktop file for: %s", desktop_file); + g_warning("Could not load desktop file for: %s", desktop_file.c_str()); g_key_file_free(keyfile); - g_error_free(error); return; } if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, - "X-Ayatana-Desktop-Shortcuts", NULL)) + "X-Ayatana-Desktop-Shortcuts", nullptr)) { - DbusmenuMenuitem* root = dbusmenu_menuitem_new(); - dbusmenu_menuitem_set_root(root, TRUE); - desktop_shortcuts = indicator_desktop_shortcuts_new(desktop_file, "Unity"); - const gchar** nicks = indicator_desktop_shortcuts_get_nicks(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); + + _desktop_shortcuts = indicator_desktop_shortcuts_new(desktop_file.c_str(), "Unity"); + const gchar** nicks = indicator_desktop_shortcuts_get_nicks(_desktop_shortcuts); int index = 0; - if (nicks) + while (nicks[index]) { - while (((gpointer*) nicks)[index]) - { - gchar* name; - DbusmenuMenuitem* item; - name = indicator_desktop_shortcuts_nick_get_name(desktop_shortcuts, - nicks[index]); - ShortcutData* data = g_slice_new0(ShortcutData); - data->self = this; - data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS(g_object_ref(desktop_shortcuts)); - data->nick = g_strdup(nicks[index]); - - item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); - dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - g_signal_connect_data(item, "item-activated", - (GCallback) shortcut_activated, (gpointer) data, - (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0); - - dbusmenu_menuitem_child_append(root, item); - - index++; - - g_free(name); - } + glib::String name(indicator_desktop_shortcuts_nick_get_name(_desktop_shortcuts, + nicks[index])); + glib::Object<DbusmenuMenuitem> item(dbusmenu_menuitem_new()); + dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + dbusmenu_menuitem_property_set(item, "shortcut-nick", nicks[index]); + + auto sig = new glib::Signal<void, DbusmenuMenuitem*, gint>(item, "item-activated", + [&] (DbusmenuMenuitem* item, gint) { + const gchar *nick; + nick = dbusmenu_menuitem_property_get(item, "shortcut-nick"); + indicator_desktop_shortcuts_nick_exec(_desktop_shortcuts, nick); + }); + _gsignals.Add(sig); + + dbusmenu_menuitem_child_append(_menu_desktop_shortcuts, item); + index++; } - - if (G_IS_OBJECT(_menu_desktop_shortcuts)) - g_object_unref(G_OBJECT(_menu_desktop_shortcuts)); - - _menu_desktop_shortcuts = root; } g_key_file_free(keyfile); @@ -816,61 +724,60 @@ void BamfLauncherIcon::UpdateMenus() { GList* children, *l; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { if (!BAMF_IS_INDICATOR(l->data)) continue; - BamfIndicator* indicator = BAMF_INDICATOR(l->data); + auto indicator = static_cast<BamfIndicator*>(l->data); std::string path = bamf_indicator_get_dbus_menu_path(indicator); // we already have this if (_menu_clients.find(path) != _menu_clients.end()) continue; - DbusmenuClient* client = dbusmenu_client_new(bamf_indicator_get_remote_address(indicator), path.c_str()); - _menu_clients[path] = client; + std::string address = bamf_indicator_get_remote_address(indicator); + DbusmenuClient* client = dbusmenu_client_new(address.c_str(), path.c_str()); + _menu_clients[path] = glib::Object<DbusmenuClient>(client); } g_list_free(children); // add dynamic quicklist - if (_menuclient_dynamic_quicklist != NULL) + if (DBUSMENU_IS_CLIENT(_menuclient_dynamic_quicklist)) { - auto menu_client = DBUSMENU_CLIENT(g_object_ref(_menuclient_dynamic_quicklist)); - _menu_clients["dynamicquicklist"] = menu_client; + if (_menu_clients["dynamicquicklist"] != _menuclient_dynamic_quicklist) + { + _menu_clients["dynamicquicklist"] = glib::Object<DbusmenuClient>(_menuclient_dynamic_quicklist); + } + } + else if (_menu_clients["dynamicquicklist"]) + { + _menu_clients.erase("dynamicquicklist"); + _menuclient_dynamic_quicklist = nullptr; } // make a client for desktop file actions - if (!DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts)) + if (!DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts.RawPtr())) { UpdateDesktopQuickList(); } - -} - -void BamfLauncherIcon::OnQuit(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self) -{ - self->Quit(); } void BamfLauncherIcon::Quit() { GList* children, *l; - BamfView* view; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); - WindowManager::Default()->Close(xid); - } + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + WindowManager::Default()->Close(xid); } g_list_free(children); @@ -878,51 +785,41 @@ void BamfLauncherIcon::Quit() void BamfLauncherIcon::Stick(bool save) { - BamfView* view = BAMF_VIEW(m_App); - - if (bamf_view_is_sticky(view)) + if (IsSticky()) return; - const gchar* desktop_file = DesktopFile(); - bamf_view_set_sticky(view, true); + std::string const& desktop_file = DesktopFile(); + bamf_view_set_sticky(BAMF_VIEW(_bamf_app.RawPtr()), true); - if (save && desktop_file && strlen(desktop_file) > 0) - FavoriteStore::GetDefault().AddFavorite(desktop_file, -1); + if (save && !desktop_file.empty()) + FavoriteStore::GetDefault().AddFavorite(desktop_file.c_str(), -1); } -void BamfLauncherIcon::UnStick(void) +void BamfLauncherIcon::UnStick() { - BamfView* view = BAMF_VIEW(this->m_App); - - if (!bamf_view_is_sticky(view)) + if (!IsSticky()) return; - const gchar* desktop_file = DesktopFile(); + std::string const& desktop_file = DesktopFile(); + BamfView* view = BAMF_VIEW(_bamf_app.RawPtr()); bamf_view_set_sticky(view, false); if (bamf_view_is_closed(view) || !bamf_view_user_visible(view)) - this->Remove(); + Remove(); - if (desktop_file && desktop_file[0] != '\0') - FavoriteStore::GetDefault().RemoveFavorite(desktop_file); + if (!desktop_file.empty()) + FavoriteStore::GetDefault().RemoveFavorite(desktop_file.c_str()); } -void BamfLauncherIcon::OnTogglePin(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self) +void BamfLauncherIcon::ToggleSticky() { - BamfView* view = BAMF_VIEW(self->m_App); - bool sticky = bamf_view_is_sticky(view); - const gchar* desktop_file = self->DesktopFile(); - - if (sticky) + if (IsSticky()) { - self->UnStick(); + UnStick(); } else { - bamf_view_set_sticky(view, true); - - if (desktop_file && strlen(desktop_file) > 0) - FavoriteStore::GetDefault().AddFavorite(desktop_file, -1); + Stick(); } } @@ -934,17 +831,18 @@ void BamfLauncherIcon::EnsureMenuItemsReady() if (_menu_items.find("Pin") == _menu_items.end()) { menu_item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); - _menu_callbacks["Pin"] = g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnTogglePin, this); + _gsignals.Add(new glib::Signal<void, DbusmenuMenuitem*, int>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + [&] (DbusmenuMenuitem*, int) { + ToggleSticky(); + })); - _menu_items["Pin"] = menu_item; + _menu_items["Pin"] = glib::Object<DbusmenuMenuitem>(menu_item); } - const char* label = !bamf_view_is_sticky(BAMF_VIEW(m_App)) ? - _("Lock to launcher") : _("Unlock from launcher"); + const char* label = !IsSticky() ? _("Lock to launcher") : _("Unlock from launcher"); dbusmenu_menuitem_property_set(_menu_items["Pin"], DBUSMENU_MENUITEM_PROP_LABEL, label); @@ -953,50 +851,38 @@ void BamfLauncherIcon::EnsureMenuItemsReady() if (_menu_items.find("Quit") == _menu_items.end()) { menu_item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit")); dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); - _menu_callbacks["Quit"] = g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this); + _gsignals.Add(new glib::Signal<void, DbusmenuMenuitem*, int>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + [&] (DbusmenuMenuitem*, int) { + Quit(); + })); - _menu_items["Quit"] = menu_item; + _menu_items["Quit"] = glib::Object<DbusmenuMenuitem>(menu_item); } } -static void OnAppLabelActivated(DbusmenuMenuitem* sender, - guint timestamp, - gpointer data) -{ - BamfLauncherIcon* self = NULL; - - if (!data) - return; - - self = static_cast <BamfLauncherIcon*> (data); - self->ActivateLauncherIcon(ActionArg(ActionArg::OTHER, 0)); -} - std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() { - std::map<std::string, DbusmenuClient*>::iterator it; std::list<DbusmenuMenuitem*> result; bool first_separator_needed = false; - DbusmenuMenuitem* item = NULL; + DbusmenuMenuitem* item = nullptr; // FIXME for O: hack around the wrong abstraction UpdateMenus(); - for (it = _menu_clients.begin(); it != _menu_clients.end(); it++) + for (auto it = _menu_clients.begin(); it != _menu_clients.end(); ++it) { - GList* child = NULL; - DbusmenuClient* client = (*it).second; + GList* child = nullptr; + DbusmenuClient* client = it->second; DbusmenuMenuitem* root = dbusmenu_client_get_root(client); if (!root || !dbusmenu_menuitem_property_get_bool(root, DBUSMENU_MENUITEM_PROP_VISIBLE)) continue; - for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child)) + for (child = dbusmenu_menuitem_get_children(root); child; child = child->next) { DbusmenuMenuitem* item = (DbusmenuMenuitem*) child->data; @@ -1014,12 +900,11 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() } // FIXME: this should totally be added as a _menu_client - if (DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts)) + if (DBUSMENU_IS_MENUITEM(_menu_desktop_shortcuts.RawPtr())) { - GList* child = NULL; - DbusmenuMenuitem* root = _menu_desktop_shortcuts; + GList* child = nullptr; - for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child)) + for (child = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); child; child = child->next) { DbusmenuMenuitem* item = (DbusmenuMenuitem*) child->data; @@ -1045,7 +930,7 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - _menu_items_extra["FirstSeparator"] = item; + _menu_items_extra["FirstSeparator"] = glib::Object<DbusmenuMenuitem>(item); } result.push_back(item); } @@ -1057,7 +942,7 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() } else { - glib::String app_name(g_markup_escape_text(BamfName(), -1)); + glib::String app_name(g_markup_escape_text(BamfName().c_str(), -1)); std::ostringstream bold_app_name; bold_app_name << "<b>" << app_name << "</b>"; @@ -1071,9 +956,13 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() dbusmenu_menuitem_property_set_bool(item, "unity-use-markup", true); - g_signal_connect(item, "item-activated", (GCallback) OnAppLabelActivated, this); - _menu_items_extra["AppName"] = item; + _gsignals.Add(new glib::Signal<void, DbusmenuMenuitem*, int>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + [&] (DbusmenuMenuitem*, int) { + ActivateLauncherIcon(ActionArg(ActionArg::OTHER, 0)); + })); + + _menu_items_extra["AppName"] = glib::Object<DbusmenuMenuitem>(item); } result.push_back(item); @@ -1088,30 +977,27 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - _menu_items_extra["SecondSeparator"] = item; + _menu_items_extra["SecondSeparator"] = glib::Object<DbusmenuMenuitem>(item); } result.push_back(item); EnsureMenuItemsReady(); - std::map<std::string, DbusmenuMenuitem*>::iterator it_m; - std::list<DbusmenuMenuitem*>::iterator it_l; - bool exists; - for (it_m = _menu_items.begin(); it_m != _menu_items.end(); it_m++) + for (auto it_m = _menu_items.begin(); it_m != _menu_items.end(); ++it_m) { - const char* key = ((*it_m).first).c_str(); - if (g_strcmp0(key , "Quit") == 0 && !bamf_view_is_running(BAMF_VIEW(m_App))) + if (!IsRunning() && it_m->first == "Quit") continue; - exists = false; - std::string label_default = dbusmenu_menuitem_property_get((*it_m).second, DBUSMENU_MENUITEM_PROP_LABEL); - for (it_l = result.begin(); it_l != result.end(); it_l++) + bool exists = false; + std::string label_default(dbusmenu_menuitem_property_get(it_m->second, DBUSMENU_MENUITEM_PROP_LABEL)); + + for (auto menu_item : result) { - const gchar* type = dbusmenu_menuitem_property_get(*it_l, DBUSMENU_MENUITEM_PROP_TYPE); - if (type == NULL)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0) + const gchar* type = dbusmenu_menuitem_property_get(menu_item, DBUSMENU_MENUITEM_PROP_TYPE); + if (type == nullptr)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0) { - std::string label_menu = dbusmenu_menuitem_property_get(*it_l, DBUSMENU_MENUITEM_PROP_LABEL); - if (label_menu.compare(label_default) == 0) + std::string label_menu(dbusmenu_menuitem_property_get(menu_item, DBUSMENU_MENUITEM_PROP_LABEL)); + if (label_menu == label_default) { exists = true; break; @@ -1120,17 +1006,15 @@ std::list<DbusmenuMenuitem*> BamfLauncherIcon::GetMenus() } if (!exists) - result.push_back((*it_m).second); + result.push_back(it_m->second); } return result; } - void BamfLauncherIcon::UpdateIconGeometries(std::vector<nux::Point3> center) { GList* children, *l; - BamfView* view; nux::Geometry geo; geo.x = center[0].x - 24; @@ -1138,17 +1022,15 @@ void BamfLauncherIcon::UpdateIconGeometries(std::vector<nux::Point3> center) geo.width = 48; geo.height = 48; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); - WindowManager::Default()->SetWindowIconGeometry((Window)xid, geo); - } + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + WindowManager::Default()->SetWindowIconGeometry(xid, geo); } g_list_free(children); @@ -1161,23 +1043,24 @@ void BamfLauncherIcon::OnCenterStabilized(std::vector<nux::Point3> center) const gchar* BamfLauncherIcon::GetRemoteUri() { - if (!_remote_uri) + if (_remote_uri.empty()) { - const gchar* desktop_file = DesktopFile(); - gchar* basename = g_path_get_basename(desktop_file); - - _remote_uri = g_strdup_printf("application://%s", basename); + const std::string prefix = "application://"; + glib::String basename(g_path_get_basename(DesktopFile().c_str())); - g_free(basename); + if (!basename.Str().empty()) + { + _remote_uri = prefix + basename.Str(); + } } - return _remote_uri; + return _remote_uri.c_str(); } std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& uris) { std::set<std::string> result; - gboolean is_home_launcher = g_str_has_suffix(DesktopFile(), "nautilus-home.desktop"); + gboolean is_home_launcher = g_str_has_suffix(DesktopFile().c_str(), "nautilus-home.desktop"); if (is_home_launcher) { @@ -1187,7 +1070,9 @@ std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& ur } for (auto i : uris.Types()) + { for (auto j : GetSupportedTypes()) + { if (g_content_type_is_a(i.c_str(), j.c_str())) { for (auto k : uris.UrisByType(i)) @@ -1195,26 +1080,28 @@ std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& ur break; } + } + } return result; } -gboolean BamfLauncherIcon::OnDndHoveredTimeout(gpointer data) +void BamfLauncherIcon::OnDndHovered() { - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - // for now, let's not do this, it turns out to be quite buggy - //if (self->_dnd_hovered && bamf_view_is_running(BAMF_VIEW(self->m_App))) - // self->Spread(CompAction::StateInitEdgeDnd, true); - - self->_dnd_hover_timer = 0; - return false; + //if (_dnd_hovered && IsRunning()) + // Spread(CompAction::StateInitEdgeDnd, true); } void BamfLauncherIcon::OnDndEnter() { _dnd_hovered = true; - _dnd_hover_timer = g_timeout_add(1000, &BamfLauncherIcon::OnDndHoveredTimeout, this); + _dnd_hover_timer = g_timeout_add(1000, [] (gpointer data) -> gboolean { + BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data); + self->OnDndHovered(); + self->_dnd_hover_timer = 0; + return false; + }, this); } void BamfLauncherIcon::OnDndLeave() @@ -1231,37 +1118,16 @@ nux::DndAction BamfLauncherIcon::OnQueryAcceptDrop(unity::DndData& dnd_data) return ValidateUrisForLaunch(dnd_data).empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY; } -void BamfLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data) +void BamfLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data) { OpenInstanceWithUris(ValidateUrisForLaunch(dnd_data)); } -void BamfLauncherIcon::OnDesktopFileChanged(GFileMonitor* monitor, - GFile* file, - GFile* other_file, - GFileMonitorEvent event_type, - gpointer data) -{ - BamfLauncherIcon* self = static_cast<BamfLauncherIcon*>(data); - switch (event_type) - { - case G_FILE_MONITOR_EVENT_DELETED: - self->UnStick(); - break; - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - self->UpdateDesktopQuickList(); - break; - default: - break; - } -} - -bool -BamfLauncherIcon::ShowInSwitcher(bool current) +bool BamfLauncherIcon::ShowInSwitcher(bool current) { bool result = false; - if (GetQuirk(QUIRK_RUNNING) && GetQuirk(QUIRK_VISIBLE)) + if (IsRunning() && IsVisible()) { if (current) { @@ -1283,91 +1149,80 @@ BamfLauncherIcon::ShowInSwitcher(bool current) return result; } -unsigned long long -BamfLauncherIcon::SwitcherPriority() +unsigned long long BamfLauncherIcon::SwitcherPriority() { GList* children, *l; - BamfView* view; unsigned long long result = 0; - children = bamf_view_get_children(BAMF_VIEW(m_App)); + children = bamf_view_get_children(BAMF_VIEW(_bamf_app.RawPtr())); /* get the list of windows */ for (l = children; l; l = l->next) { - view = static_cast <BamfView*> (l->data); + if (!BAMF_IS_WINDOW(l->data)) + continue; - if (BAMF_IS_WINDOW(view)) - { - guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view)); - result = std::max(result, WindowManager::Default()->GetWindowActiveNumber (xid)); - } + Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data)); + result = std::max(result, WindowManager::Default()->GetWindowActiveNumber(xid)); } g_list_free(children); return result; } -const std::set<std::string>& -BamfLauncherIcon::GetSupportedTypes() +const std::set<std::string>& BamfLauncherIcon::GetSupportedTypes() { if (!_supported_types_filled) - FillSupportedTypes(this); + FillSupportedTypes(); return _supported_types; } -gboolean -BamfLauncherIcon::FillSupportedTypes(gpointer data) +void BamfLauncherIcon::FillSupportedTypes() { - BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data); - - if (self->_fill_supported_types_id) + if (_fill_supported_types_id) { - g_source_remove(self->_fill_supported_types_id); - self->_fill_supported_types_id = 0; + g_source_remove(_fill_supported_types_id); + _fill_supported_types_id = 0; } - if (!self->_supported_types_filled) + if (!_supported_types_filled) { - self->_supported_types_filled = true; - - self->_supported_types.clear(); + _supported_types_filled = true; + _supported_types.clear(); - const char* desktop_file = self->DesktopFile(); + std::string const& desktop_file = DesktopFile(); - if (!desktop_file || strlen(desktop_file) <= 1) - return false; + if (desktop_file.empty()) + return; GKeyFile* key_file = g_key_file_new(); - unity::glib::Error error; + glib::Error error; - g_key_file_load_from_file(key_file, desktop_file, (GKeyFileFlags) 0, &error); + g_key_file_load_from_file(key_file, desktop_file.c_str(), (GKeyFileFlags) 0, &error); if (error) { g_key_file_free(key_file); - return false; + return; } - char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", NULL, NULL); + char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", nullptr, nullptr); if (!mimes) { g_key_file_free(key_file); - return false; + return; } - for (int i=0; mimes[i]; i++) + for (int i = 0; mimes[i]; i++) { unity::glib::String super_type(g_content_type_from_mime_type(mimes[i])); - self->_supported_types.insert(super_type.Str()); + _supported_types.insert(super_type.Str()); } g_key_file_free(key_file); g_strfreev(mimes); } - - return false; } std::string BamfLauncherIcon::GetName() const diff --git a/plugins/unityshell/src/BamfLauncherIcon.h b/plugins/unityshell/src/BamfLauncherIcon.h index b3d35c7f4..c222f4268 100644 --- a/plugins/unityshell/src/BamfLauncherIcon.h +++ b/plugins/unityshell/src/BamfLauncherIcon.h @@ -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,19 +15,17 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Jason Smith <jason.smith@canonical.com> + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #ifndef BAMFLAUNCHERICON_H #define BAMFLAUNCHERICON_H -/* Compiz */ -#include <core/core.h> +#include <UnityCore/GLibSignal.h> +#include <UnityCore/GLibWrapper.h> -#include <Nux/BaseWindow.h> -#include <NuxCore/Math/MathInc.h> -#include <gdk-pixbuf/gdk-pixbuf.h> #include <libbamf/libbamf.h> -#include <sigc++/sigc++.h> +#include <libindicator/indicator-desktop-shortcuts.h> #include "SimpleLauncherIcon.h" @@ -44,108 +42,87 @@ public: BamfLauncherIcon(BamfApplication* app); virtual ~BamfLauncherIcon(); - const char* DesktopFile(); - bool IsSticky(); + void ActivateLauncherIcon(ActionArg arg); + + std::string DesktopFile(); + + bool IsSticky() const; + bool IsVisible() const; + bool IsActive() const; + bool IsRunning() const; + bool IsUrgent() const; + + void Quit(); void Stick(bool save = true); void UnStick(); - void Quit(); - - void ActivateLauncherIcon(ActionArg arg); virtual bool ShowInSwitcher(bool current); virtual unsigned long long SwitcherPriority(); - std::vector<Window> Windows (); + std::vector<Window> Windows(); std::vector<Window> WindowsForMonitor(int monitor); + std::string NameForWindow(Window window); - std::string NameForWindow (Window window); protected: - std::string GetName() const; - std::list<DbusmenuMenuitem*> GetMenus(); - void UpdateIconGeometries(std::vector<nux::Point3> center); void OnCenterStabilized(std::vector<nux::Point3> center); - - void OnLauncherHiddenChanged(); - void AddProperties(GVariantBuilder* builder); - - const gchar* GetRemoteUri(); - - nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data); void OnAcceptDrop(unity::DndData& dnd_data); void OnDndEnter(); + void OnDndHovered(); void OnDndLeave(); - void OpenInstanceLauncherIcon(ActionArg arg); + void ToggleSticky(); + nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data); + + std::list<DbusmenuMenuitem*> GetMenus(); std::set<std::string> ValidateUrisForLaunch(unity::DndData& dnd_data); - const char* BamfName(); + const gchar* GetRemoteUri(); + std::string BamfName() const; - bool HandlesSpread () { return true; } + bool HandlesSpread() { return true; } + std::string GetName() const; private: - BamfApplication* m_App; - std::map<std::string, DbusmenuClient*> _menu_clients; - std::map<std::string, DbusmenuMenuitem*> _menu_items; - std::map<std::string, DbusmenuMenuitem*> _menu_items_extra; - std::map<std::string, gulong> _menu_callbacks; - DbusmenuMenuitem* _menu_desktop_shortcuts; - gchar* _remote_uri; - bool _dnd_hovered; - guint _dnd_hover_timer; - - gchar* _cached_desktop_file; - gchar* _cached_name; - - GFileMonitor* _desktop_file_monitor; - gulong _on_desktop_file_changed_handler_id; - - std::set<std::string> _supported_types; - bool _supported_types_filled; - guint _fill_supported_types_id; - guint32 _window_moved_id; - guint32 _window_moved_xid; - void EnsureWindowState(); - + void EnsureMenuItemsReady(); void UpdateDesktopFile(); void UpdateMenus(); void UpdateDesktopQuickList(); + void FillSupportedTypes(); void OpenInstanceWithUris(std::set<std::string> uris); void Focus(ActionArg arg); bool Spread(bool current_desktop, int state, bool force); - void EnsureMenuItemsReady(); - void OnWindowMinimized(guint32 xid); void OnWindowMoved(guint32 xid); - bool OwnsWindow(Window w); + + bool OwnsWindow(Window w) const; const std::set<std::string>& GetSupportedTypes(); - static void OnClosed(BamfView* view, gpointer data); - static void OnUserVisibleChanged(BamfView* view, gboolean visible, gpointer data); - static void OnActiveChanged(BamfView* view, gboolean active, gpointer data); - static void OnRunningChanged(BamfView* view, gboolean running, gpointer data); - static void OnUrgentChanged(BamfView* view, gboolean urgent, gpointer data); - static void OnChildAdded(BamfView* view, BamfView* child, gpointer data); - static void OnChildRemoved(BamfView* view, BamfView* child, gpointer data); - - static void OnQuit(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self); - static void OnLaunch(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self); - static void OnTogglePin(DbusmenuMenuitem* item, int time, BamfLauncherIcon* self); - - static void OnDesktopFileChanged(GFileMonitor* monitor, - GFile* file, - GFile* other_file, - GFileMonitorEvent event_type, - gpointer data); - - static gboolean OnDndHoveredTimeout(gpointer data); - static gboolean FillSupportedTypes(gpointer data); + + glib::Object<BamfApplication> _bamf_app; + bool _dnd_hovered; + guint _dnd_hover_timer; + + bool _supported_types_filled; + guint _fill_supported_types_id; + guint _window_moved_id; + + std::string _remote_uri; + std::string _desktop_file; + std::set<std::string> _supported_types; + std::map<std::string, glib::Object<DbusmenuClient>> _menu_clients; + std::map<std::string, glib::Object<DbusmenuMenuitem>> _menu_items; + std::map<std::string, glib::Object<DbusmenuMenuitem>> _menu_items_extra; + glib::Object<IndicatorDesktopShortcuts> _desktop_shortcuts; + glib::Object<DbusmenuMenuitem> _menu_desktop_shortcuts; + glib::Object<GFileMonitor> _desktop_file_monitor; + glib::SignalManager _gsignals; }; } diff --git a/plugins/unityshell/src/DashController.cpp b/plugins/unityshell/src/DashController.cpp index 592b8f9be..da1cd0159 100644 --- a/plugins/unityshell/src/DashController.cpp +++ b/plugins/unityshell/src/DashController.cpp @@ -37,7 +37,7 @@ nux::logging::Logger logger("unity.dash.controller"); } Controller::Controller() - : launcher_width(66) + : launcher_width(64) , panel_height(24) , window_(0) , visible_(false) @@ -118,6 +118,18 @@ void Controller::RegisterUBusInterests() sigc::mem_fun(this, &Controller::OnActivateRequest)); ubus_manager_.RegisterInterest(UBUS_DASH_ABOUT_TO_SHOW, [&] (GVariant*) { EnsureDash(); }); + 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); + + // hide if something else is coming up + if (g_strcmp0(overlay_identity, "dash")) + { + HideDash(true); + } + }); } void Controller::EnsureDash() @@ -243,7 +255,8 @@ void Controller::ShowDash() StartShowHideTimeline(); - ubus_manager_.SendMessage(UBUS_PLACE_VIEW_SHOWN, g_variant_new_int32(UScreen::GetDefault()->GetMonitorWithMouse())); + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, UScreen::GetDefault()->GetMonitorWithMouse()); + ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info); } void Controller::HideDash(bool restore) @@ -263,8 +276,9 @@ void Controller::HideDash(bool restore) PluginAdapter::Default ()->restoreInputFocus (); StartShowHideTimeline(); - - ubus_manager_.SendMessage(UBUS_PLACE_VIEW_HIDDEN); + + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, g_variant_new_int32(UScreen::GetDefault()->GetMonitorWithMouse())); + ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info); } void Controller::StartShowHideTimeline() diff --git a/plugins/unityshell/src/DashStyle.cpp b/plugins/unityshell/src/DashStyle.cpp index 94f819f62..a3f39c585 100644 --- a/plugins/unityshell/src/DashStyle.cpp +++ b/plugins/unityshell/src/DashStyle.cpp @@ -119,6 +119,7 @@ public: void Text(cairo_t* cr, nux::Color const& color, std::string const& label, + int font_size = -1, double horizMargin = 10.0, Alignment alignment = Alignment::CENTER); @@ -1325,6 +1326,7 @@ void Style::Impl::GetTextExtents(int& width, void Style::Impl::Text(cairo_t* cr, nux::Color const& color, std::string const& label, + int text_size, double horizMargin, Alignment alignment) { @@ -1358,6 +1360,11 @@ void Style::Impl::Text(cairo_t* cr, else desc = pango_font_description_from_string(fontName); + if (text_size > 0) + { + pango_font_description_set_absolute_size(desc, text_size * PANGO_SCALE); + } + PangoWeight weight; switch (regular_text_weight_) { @@ -1428,6 +1435,7 @@ void Style::Impl::Text(cairo_t* cr, pango_layout_get_extents(layout, &ink, &log); x = horizMargin; // let pango alignment handle the x position y = ((double) h - pango_units_to_double(log.height)) / 2.0; + cairo_move_to(cr, x, y); pango_cairo_show_layout(cr, layout); @@ -1530,7 +1538,9 @@ void Style::Impl::DrawOverlay(cairo_t* cr, cairo_set_operator(cr, old); } -bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, std::string const& label, Alignment alignment) +bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, + std::string const& label, int font_size, + Alignment alignment, bool zeromargin) { // sanity checks if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) @@ -1539,8 +1549,10 @@ bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, std::string const& if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE) return false; - unsigned int garnish = GetButtonGarnishSize(); - + unsigned int garnish = 0; + if (zeromargin == false) + garnish = GetButtonGarnishSize(); + //ButtonOutlinePath(cr, true); double w = cairo_image_surface_get_width(cairo_get_target(cr)); double h = cairo_image_surface_get_height(cairo_get_target(cr)); @@ -1571,7 +1583,6 @@ bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, std::string const& cairo_fill_preserve(cr); } cairo_set_source_rgba(cr, pimpl->button_label_border_color_[state]); - //cairo_set_line_width(cr, pimpl->button_label_border_size_[state]); cairo_stroke(cr); pimpl->DrawOverlay(cr, @@ -1582,12 +1593,133 @@ bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, std::string const& pimpl->Text(cr, pimpl->button_label_text_color_[state], label, + font_size, 10.0, alignment); return true; } +bool Style::SquareButton(cairo_t* cr, nux::ButtonVisualState state, + std::string const& label, bool curve_bottom, + int font_size, Alignment alignment, + bool zeromargin) +{ + // sanity checks + if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) + return false; + + if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE) + return false; + + unsigned int garnish = 0; + if (zeromargin == false) + garnish = GetButtonGarnishSize(); + + double w = cairo_image_surface_get_width(cairo_get_target(cr)); + double h = cairo_image_surface_get_height(cairo_get_target(cr)); + + double x = garnish; + double y = garnish; + + double width = w - (2.0 * garnish) - 1.0; + double height = h - (2.0 * garnish) - 1.0; + + bool odd = true; + double radius = 7.0; + + // draw the grid background + { + cairo_set_line_width(cr, 1); + cairo_move_to(cr, _align(x + width, odd), _align(y, odd)); + if (curve_bottom) + { + LOG_DEBUG(logger) << "curve: " << _align(x + width, odd) << " - " << _align(y + height - radius, odd); + // line to bottom-right corner + cairo_line_to(cr, _align(x + width, odd), _align(y + height - radius, odd)); + + // line to bottom-right, left of the corner + cairo_arc(cr, + _align(x + width - radius, odd), + _align(y + height - radius, odd), + radius, + 0.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + + // line to bottom-left, right of the corner + cairo_line_to(cr, _align(x + radius, odd), _align(y + height, odd)); + + // line to bottom-left, above the corner + cairo_arc(cr, + _align(x + radius, odd), + _align(y + height - radius, odd), + radius, + 90.0f * G_PI / 180.0f, + 180.0f * G_PI / 180.0f); + + // line to top + cairo_line_to(cr, _align(x, odd), _align(y, odd)); + } + else + { + cairo_line_to(cr, _align(x + width, odd), _align(y + height, odd)); + cairo_line_to(cr, _align(x, odd), _align(x + height, odd)); + cairo_line_to(cr, _align(x, odd), _align(y, odd)); + } + + cairo_set_source_rgba(cr, pimpl->button_label_border_color_[nux::ButtonVisualState::VISUAL_STATE_NORMAL]); + cairo_stroke(cr); + } + + cairo_set_line_width(cr, pimpl->button_label_border_size_[state]); + odd = cairo_get_line_width(cr) == 2.0 ? false : true; + + + if (pimpl->button_label_border_size_[state] == 2.0) + { + x += 1; + y += 1; + width -= 1.0; + height -= 1.0; + } + + if (state == nux::ButtonVisualState::VISUAL_STATE_PRESSED) + { + RoundedRect(cr, + 1.0, + _align(x, odd), _align(y, odd), + 5.0, + _align(width, odd), _align(height, odd)); + + if (pimpl->button_label_fill_color_[state].alpha != 0.0) + { + cairo_set_source_rgba(cr, pimpl->button_label_fill_color_[state]); + cairo_fill_preserve(cr); + } + cairo_set_source_rgba(cr, pimpl->button_label_border_color_[state]); + cairo_stroke(cr); + } + + pimpl->DrawOverlay(cr, + pimpl->button_label_overlay_opacity_[state], + pimpl->button_label_overlay_mode_[state], + pimpl->button_label_blur_size_[state] * 0.75); + + // FIXME - magic value of 42 here for the offset in the HUD, + // replace with a nicer style system that lets hud override + // default values when it needs to + pimpl->Text(cr, + pimpl->button_label_text_color_[state], + label, + font_size, + 42.0 + 10.0, + alignment); + + cairo_surface_write_to_png(cairo_get_target(cr), "/tmp/wut.png"); + + return true; +} + bool Style::StarEmpty(cairo_t* cr, nux::ButtonVisualState state) { // sanity checks diff --git a/plugins/unityshell/src/DashStyle.h b/plugins/unityshell/src/DashStyle.h index 0c06244f6..ba10f7c9d 100644 --- a/plugins/unityshell/src/DashStyle.h +++ b/plugins/unityshell/src/DashStyle.h @@ -87,8 +87,15 @@ public: static Style& Instance(); virtual bool Button(cairo_t* cr, nux::ButtonVisualState state, - std::string const& label, - Alignment alignment = Alignment::CENTER); + std::string const& label, int font_size=-1, + Alignment alignment = Alignment::CENTER, + bool zeromargin=false); + + virtual bool SquareButton(cairo_t* cr, nux::ButtonVisualState state, + std::string const& label, bool curve_bottom, + int font_size=-1, + Alignment alignment = Alignment::CENTER, + bool zeromargin=false); virtual bool StarEmpty(cairo_t* cr, nux::ButtonVisualState state); diff --git a/plugins/unityshell/src/DashView.h b/plugins/unityshell/src/DashView.h index 938950665..80b64ada5 100644 --- a/plugins/unityshell/src/DashView.h +++ b/plugins/unityshell/src/DashView.h @@ -30,7 +30,7 @@ #include <UnityCore/HomeLens.h> #include "BackgroundEffectHelper.h" -#include "DashSearchBar.h" +#include "SearchBar.h" #include "Introspectable.h" #include "LensBar.h" #include "LensView.h" diff --git a/plugins/unityshell/src/DeviceLauncherIcon.cpp b/plugins/unityshell/src/DeviceLauncherIcon.cpp index 59bac1d34..d29c4b286 100644 --- a/plugins/unityshell/src/DeviceLauncherIcon.cpp +++ b/plugins/unityshell/src/DeviceLauncherIcon.cpp @@ -130,6 +130,7 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus() { menu_item = dbusmenu_menuitem_new(); + // TRANSLATORS: This refers to the action of formatting a device dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Format...")); dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); diff --git a/plugins/unityshell/src/FilterAllButton.cpp b/plugins/unityshell/src/FilterAllButton.cpp index e3473d2ad..dc42e94f2 100644 --- a/plugins/unityshell/src/FilterAllButton.cpp +++ b/plugins/unityshell/src/FilterAllButton.cpp @@ -59,6 +59,7 @@ void FilterAllButton::OnStateChanged(nux::View* view) { if (filter_ and Active()) filter_->Clear(); + QueueDraw(); } void FilterAllButton::OnFilteringChanged(bool filtering) diff --git a/plugins/unityshell/src/HudButton.cpp b/plugins/unityshell/src/HudButton.cpp new file mode 100644 index 000000000..269ee401f --- /dev/null +++ b/plugins/unityshell/src/HudButton.cpp @@ -0,0 +1,208 @@ +/* + * Copyright 2011 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 applicable version of the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of both the GNU Lesser General Public + * License version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ +#include "config.h" + +#include <pango/pango.h> +#include <pango/pangocairo.h> +#include <gdk/gdk.h> +#include <gtk/gtk.h> + +#include <Nux/Nux.h> +#include <NuxCore/Logger.h> +#include <NuxImage/CairoGraphics.h> +#include <NuxGraphics/NuxGraphics.h> +#include <UnityCore/GLibWrapper.h> +#include "DashStyle.h" + +#include "HudButton.h" + +namespace +{ +nux::logging::Logger logger("unity.hud.HudButton"); +} + +namespace unity +{ +namespace hud +{ + + +HudButton::HudButton (nux::TextureArea *image, NUX_FILE_LINE_DECL) + : nux::Button (image, NUX_FILE_LINE_PARAM) + , is_rounded(false) + , is_focused_(false) +{ + InitTheme(); + key_nav_focus_change.connect([this](nux::Area *area, bool recieving, nux::KeyNavDirection direction){ QueueDraw(); }); +} + +HudButton::HudButton (const std::string label_, NUX_FILE_LINE_DECL) + : nux::Button (NUX_FILE_LINE_PARAM) + , is_rounded(false) + , is_focused_(false) +{ + InitTheme(); +} + +HudButton::HudButton (const std::string label_, nux::TextureArea *image, NUX_FILE_LINE_DECL) + : nux::Button (image, NUX_FILE_LINE_PARAM) + , is_rounded(false) + , is_focused_(false) +{ + InitTheme(); +} + +HudButton::HudButton (NUX_FILE_LINE_DECL) + : nux::Button (NUX_FILE_LINE_PARAM) + , is_rounded(false) + , is_focused_(false) +{ + InitTheme(); +} + +HudButton::~HudButton() { +} + +void HudButton::InitTheme() +{ + is_rounded.changed.connect([&] (bool rounded) + { + nux::Geometry geo = GetGeometry(); + prelight_->Invalidate(geo); + active_->Invalidate(geo); + normal_->Invalidate(geo); + }); + + SetMinimumHeight(42); + if (!active_) + { + nux::Geometry const& geo = GetGeometry(); + + prelight_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRELIGHT))); + active_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRESSED))); + normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL))); + } +} + +void HudButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state) +{ + dash::Style::Instance().SquareButton(cr, faked_state, label_, + is_rounded, 17, + dash::Alignment::LEFT, true); +} + +bool HudButton::AcceptKeyNavFocus() +{ + return true; +} + + +long HudButton::ComputeContentSize () +{ + long ret = nux::Button::ComputeContentSize(); + nux::Geometry const& geo = GetGeometry(); + + if (cached_geometry_ != geo) + { + prelight_->Invalidate(geo); + active_->Invalidate(geo); + normal_->Invalidate(geo); + + cached_geometry_ = geo; + } + + return ret; +} + +void HudButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry const& geo = GetGeometry(); + gPainter.PaintBackground(GfxContext, geo); + // set up our texture mode + nux::TexCoordXForm texxform; + texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + + // clear what is behind us + unsigned int alpha = 0, src = 0, dest = 0; + GfxContext.GetRenderStates().GetBlend(alpha, src, dest); + GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + GfxContext.GetRenderStates().SetBlend(true); + + nux::Color col = nux::color::Black; + col.alpha = 0; + GfxContext.QRP_Color(geo.x, + geo.y, + geo.width, + geo.height, + col); + + nux::BaseTexture* texture = normal_->GetTexture(); + if (HasKeyFocus()) + texture = active_->GetTexture(); + else if (HasKeyFocus()) + texture = prelight_->GetTexture(); + else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED) + texture = active_->GetTexture(); + + GfxContext.QRP_1Tex(geo.x, + geo.y, + texture->GetWidth() + 1, // FIXME !! - jay, nux has gone crazy, unless i specify +1 here, it won't render the entire texture + texture->GetHeight(), + texture->GetDeviceTexture(), + texxform, + nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + + GfxContext.GetRenderStates().SetBlend(alpha, src, dest); +} + +void HudButton::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { +} + +void HudButton::PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw) { + nux::Button::PostDraw(GfxContext, force_draw); +} + +void HudButton::SetQuery(Query::Ptr query) +{ + query_ = query; + label_ = query->formatted_text; + label = query->formatted_text; +} + +Query::Ptr HudButton::GetQuery() +{ + return query_; +} + +// Introspectable +std::string HudButton::GetName() const +{ + return "HudButton"; +} + +void HudButton::AddProperties(GVariantBuilder* builder) +{ + g_variant_builder_add(builder, "{sv}", "label", g_variant_new_string(label_.c_str())); +} + +} +} diff --git a/plugins/unityshell/src/HudButton.h b/plugins/unityshell/src/HudButton.h new file mode 100644 index 000000000..ef55760d3 --- /dev/null +++ b/plugins/unityshell/src/HudButton.h @@ -0,0 +1,81 @@ +/* + * Copyright 2011 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 applicable version of the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of both the GNU Lesser General Public + * License version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ + + + +#ifndef FILTERBASICBUTTON_H +#define FILTERBASICBUTTON_H + +#include <Nux/Nux.h> +#include <Nux/CairoWrapper.h> +#include <Nux/Button.h> +#include <Nux/TextureArea.h> +#include <UnityCore/Hud.h> +#include "Introspectable.h" + +namespace unity { +namespace hud { +class HudButton : public nux::Button, public unity::debug::Introspectable +{ + typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr; +public: + typedef nux::ObjectPtr<HudButton> Ptr; + HudButton (nux::TextureArea *image, NUX_FILE_LINE_PROTO); + HudButton (const std::string label, NUX_FILE_LINE_PROTO); + HudButton (const std::string label, nux::TextureArea *image, NUX_FILE_LINE_PROTO); + HudButton (NUX_FILE_LINE_PROTO); + virtual ~HudButton(); + + void SetQuery(Query::Ptr query); + std::shared_ptr<Query> GetQuery(); + + nux::Property<std::string> label; + nux::Property<std::string> hint; + nux::Property<bool> is_rounded; +protected: + + virtual bool AcceptKeyNavFocus(); + virtual long ComputeContentSize(); + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw); + + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + + void InitTheme (); + void RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state); + typedef std::unique_ptr<nux::CairoWrapper> NuxCairoPtr; + + NuxCairoPtr prelight_; + NuxCairoPtr active_; + NuxCairoPtr normal_; + +private: + std::string label_; + + Query::Ptr query_; + nux::Geometry cached_geometry_; + bool is_focused_; +}; +} +} +#endif // FILTERBASICBUTTON_H diff --git a/plugins/unityshell/src/HudController.cpp b/plugins/unityshell/src/HudController.cpp new file mode 100644 index 000000000..bf02375f2 --- /dev/null +++ b/plugins/unityshell/src/HudController.cpp @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gord Allott <gord.allott@canonical.com> + */ + +#include "HudController.h" + +#include <NuxCore/Logger.h> +#include <Nux/HLayout.h> +#include "PluginAdapter.h" +#include "UBusMessages.h" +#include "UScreen.h" +namespace unity +{ +namespace hud +{ + +namespace +{ +nux::logging::Logger logger("unity.hud.controller"); +} + +Controller::Controller() + : launcher_width(66) + , panel_height(24) + , hud_service_("com.canonical.hud", "/com/canonical/hud") + , window_(0) + , visible_(false) + , need_show_(false) + , timeline_id_(0) + , last_opacity_(0.0f) + , start_time_(0) +{ + LOG_DEBUG(logger) << "hud startup"; + SetupRelayoutCallbacks(); + + ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud)); + + //!!FIXME!! - just hijacks the dash close request so we get some more requests than normal, + ubus.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud)); + + ubus.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); + + if (g_strcmp0(overlay_identity, "hud")) + { + HideHud(true); + } + }); + + PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed)); + + hud_service_.queries_updated.connect(sigc::mem_fun(this, &Controller::OnQueriesFinished)); + EnsureHud(); +} + +Controller::~Controller() +{ + if (window_) + window_->UnReference(); + window_ = 0; + + g_source_remove(timeline_id_); + g_source_remove(ensure_id_); +} + +void Controller::SetupWindow() +{ + window_ = new nux::BaseWindow("Hud"); + window_->SinkReference(); + window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); + window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this); + window_->ShowWindow(false); + window_->SetOpacity(0.0f); + window_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow)); +} + +void Controller::SetupHudView() +{ + LOG_DEBUG(logger) << "SetupHudView called"; + view_ = new View(); + + layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); + layout_->AddView(view_, 1); + window_->SetLayout(layout_); + + view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow)); + + LOG_DEBUG(logger) << "connecting to signals"; + view_->search_changed.connect(sigc::mem_fun(this, &Controller::OnSearchChanged)); + view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated)); + view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated)); + view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected)); +} + +void Controller::SetupRelayoutCallbacks() +{ + GdkScreen* screen = gdk_screen_get_default(); + + sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen, + "monitors-changed", sigc::mem_fun(this, &Controller::Relayout))); + sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen, + "size-changed", sigc::mem_fun(this, &Controller::Relayout))); +} + +void Controller::EnsureHud() +{ + if (window_) + return; + + LOG_DEBUG(logger) << "Initializing Hud"; + + SetupWindow(); + SetupHudView(); + Relayout(); + ensure_id_ = 0; +} + +nux::BaseWindow* Controller::window() const +{ + return window_; +} + +// We update the @geo that's sent in with our desired width and height +void Controller::OnWindowConfigure(int window_width, int window_height, + nux::Geometry& geo, void* data) +{ + Controller* self = static_cast<Controller*>(data); + geo = self->GetIdealWindowGeometry(); +} + +nux::Geometry Controller::GetIdealWindowGeometry() +{ + UScreen *uscreen = UScreen::GetDefault(); + int primary_monitor = uscreen->GetPrimaryMonitor(); + auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor); + + // We want to cover as much of the screen as possible to grab any mouse events outside + // of our window + return nux::Geometry (monitor_geo.x, + monitor_geo.y + panel_height, + monitor_geo.width, + monitor_geo.height - panel_height); +} + +void Controller::Relayout(GdkScreen*screen) +{ + EnsureHud(); + nux::Geometry content_geo = view_->GetGeometry(); + nux::Geometry geo = GetIdealWindowGeometry(); + + window_->SetGeometry(geo); + layout_->SetMinMaxSize(content_geo.width, content_geo.height); + view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry()); + view_->Relayout(); +} + +void Controller::OnMouseDownOutsideWindow(int x, int y, + unsigned long bflags, unsigned long kflags) +{ + LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called"; + HideHud(); +} + +void Controller::OnScreenUngrabbed() +{ + LOG_DEBUG(logger) << "OnScreenUngrabbed called"; + if (need_show_) + { + EnsureHud(); + ShowHud(); + } +} + +void Controller::OnExternalShowHud(GVariant* variant) +{ + EnsureHud(); + visible_ ? HideHud() : ShowHud(); +} + +void Controller::OnExternalHideHud(GVariant* variant) +{ + LOG_DEBUG(logger) << "External Hiding the hud"; + EnsureHud(); + HideHud(); +} + +void Controller::ShowHideHud() +{ + EnsureHud(); + visible_ ? HideHud(true) : ShowHud(); +} + +bool Controller::IsVisible() +{ + return visible_; +} + +void Controller::ShowHud() +{ + LOG_DEBUG(logger) << "Showing the hud"; + EnsureHud(); + view_->AboutToShow(); + + window_->ShowWindow(true); + window_->PushToFront(); + window_->EnableInputWindow(true, "Hud", true, false); + window_->SetInputFocus(); + nux::GetWindowCompositor().SetKeyFocusArea(view_->default_focus()); + window_->CaptureMouseDownAnyWhereElse(true); + view_->CaptureMouseDownAnyWhereElse(true); + window_->QueueDraw(); + + view_->ResetToDefault(); + + view_->SetIcon(""); + hud_service_.RequestQuery(""); + need_show_ = false; + visible_ = true; + + StartShowHideTimeline(); + view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry()); + + // hide the launcher + GVariant* message_data = g_variant_new("(b)", TRUE); + ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); + + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, 0); + ubus.SendMessage(UBUS_OVERLAY_SHOWN, info); +} +void Controller::HideHud(bool restore) +{ + LOG_DEBUG (logger) << "hiding the hud"; + if (visible_ == false) + return; + + EnsureHud(); + view_->AboutToHide(); + window_->CaptureMouseDownAnyWhereElse(false); + window_->EnableInputWindow(false, "Hud", true, false); + visible_ = false; + + StartShowHideTimeline(); + + restore = true; + if (restore) + PluginAdapter::Default ()->restoreInputFocus (); + + hud_service_.CloseQuery(); + + //unhide the launcher + GVariant* message_data = g_variant_new("(b)", FALSE); + ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data); + + GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, 0); + ubus.SendMessage(UBUS_OVERLAY_HIDDEN, info); +} + +void Controller::StartShowHideTimeline() +{ + EnsureHud(); + + if (timeline_id_) + g_source_remove(timeline_id_); + + timeline_id_ = g_timeout_add(15, (GSourceFunc)Controller::OnViewShowHideFrame, this); + last_opacity_ = window_->GetOpacity(); + start_time_ = g_get_monotonic_time(); + +} + +gboolean Controller::OnViewShowHideFrame(Controller* self) +{ +#define _LENGTH_ 90000 + float diff = g_get_monotonic_time() - self->start_time_; + float progress = diff / (float)_LENGTH_; + float last_opacity = self->last_opacity_; + + if (self->visible_) + { + self->window_->SetOpacity(last_opacity + ((1.0f - last_opacity) * progress)); + } + else + { + self->window_->SetOpacity(last_opacity - (last_opacity * progress)); + } + + if (diff > _LENGTH_) + { + self->timeline_id_ = 0; + + // Make sure the state is right + self->window_->SetOpacity(self->visible_ ? 1.0f : 0.0f); + if (!self->visible_) + { + self->window_->ShowWindow(false); + } + + return FALSE; + } + + return TRUE; +} + +void Controller::OnActivateRequest(GVariant* variant) +{ + EnsureHud(); + ShowHud(); +} + +void Controller::OnSearchChanged(std::string search_string) +{ + LOG_DEBUG(logger) << "Search Changed"; + hud_service_.RequestQuery(search_string); +} + +void Controller::OnSearchActivated(std::string search_string) +{ + unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp; + hud_service_.ExecuteQueryBySearch(search_string, timestamp); + HideHud(); +} + +void Controller::OnQueryActivated(Query::Ptr query) +{ + LOG_DEBUG(logger) << "Activating query, " << query->formatted_text; + unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp; + hud_service_.ExecuteQuery(query, timestamp); + HideHud(); +} + +void Controller::OnQuerySelected(Query::Ptr query) +{ + LOG_DEBUG(logger) << "Selected query, " << query->formatted_text; + view_->SetIcon(query->icon_name); +} + + +void Controller::OnQueriesFinished(Hud::Queries queries) +{ + view_->SetQueries(queries); + std::string icon_name = ""; + for (auto query = queries.begin(); query != queries.end(); query++) + { + if (!(*query)->icon_name.empty()) + { + icon_name = (*query)->icon_name; + break; + } + } + + LOG_DEBUG(logger) << "setting icon to - " << icon_name; + view_->SetIcon(icon_name); +} + +// Introspectable +std::string Controller::GetName() const +{ + return "HudController"; +} + +void Controller::AddProperties(GVariantBuilder* builder) +{ + g_variant_builder_add(builder, "{sv}", "visible", g_variant_new_boolean (visible_)); +} + + +} +} diff --git a/plugins/unityshell/src/HudController.h b/plugins/unityshell/src/HudController.h new file mode 100644 index 000000000..211842404 --- /dev/null +++ b/plugins/unityshell/src/HudController.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef UNITY_HUD_CONTROLLER_H_ +#define UNITY_HUD_CONTROLLER_H_ + +#include <memory> + +#include <gdk/gdk.h> +#include <UnityCore/GLibSignal.h> +#include <UnityCore/Hud.h> + +#include <NuxCore/Property.h> +#include <NuxGraphics/GraphicsEngine.h> +#include <Nux/Nux.h> +#include <Nux/BaseWindow.h> + +#include "HudView.h" +#include "UBusWrapper.h" + +namespace unity +{ +namespace hud +{ + +class Controller : public unity::debug::Introspectable +{ +public: + typedef std::shared_ptr<Controller> Ptr; + + Controller(); + ~Controller(); + + nux::BaseWindow* window() const; + + nux::Property<int> launcher_width; + nux::Property<int> panel_height; + + void ShowHideHud(); + void ShowHud(); + void HideHud(bool restore_focus = true); + bool IsVisible(); +protected: + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + +private: + void EnsureHud(); + void SetupWindow(); + void SetupHudView(); + void SetupRelayoutCallbacks(); + void RegisterUBusInterests(); + + nux::Geometry GetIdealWindowGeometry(); + void Relayout(GdkScreen*screen=NULL); + + void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags); + void OnScreenUngrabbed(); + void OnExternalShowHud(GVariant* variant); + void OnExternalHideHud(GVariant* variant); + void OnActivateRequest(GVariant* variant); + + void OnSearchChanged(std::string search_string); + void OnSearchActivated(std::string search_string); + void OnQueryActivated(Query::Ptr query); + void OnQuerySelected(Query::Ptr query); + + +private: + void StartShowHideTimeline(); + static gboolean OnViewShowHideFrame(Controller* self); + + static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data); + + void OnQueriesFinished(Hud::Queries queries); + +private: + UBusManager ubus; + Hud hud_service_; + glib::SignalManager sig_manager_; + nux::BaseWindow* window_; + bool visible_; + bool need_show_; + + guint timeline_id_; + float last_opacity_; + gint64 start_time_; + + View* view_; + guint ensure_id_; + + nux::Layout* layout_; +}; + + +} +} +#endif diff --git a/plugins/unityshell/src/HudIcon.cpp b/plugins/unityshell/src/HudIcon.cpp new file mode 100644 index 000000000..d0128ff42 --- /dev/null +++ b/plugins/unityshell/src/HudIcon.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gord Allott <gord.allott@canonical.com> + */ + + +#include "HudIcon.h" +#include "NuxCore/Logger.h" +namespace +{ + nux::logging::Logger logger("unity.hud.icon"); +} + +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) +{ + Init(); +} + +Icon::~Icon() +{ +} + +void Icon::Init() +{ + SetMinimumWidth(66); + SetMinimumHeight(66); + background_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_back_54.png", -1, true); + gloss_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_shine_54.png", -1, true); + edge_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_edge_54.png", -1, true); + + texture_updated.connect([&] (nux::BaseTexture* texture) + { + icon_texture_source_ = new HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture>(texture)); + icon_texture_source_->ColorForIcon(_pixbuf_cached); + QueueDraw(); + LOG_DEBUG(logger) << "got our texture"; + }); +} + +void Icon::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + if (texture() == nullptr) + return; + + unity::ui::RenderArg arg; + arg.icon = icon_texture_source_.GetPointer(); + arg.colorify = nux::color::White; + arg.running_arrow = true; + arg.running_on_viewport = true; + arg.render_center = nux::Point3(32, 32, 0); + arg.logical_center = nux::Point3(52, 50, 0); + arg.window_indicators = true; + arg.backlight_intensity = 1.0f; + arg.alpha = 1.0f; + + std::list<unity::ui::RenderArg> args; + args.push_front(arg); + + + auto toplevel = GetToplevel(); + icon_renderer_.SetTargetSize(54, 46, 0); + icon_renderer_.PreprocessIcons(args, toplevel->GetGeometry()); + icon_renderer_.RenderIcon(GfxContext, arg, toplevel->GetGeometry(), toplevel->GetGeometry()); +} + + +} +} + diff --git a/plugins/unityshell/src/HudIcon.h b/plugins/unityshell/src/HudIcon.h new file mode 100644 index 000000000..5e24b518b --- /dev/null +++ b/plugins/unityshell/src/HudIcon.h @@ -0,0 +1,73 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gord Allott <gord.allott@canonical.com> + * + */ + +#ifndef HUDICON_H +#define HUDICON_H + +#include <set> +#include <string> + +#include "config.h" + +#include <Nux/Nux.h> +#include <Nux/BaseWindow.h> +#include <NuxCore/Math/MathInc.h> + +#include <sigc++/trackable.h> +#include <sigc++/signal.h> +#include <sigc++/functors/ptr_fun.h> +#include <sigc++/functors/mem_fun.h> + +#include <gtk/gtk.h> + +#include "IconTexture.h" +#include "HudIconTextureSource.h" +#include "IconRenderer.h" +#include "Introspectable.h" + +namespace unity +{ +namespace hud +{ + +class Icon : public unity::IconTexture +{ +public: + typedef nux::ObjectPtr<IconTexture> Ptr; + Icon(nux::BaseTexture* texture, guint width, guint height); + Icon(const char* icon_name, unsigned int size, bool defer_icon_loading = false); + ~Icon(); + +protected: + void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + void Init(); + + nux::ObjectPtr<nux::BaseTexture> background_; + nux::ObjectPtr<nux::BaseTexture> gloss_; + nux::ObjectPtr<nux::BaseTexture> edge_; + nux::ObjectPtr<HudIconTextureSource> icon_texture_source_; + unity::ui::IconRenderer icon_renderer_; +}; + +} + +} + +#endif /* HUDICON_H */ diff --git a/plugins/unityshell/src/HudIconTextureSource.cpp b/plugins/unityshell/src/HudIconTextureSource.cpp new file mode 100644 index 000000000..3e9f06736 --- /dev/null +++ b/plugins/unityshell/src/HudIconTextureSource.cpp @@ -0,0 +1,110 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + + +#include "HudIconTextureSource.h" +#include "config.h" + +#include <glib.h> + +#include <Nux/Nux.h> +#include <NuxCore/Logger.h> + + +namespace unity +{ +namespace hud +{ + +HudIconTextureSource::HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture> texture) + : unity::ui::IconTextureSource() + , icon_texture_(texture) +{ +} + +HudIconTextureSource::~HudIconTextureSource() +{ +} + +void HudIconTextureSource::ColorForIcon(GdkPixbuf* pixbuf) +{ + unsigned int width = gdk_pixbuf_get_width(pixbuf); + unsigned int height = gdk_pixbuf_get_height(pixbuf); + unsigned int row_bytes = gdk_pixbuf_get_rowstride(pixbuf); + + long int rtotal = 0, gtotal = 0, btotal = 0; + float total = 0.0f; + + guchar* img = gdk_pixbuf_get_pixels(pixbuf); + + for (unsigned int i = 0; i < width; i++) + { + for (unsigned int j = 0; j < height; j++) + { + guchar* pixels = img + (j * row_bytes + i * 4); + guchar r = *(pixels + 0); + guchar g = *(pixels + 1); + guchar b = *(pixels + 2); + guchar a = *(pixels + 3); + + float saturation = (MAX(r, MAX(g, b)) - MIN(r, MIN(g, b))) / 255.0f; + float relevance = .1 + .9 * (a / 255.0f) * saturation; + + rtotal += (guchar)(r * relevance); + gtotal += (guchar)(g * relevance); + btotal += (guchar)(b * relevance); + + total += relevance * 255; + } + } + + nux::color::RedGreenBlue rgb(rtotal / total, + gtotal / total, + btotal / total); + nux::color::HueSaturationValue hsv(rgb); + + if (hsv.saturation > 0.15f) + hsv.saturation = 0.65f; + + hsv.value = 0.90f; + bg_color = nux::Color(nux::color::RedGreenBlue(hsv)); +} + +nux::Color HudIconTextureSource::BackgroundColor() +{ + return bg_color; +} + +nux::BaseTexture* HudIconTextureSource::TextureForSize(int size) +{ + return icon_texture_.GetPointer(); +} + +nux::Color HudIconTextureSource::GlowColor() +{ + return nux::Color(0.0f, 0.0f, 0.0f, 0.0f); +} + +nux::BaseTexture* HudIconTextureSource::Emblem() +{ + return nullptr; +} + +} +} \ No newline at end of file diff --git a/plugins/unityshell/src/HudIconTextureSource.h b/plugins/unityshell/src/HudIconTextureSource.h new file mode 100644 index 000000000..e0537f9c2 --- /dev/null +++ b/plugins/unityshell/src/HudIconTextureSource.h @@ -0,0 +1,51 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + + +#ifndef HUDICONTEXTURESOURCE_H +#define HUDICONTEXTURESOURCE_H + +#include "IconTextureSource.h" + +namespace unity +{ +namespace hud +{ + +class HudIconTextureSource : public unity::ui::IconTextureSource +{ +public: + HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture> texture); + ~HudIconTextureSource(); + + virtual nux::Color BackgroundColor(); + virtual nux::BaseTexture* TextureForSize(int size); + virtual nux::Color GlowColor(); + virtual nux::BaseTexture* Emblem(); + void ColorForIcon(GdkPixbuf* pixbuf); + +private: + nux::Color bg_color; + nux::ObjectPtr<nux::BaseTexture> icon_texture_; +}; + +} +} + +#endif // HUDICONTEXTURESOURCE_H diff --git a/plugins/unityshell/src/HudView.cpp b/plugins/unityshell/src/HudView.cpp new file mode 100644 index 000000000..3abbd01c8 --- /dev/null +++ b/plugins/unityshell/src/HudView.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gord Allott <gord.allott@canonical.com> + */ + +#include "HudView.h" + +#include <math.h> + +#include <gio/gdesktopappinfo.h> +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> +#include <Nux/Button.h> +#include <iostream> +#include <sstream> + +#include <NuxCore/Logger.h> +#include <UnityCore/GLibWrapper.h> +#include <UnityCore/RadioOptionFilter.h> +#include <Nux/HLayout.h> +#include <Nux/LayeredLayout.h> + +#include <NuxCore/Logger.h> +#include "HudButton.h" +#include "UBusMessages.h" +#include "DashStyle.h" + +namespace unity +{ +namespace hud +{ + +namespace +{ +nux::logging::Logger logger("unity.hud.view"); +int icon_size = 42; +const std::string default_text = _("Type your command"); +} + +NUX_IMPLEMENT_OBJECT_TYPE(View); + +View::View() + : nux::View(NUX_TRACKER_LOCATION) + , button_views_(NULL) +{ + renderer_.SetOwner(this); + renderer_.need_redraw.connect([this] () { + QueueDraw(); + }); + + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + SetupViews(); + search_bar_->key_down.connect (sigc::mem_fun (this, &View::OnKeyDown)); + + search_bar_->activated.connect ([&]() { + search_activated.emit(search_bar_->search_string); + }); + + mouse_down.connect(sigc::mem_fun(this, &View::OnMouseButtonDown)); + + Relayout(); + +} + +View::~View() +{ + RemoveChild(search_bar_.GetPointer()); + for (auto button = buttons_.begin(); button != buttons_.end(); button++) + { + RemoveChild((*button).GetPointer()); + } +} + +void View::ResetToDefault() +{ + search_bar_->search_string = ""; + search_bar_->search_hint = default_text; +} + +void View::Relayout() +{ + nux::Geometry geo = GetGeometry(); + content_geo_ = GetBestFitGeometry(geo); + LOG_DEBUG(logger) << "content_geo: " << content_geo_.width << "x" << content_geo_.height; + + layout_->SetMinMaxSize(content_geo_.width, content_geo_.height); + + QueueDraw(); +} + +long View::PostLayoutManagement(long LayoutResult) +{ + Relayout(); + return LayoutResult; +} + + +nux::View* View::default_focus() const +{ + return search_bar_->text_entry(); +} + +void View::SetQueries(Hud::Queries queries) +{ + // remove the previous children + for (auto button = buttons_.begin(); button != buttons_.end(); button++) + { + RemoveChild((*button).GetPointer()); + } + + queries_ = queries_; + buttons_.clear(); + button_views_->Clear(); + int found_items = 0; + for (auto query = queries.begin(); query != queries.end(); query++) + { + if (found_items > 5) + break; + + HudButton::Ptr button = HudButton::Ptr(new HudButton()); + buttons_.push_front(button); + button->SetQuery(*query); + button_views_->AddView(button.GetPointer(), 0, nux::MINOR_POSITION_LEFT); + + button->click.connect([&](nux::View* view) { + query_activated.emit(dynamic_cast<HudButton*>(view)->GetQuery()); + }); + + button->key_nav_focus_activate.connect([&](nux::Area *area) { + query_activated.emit(dynamic_cast<HudButton*>(area)->GetQuery()); + }); + + button->key_nav_focus_change.connect([&](nux::Area *area, bool recieving, KeyNavDirection direction){ + if (recieving) + query_selected.emit(dynamic_cast<HudButton*>(area)->GetQuery()); + }); + + button->is_rounded = (query == --(queries.end())) ? true : false; + button->SetMinimumWidth(941); + found_items++; + } + + QueueRelayout(); + QueueDraw(); +} + +void View::SetIcon(std::string icon_name) +{ + LOG_DEBUG(logger) << "Setting icon to " << icon_name; + icon_->SetByIconName(icon_name.c_str(), icon_size); + QueueDraw(); +} + +// Gives us the width and height of the contents that will give us the best "fit", +// which means that the icons/views will not have uneccessary padding, everything will +// look tight +nux::Geometry View::GetBestFitGeometry(nux::Geometry const& for_geo) +{ + //FIXME - remove magic values, replace with scalable text depending on DPI + // requires smarter font settings really... + int width, height = 0; + width = 1024; + height = 276; + + LOG_DEBUG (logger) << "best fit is, " << width << ", " << height; + + return nux::Geometry(0, 0, width, height); +} + +void View::AboutToShow() +{ + renderer_.AboutToShow(); +} + +void View::AboutToHide() +{ + renderer_.AboutToHide(); +} + +void View::SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo) +{ + window_geometry_ = geo; + window_geometry_.x = 0; + window_geometry_.y = 0; + 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; +} + +void View::SetupViews() +{ + layout_ = new nux::HLayout(); + + icon_ = new Icon("", icon_size, true); + nux::Layout* icon_layout = new nux::VLayout(); + icon_layout->SetVerticalExternalMargin(icon_vertical_margin); + icon_layout->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL); + layout_->AddLayout(icon_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT); + 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); + + + content_layout_ = new nux::VLayout(); + layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP); + SetLayout(layout_.GetPointer()); + + // add the top spacing + content_layout_->AddLayout(new nux::SpaceLayout(top_spacing,top_spacing,top_spacing,top_spacing), 0); + + // add the search bar to the composite + search_bar_ = new unity::SearchBar(content_width, true); + search_bar_->disable_glow = true; + search_bar_->search_hint = default_text; + search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged)); + AddChild(search_bar_.GetPointer()); + content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT); + + button_views_ = new nux::VLayout(); + button_views_->SetMaximumWidth(content_width); + + content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT); +} + +void View::OnSearchChanged(std::string const& search_string) +{ + LOG_DEBUG(logger) << "got search change"; + search_changed.emit(search_string); + if (search_string.empty()) + { + search_bar_->search_hint = default_text; + } + else + { + search_bar_->search_hint = ""; + } +} + + +void View::OnKeyDown (unsigned long event_type, unsigned long keysym, + unsigned long event_state, const TCHAR* character, + unsigned short key_repeat_count) +{ + if (keysym == NUX_VK_ESCAPE) + { + LOG_DEBUG(logger) << "got escape key"; + ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST); + } +} + +void View::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key) +{ + if (!content_geo_.IsPointInside(x, y)) + { + ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST); + } +} + +void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw) +{ + renderer_.DrawFull(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_, true); +} + +void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw) +{ + renderer_.DrawInner(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_); + + if (IsFullRedraw()) + { + nux::GetPainter().PushBackgroundStack(); + layout_->ProcessDraw(gfx_context, force_draw); + nux::GetPainter().PopBackgroundStack(); + } + else + { + layout_->ProcessDraw(gfx_context, force_draw); + } + + renderer_.DrawInnerCleanup(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_); +} + +// Keyboard navigation +bool View::AcceptKeyNavFocus() +{ + return false; +} + +// Introspectable +std::string View::GetName() const +{ + return "HudView"; +} + +void View::AddProperties(GVariantBuilder* builder) +{ + +} + +bool View::InspectKeyEvent(unsigned int eventType, + unsigned int key_sym, + const char* character) +{ + if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ESCAPE)) + { + if (search_bar_->search_string == "") + { + ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST); + } + else + { + search_bar_->search_string = ""; + search_bar_->search_hint = default_text; + } + return true; + } + return false; +} + +nux::Area* View::FindKeyFocusArea(unsigned int key_symbol, + unsigned long x11_key_code, + unsigned long special_keys_state) +{ + // Do what nux::View does, but if the event isn't a key navigation, + // designate the text entry to process it. + + nux::KeyNavDirection direction = nux::KEY_NAV_NONE; + switch (x11_key_code) + { + case NUX_VK_UP: + direction = nux::KEY_NAV_UP; + break; + case NUX_VK_DOWN: + direction = nux::KEY_NAV_DOWN; + break; + case NUX_VK_LEFT: + direction = nux::KEY_NAV_LEFT; + break; + case NUX_VK_RIGHT: + direction = nux::KEY_NAV_RIGHT; + break; + case NUX_VK_LEFT_TAB: + direction = nux::KEY_NAV_TAB_PREVIOUS; + break; + case NUX_VK_TAB: + direction = nux::KEY_NAV_TAB_NEXT; + break; + case NUX_VK_ENTER: + case NUX_KP_ENTER: + // Not sure if Enter should be a navigation key + direction = nux::KEY_NAV_ENTER; + break; + default: + direction = nux::KEY_NAV_NONE; + break; + } + + if (has_key_focus_) + { + return this; + } + else if (direction == nux::KEY_NAV_NONE) + { + // then send the event to the search entry + return search_bar_->text_entry(); + } + else if (next_object_to_key_focus_area_) + { + return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); + } + return NULL; +} + +} +} diff --git a/plugins/unityshell/src/HudView.h b/plugins/unityshell/src/HudView.h new file mode 100644 index 000000000..b0a54d740 --- /dev/null +++ b/plugins/unityshell/src/HudView.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef UNITY_HUD_VIEW_H_ +#define UNITY_HUD_VIEW_H_ + +#include <string> + +#include <NuxGraphics/GraphicsEngine.h> +#include <Nux/Nux.h> +#include <Nux/PaintLayer.h> +#include <Nux/View.h> +#include <Nux/VLayout.h> +#include <StaticCairoText.h> + +#include <glib.h> + +#include <UnityCore/Hud.h> +#include "Introspectable.h" + +#include "UBusWrapper.h" +#include "HudIcon.h" +#include "HudButton.h" +#include "SearchBar.h" +#include "OverlayRenderer.h" + +namespace unity +{ +namespace hud +{ + +class View : public nux::View, public unity::debug::Introspectable +{ + NUX_DECLARE_OBJECT_TYPE(HudView, nux::View); + typedef nux::ObjectPtr<View> Ptr; +public: + View(); + ~View(); + + void ResetToDefault(); + + void Relayout(); + nux::View* default_focus() const; + + void SetQueries(Hud::Queries queries); + void SetIcon(std::string icon_name); + + void AboutToShow(); + void AboutToHide(); + + void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo); + + sigc::signal<void, std::string> search_changed; + sigc::signal<void, std::string> search_activated; + sigc::signal<void, Query::Ptr> query_activated; + sigc::signal<void, Query::Ptr> query_selected; + +protected: + virtual Area* FindKeyFocusArea(unsigned int key_symbol, + unsigned long x11_key_code, + unsigned long special_keys_state); + + void SetupViews(); + void OnSearchChanged(std::string const& search_string); + virtual long PostLayoutManagement(long LayoutResult); +private: + void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key); + void OnKeyDown (unsigned long event_type, unsigned long event_keysym, + unsigned long event_state, const TCHAR* character, + unsigned short key_repeat_count); + 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); + bool AcceptKeyNavFocus(); + nux::Geometry GetBestFitGeometry(nux::Geometry const& for_geo); + + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + +private: + UBusManager ubus; + nux::ObjectPtr<nux::Layout> layout_; + nux::ObjectPtr<nux::Layout> content_layout_; + nux::ObjectPtr<nux::VLayout> button_views_; + std::list<HudButton::Ptr> buttons_; + + //FIXME - replace with dash search bar once modifications to dash search bar land + SearchBar::Ptr search_bar_; + Icon::Ptr icon_; + bool visible_; + + Hud::Queries queries_; + nux::Geometry content_geo_; + OverlayRenderer renderer_; + nux::Geometry window_geometry_; + nux::Geometry absolute_window_geometry_; +}; + + +} +} +#endif + diff --git a/plugins/unityshell/src/IMTextEntry.cpp b/plugins/unityshell/src/IMTextEntry.cpp index 1704a5561..bc1b217c6 100644 --- a/plugins/unityshell/src/IMTextEntry.cpp +++ b/plugins/unityshell/src/IMTextEntry.cpp @@ -27,12 +27,10 @@ namespace unity { -namespace dash -{ namespace { -nux::logging::Logger logger("unity.dash.imtextentry"); +nux::logging::Logger logger("unity.imtextentry"); } NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry); @@ -338,4 +336,3 @@ void IMTextEntry::OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned l } } -} diff --git a/plugins/unityshell/src/IMTextEntry.h b/plugins/unityshell/src/IMTextEntry.h index 9209c84f5..ab847bae6 100644 --- a/plugins/unityshell/src/IMTextEntry.h +++ b/plugins/unityshell/src/IMTextEntry.h @@ -30,8 +30,6 @@ namespace unity { -namespace dash -{ using namespace unity::glib; using namespace nux; @@ -80,6 +78,5 @@ private: }; } -} #endif diff --git a/plugins/unityshell/src/IconRenderer.cpp b/plugins/unityshell/src/IconRenderer.cpp index 4b1e46c90..b231fcc6f 100644 --- a/plugins/unityshell/src/IconRenderer.cpp +++ b/plugins/unityshell/src/IconRenderer.cpp @@ -246,7 +246,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con for (it = args.begin(), i = 0; it != args.end(); it++, i++) { - launcher::AbstractLauncherIcon* launcher_icon = it->icon; + IconTextureSource* launcher_icon = it->icon; float w = icon_size; float h = icon_size; @@ -270,7 +270,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con ViewProjectionMatrix = PremultMatrix * ObjectMatrix; - UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, launcher::AbstractLauncherIcon::TRANSFORM_TILE); + UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, ui::IconTextureSource::TRANSFORM_TILE); w = image_size; h = image_size; @@ -278,7 +278,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con y = it->render_center.y - icon_size / 2.0f + (icon_size - image_size) / 2.0f; z = it->render_center.z; - UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, launcher::AbstractLauncherIcon::TRANSFORM_IMAGE); + UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, ui::IconTextureSource::TRANSFORM_IMAGE); // hardcode values for now until SVG's are in place and we can remove this // 200 == size of large glow @@ -296,7 +296,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con y = it->render_center.y - icon_glow_size / 2.0f; z = it->render_center.z; - UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, launcher::AbstractLauncherIcon::TRANSFORM_GLOW); + UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, ui::IconTextureSource::TRANSFORM_GLOW); w = geo.width + 2; h = icon_size + spacing; @@ -306,7 +306,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con y = it->logical_center.y - h / 2.0f; z = it->logical_center.z; - UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, launcher::AbstractLauncherIcon::TRANSFORM_HIT_AREA); + UpdateIconTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, ui::IconTextureSource::TRANSFORM_HIT_AREA); if (launcher_icon->Emblem()) { @@ -331,19 +331,19 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con ViewProjectionMatrix = PremultMatrix * ObjectMatrix; UpdateIconSectionTransform(launcher_icon, ViewProjectionMatrix, geo, x, y, emb_w, emb_h, z, - it->render_center.x - w / 2.0f, it->render_center.y - h / 2.0f, w, h, launcher::AbstractLauncherIcon::TRANSFORM_EMBLEM); + it->render_center.x - w / 2.0f, it->render_center.y - h / 2.0f, w, h, ui::IconTextureSource::TRANSFORM_EMBLEM); } } } -void IconRenderer::UpdateIconTransform(launcher::AbstractLauncherIcon* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, - float x, float y, float w, float h, float z, launcher::AbstractLauncherIcon::TransformIndex index) +void IconRenderer::UpdateIconTransform(ui::IconTextureSource* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, + float x, float y, float w, float h, float z, ui::IconTextureSource::TransformIndex index) { UpdateIconSectionTransform (icon, ViewProjectionMatrix, geo, x, y, w, h, z, x, y, w, h, index); } -void IconRenderer::UpdateIconSectionTransform(launcher::AbstractLauncherIcon* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, - float x, float y, float w, float h, float z, float xx, float yy, float ww, float hh, launcher::AbstractLauncherIcon::TransformIndex index) +void IconRenderer::UpdateIconSectionTransform(ui::IconTextureSource* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, + float x, float y, float w, float h, float z, float xx, float yy, float ww, float hh, ui::IconTextureSource::TransformIndex index) { nux::Vector4 v0 = nux::Vector4(x, y, z, 1.0f); nux::Vector4 v1 = nux::Vector4(x, y + h, z, 1.0f); @@ -402,7 +402,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::BaseTexture* glow = local::icon_glow[size]; nux::BaseTexture* shine = local::icon_shine[size]; - + bool force_filter = icon_size != background->GetWidth(); if (arg.keyboard_nav_hl) { @@ -426,7 +426,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& shine = local::squircle_shine; } - auto tile_transform = arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_TILE, monitor); + auto tile_transform = arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_TILE, monitor); // draw tile if (backlight_intensity > 0 && !arg.draw_edge_only) @@ -437,6 +437,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& background_color, arg.colorify, backlight_intensity * arg.alpha, + force_filter, tile_transform); } @@ -450,6 +451,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& edge_color, arg.colorify, arg.alpha, + force_filter, tile_transform); } // end tile draw @@ -461,7 +463,8 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::color::White, arg.colorify, arg.alpha, - arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_IMAGE, monitor)); + false, + arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_IMAGE, monitor)); // draw overlay shine RenderElement(GfxContext, @@ -470,6 +473,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::color::White, arg.colorify, arg.alpha, + force_filter, tile_transform); // draw glow @@ -481,7 +485,8 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& glow_color, nux::color::White, glow_intensity * arg.alpha, - arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_GLOW, monitor)); + force_filter, + arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_GLOW, monitor)); } // draw shimmer @@ -502,7 +507,8 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& arg.icon->GlowColor(), nux::color::White, fade_out * arg.alpha, - arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_GLOW, monitor)); + force_filter, + arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_GLOW, monitor)); GfxContext.PopClippingRectangle(); } @@ -524,6 +530,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::color::White, nux::color::White, arg.alpha, + force_filter, tile_transform); } @@ -535,7 +542,8 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::color::White, nux::color::White, arg.alpha, - arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_EMBLEM, monitor)); + force_filter, + arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_EMBLEM, monitor)); } // draw indicators @@ -560,6 +568,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const& nux::Color(0xFFFFFFFF), nux::color::White, arg.alpha, + false, tile_transform); } } @@ -628,12 +637,16 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext, nux::Color bkg_color, nux::Color colorify, float alpha, + bool force_filter, std::vector<nux::Vector4>& xform_coords) { if (icon.IsNull()) return; - if (nux::Abs(arg.x_rotation) < 0.01f && nux::Abs(arg.y_rotation) < 0.01f && nux::Abs(arg.z_rotation) < 0.01f) + if (nux::Abs(arg.x_rotation) < 0.01f && + nux::Abs(arg.y_rotation) < 0.01f && + nux::Abs(arg.z_rotation) < 0.01f && + !force_filter) icon->SetFiltering(GL_NEAREST, GL_NEAREST); else icon->SetFiltering(GL_LINEAR, GL_LINEAR); @@ -810,7 +823,7 @@ void IconRenderer::RenderIndicators(nux::GraphicsEngine& GfxContext, } else { - auto bounds = arg.icon->GetTransform(launcher::AbstractLauncherIcon::TRANSFORM_TILE, monitor); + auto bounds = arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_TILE, monitor); markerX = bounds[0].x + 2; scale = 2; } diff --git a/plugins/unityshell/src/IconRenderer.h b/plugins/unityshell/src/IconRenderer.h index cd147f6d6..4ee5013f1 100644 --- a/plugins/unityshell/src/IconRenderer.h +++ b/plugins/unityshell/src/IconRenderer.h @@ -24,7 +24,6 @@ #include <Nux/BaseWindow.h> #include <Nux/View.h> -#include "AbstractLauncherIcon.h" #include "AbstractIconRenderer.h" namespace unity @@ -32,6 +31,8 @@ namespace unity namespace ui { +class IconTextureSource; + class IconRenderer : public AbstractIconRenderer { public: @@ -55,6 +56,7 @@ protected: nux::Color bkg_color, nux::Color colorify, float alpha, + bool force_filter, std::vector<nux::Vector4>& xform_coords); void RenderIndicators(nux::GraphicsEngine& GfxContext, @@ -69,11 +71,11 @@ protected: float progress_fill, float bias); - void UpdateIconTransform(launcher::AbstractLauncherIcon* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, - float x, float y, float w, float h, float z, launcher::AbstractLauncherIcon::TransformIndex index); + void UpdateIconTransform(ui::IconTextureSource* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, + float x, float y, float w, float h, float z, ui::IconTextureSource::TransformIndex index); - void UpdateIconSectionTransform(launcher::AbstractLauncherIcon* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, - float x, float y, float w, float h, float z, float xx, float yy, float ww, float hh, launcher::AbstractLauncherIcon::TransformIndex index); + void UpdateIconSectionTransform(ui::IconTextureSource* icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry const& geo, + float x, float y, float w, float h, float z, float xx, float yy, float ww, float hh, ui::IconTextureSource::TransformIndex index); void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& PerspectiveMatrix, int ViewportWidth, diff --git a/plugins/unityshell/src/IconTexture.cpp b/plugins/unityshell/src/IconTexture.cpp index 24a9910ea..0741e63e6 100644 --- a/plugins/unityshell/src/IconTexture.cpp +++ b/plugins/unityshell/src/IconTexture.cpp @@ -24,6 +24,7 @@ #include <pango/pangocairo.h> #include <Nux/Nux.h> +#include <NuxCore/Logger.h> #include <NuxGraphics/GLThread.h> #include <UnityCore/GLibWrapper.h> #include <UnityCore/Variant.h> @@ -37,6 +38,7 @@ namespace unity namespace { const char* const DEFAULT_ICON = "text-x-preview"; +nux::logging::Logger logger("unity.icontexture"); } using namespace unity; @@ -67,7 +69,7 @@ IconTexture::IconTexture(const char* icon_name, unsigned int size, bool defer_ic { _icon_name = g_strdup(icon_name ? icon_name : DEFAULT_ICON); - if (!g_strcmp0(_icon_name, "") == 0 && !defer_icon_loading) + if (g_strcmp0(_icon_name, "") != 0 && !defer_icon_loading) LoadIcon(); } @@ -95,8 +97,11 @@ void IconTexture::SetByFilePath(const char* file_path, unsigned int size) void IconTexture::LoadIcon() { - static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview"; - + 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) return; _loading = true; @@ -144,6 +149,7 @@ void IconTexture::Refresh(GdkPixbuf* pixbuf) _texture_height, sigc::mem_fun(this, &IconTexture::CreateTextureCallback)); QueueDraw(); + _loading = false; } void IconTexture::IconLoaded(std::string const& icon_name, unsigned size, @@ -162,6 +168,9 @@ void IconTexture::IconLoaded(std::string const& icon_name, unsigned size, if (icon_name != DEFAULT_ICON) SetByIconName(DEFAULT_ICON, _size); } + + texture_updated.emit(_texture_cached.GetPointer()); + QueueDraw(); } void IconTexture::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) diff --git a/plugins/unityshell/src/IconTexture.h b/plugins/unityshell/src/IconTexture.h index 57a0aa4f9..7bfdc1a64 100644 --- a/plugins/unityshell/src/IconTexture.h +++ b/plugins/unityshell/src/IconTexture.h @@ -53,6 +53,8 @@ public: nux::BaseTexture* texture(); + sigc::signal<void, nux::BaseTexture*> texture_updated; + protected: // Key navigation virtual bool AcceptKeyNavFocus(); @@ -61,7 +63,8 @@ protected: std::string GetName() const; void AddProperties(GVariantBuilder* builder); virtual bool DoCanFocus(); - + GdkPixbuf* _pixbuf_cached; + protected: void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); @@ -74,7 +77,7 @@ private: char* _icon_name; unsigned int _size; - GdkPixbuf* _pixbuf_cached; + nux::ObjectPtr<nux::BaseTexture> _texture_cached; // FIXME: make these two a nux::Size. int _texture_width; diff --git a/plugins/unityshell/src/IconTextureSource.cpp b/plugins/unityshell/src/IconTextureSource.cpp new file mode 100644 index 000000000..7cfcd8ac1 --- /dev/null +++ b/plugins/unityshell/src/IconTextureSource.cpp @@ -0,0 +1,46 @@ +// -*- 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Jason Smith <jason.smith@canonical.com> + */ + +#include "IconTextureSource.h" +#include "MultiMonitor.h" + +namespace unity +{ +namespace ui +{ + +IconTextureSource::IconTextureSource() +{ + transform_map.resize(max_num_monitors); +} + +std::vector<nux::Vector4> & IconTextureSource::GetTransform(TransformIndex index, int monitor) +{ + auto iter = transform_map[monitor].find(index); + if (iter == transform_map[monitor].end()) + { + auto iter2 = transform_map[monitor].insert(std::map<TransformIndex, std::vector<nux::Vector4> >::value_type(index, std::vector<nux::Vector4>(4))); + return iter2.first->second; + } + + return iter->second; +} + +} +} \ No newline at end of file diff --git a/plugins/unityshell/src/IconTextureSource.h b/plugins/unityshell/src/IconTextureSource.h new file mode 100644 index 000000000..7ae6ef202 --- /dev/null +++ b/plugins/unityshell/src/IconTextureSource.h @@ -0,0 +1,67 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Jason Smith <jason.smith@canonical.com> + * + */ + +#ifndef ICONTEXTURESOURCE_H +#define ICONTEXTURESOURCE_H + +#include <Nux/Nux.h> +#include <NuxCore/Property.h> +#include <NuxCore/Math/MathInc.h> + +namespace unity +{ +namespace ui +{ + +class IconTextureSource : public nux::InitiallyUnownedObject +{ +public: + typedef nux::ObjectPtr<IconTextureSource> Ptr; + + enum TransformIndex + { + TRANSFORM_TILE, + TRANSFORM_IMAGE, + TRANSFORM_HIT_AREA, + TRANSFORM_GLOW, + TRANSFORM_EMBLEM, + }; + + IconTextureSource(); + + std::vector<nux::Vector4> & GetTransform(TransformIndex index, int monitor); + + virtual nux::Color BackgroundColor() = 0; + + virtual nux::Color GlowColor() = 0; + + virtual nux::BaseTexture* TextureForSize(int size) = 0; + + virtual nux::BaseTexture* Emblem() = 0; + +private: + std::vector<std::map<TransformIndex, std::vector<nux::Vector4> > > transform_map; +}; + +} +} + +#endif // LAUNCHERICON_H + diff --git a/plugins/unityshell/src/Launcher.cpp b/plugins/unityshell/src/Launcher.cpp index 0b2e76178..1759b187a 100644 --- a/plugins/unityshell/src/Launcher.cpp +++ b/plugins/unityshell/src/Launcher.cpp @@ -76,6 +76,8 @@ const int PULSE_BLINK_LAMBDA = 2; const float BACKLIGHT_STRENGTH = 0.9f; const int panel_height = 24; +const int ICON_PADDING = 6; +const int RIGHT_LINE_WIDTH = 1; } @@ -252,8 +254,8 @@ Launcher::Launcher(nux::BaseWindow* parent, _drag_window = NULL; _offscreen_drag_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, nux::BITFMT_R8G8B8A8); - ubus.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, sigc::mem_fun(this, &Launcher::OnPlaceViewShown)); - ubus.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, sigc::mem_fun(this, &Launcher::OnPlaceViewHidden)); + ubus.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &Launcher::OnOverlayShown)); + ubus.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &Launcher::OnOverlayHidden)); ubus.RegisterInterest(UBUS_LAUNCHER_ACTION_DONE, sigc::mem_fun(this, &Launcher::OnActionDone)); ubus.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &Launcher::OnBGColorChanged)); ubus.RegisterInterest(UBUS_LAUNCHER_LOCK_HIDE, sigc::mem_fun(this, &Launcher::OnLockHideChanged)); @@ -1279,40 +1281,61 @@ void Launcher::SaturateIcons() } } -void Launcher::OnPlaceViewShown(GVariant* data) +void Launcher::OnOverlayShown(GVariant* data) { - if (g_variant_get_int32(data) != monitor) - return; + // check the type of overlay + 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); - LauncherModel::iterator it; - _dash_is_open = true; - bg_effect_helper_.enabled = true; - _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, true); - _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, true); + if (!g_strcmp0(overlay_identity, "dash")) + { + if (overlay_monitor == monitor) + { + LauncherModel::iterator it; + + _dash_is_open = true; + bg_effect_helper_.enabled = true; + _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, true); + _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, true); - DesaturateIcons(); + DesaturateIcons(); + } + } } -void Launcher::OnPlaceViewHidden(GVariant* data) +void Launcher::OnOverlayHidden(GVariant* data) { - if (!_dash_is_open) - return; + // check the type of overlay + 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); - LauncherModel::iterator it; + if (!g_strcmp0(overlay_identity, "dash")) + { + if (!_dash_is_open) + return; + + LauncherModel::iterator it; - _dash_is_open = false; - bg_effect_helper_.enabled = false; - _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false); - _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false); + _dash_is_open = false; + bg_effect_helper_.enabled = false; + _hide_machine->SetQuirk(LauncherHideMachine::PLACES_VISIBLE, false); + _hover_machine->SetQuirk(LauncherHoverMachine::PLACES_VISIBLE, false); - // as the leave event is no more received when the place is opened - // FIXME: remove when we change the mouse grab strategy in nux - nux::Point pt = nux::GetWindowCompositor().GetMousePosition(); + // as the leave event is no more received when the place is opened + // FIXME: remove when we change the mouse grab strategy in nux + nux::Point pt = nux::GetWindowCompositor().GetMousePosition(); - SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt)); + SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt)); - SaturateIcons(); + SaturateIcons(); + } } void Launcher::OnActionDone(GVariant* data) @@ -1733,7 +1756,8 @@ void Launcher::Resize() UScreen* uscreen = UScreen::GetDefault(); auto geo = uscreen->GetMonitorGeometry(monitor()); - nux::Geometry new_geometry(geo.x, geo.y + panel_height, _icon_size + 12, geo.height - panel_height); + int width = _icon_size + ICON_PADDING*2 + RIGHT_LINE_WIDTH - 2; + nux::Geometry new_geometry(geo.x, geo.y + panel_height, width, geo.height - panel_height); SetMaximumHeight(new_geometry.height); _parent->SetGeometry(new_geometry); SetGeometry(new_geometry); @@ -1855,6 +1879,7 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) nux::Geometry geo_absolute = GetAbsoluteGeometry(); RenderArgs(args, bkg_box, &launcher_alpha, geo_absolute); + bkg_box.width -= RIGHT_LINE_WIDTH; if (_drag_icon && _render_drag_window) { @@ -1959,12 +1984,15 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) if (!_dash_is_open) { + const double right_line_opacity = 0.15f * launcher_alpha; + gPainter.Paint2DQuadColor(GfxContext, - nux::Geometry(bkg_box.x + bkg_box.width - 1, + nux::Geometry(bkg_box.x + bkg_box.width, bkg_box.y, - 1, + RIGHT_LINE_WIDTH, bkg_box.height), - nux::Color(0x60606060)); + nux::color::White * right_line_opacity); + gPainter.Paint2DQuadColor(GfxContext, nux::Geometry(bkg_box.x, bkg_box.y, @@ -2486,7 +2514,7 @@ Launcher::RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherI clock_gettime(CLOCK_MONOTONIC, ¤t); SetupRenderArg(icon, current, arg); - arg.render_center = nux::Point3(_icon_size / 2.0f, _icon_size / 2.0f, 0.0f); + arg.render_center = nux::Point3(roundf(_icon_size / 2.0f), roundf(_icon_size / 2.0f), 0.0f); arg.logical_center = arg.render_center; arg.x_rotation = 0.0f; arg.running_arrow = false; @@ -2846,9 +2874,9 @@ Launcher::handle_dbus_method_call(GDBusConnection* connection, 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, NULL, aptdaemon_task, icon); + self->launcher_addrequest_special.emit(desktop_file, nullptr, aptdaemon_task, icon); - g_dbus_method_invocation_return_value(invocation, NULL); + g_dbus_method_invocation_return_value(invocation, nullptr); g_free(icon); g_free(title); g_free(desktop_file); diff --git a/plugins/unityshell/src/Launcher.h b/plugins/unityshell/src/Launcher.h index 36949e5f6..56021053b 100644 --- a/plugins/unityshell/src/Launcher.h +++ b/plugins/unityshell/src/Launcher.h @@ -126,7 +126,7 @@ public: void EnableCheckWindowOverLauncher(gboolean enabled); sigc::signal<void, char*, AbstractLauncherIcon*> launcher_addrequest; - sigc::signal<void, char*, AbstractLauncherIcon*, char*, char*> launcher_addrequest_special; + sigc::signal<void, std::string const&, AbstractLauncherIcon*, std::string const&, std::string const&> launcher_addrequest_special; sigc::signal<void, AbstractLauncherIcon*> launcher_removerequest; sigc::signal<void> selection_change; sigc::signal<void> hidden_changed; @@ -281,8 +281,8 @@ private: void OnIconNeedsRedraw(AbstractLauncherIcon* icon); - void OnPlaceViewHidden(GVariant* data); - void OnPlaceViewShown(GVariant* data); + void OnOverlayHidden(GVariant* data); + void OnOverlayShown(GVariant* data); void DesaturateIcons(); void SaturateIcons(); diff --git a/plugins/unityshell/src/LauncherController.cpp b/plugins/unityshell/src/LauncherController.cpp index d3780ee8b..3adacb16f 100644 --- a/plugins/unityshell/src/LauncherController.cpp +++ b/plugins/unityshell/src/LauncherController.cpp @@ -91,7 +91,7 @@ public: void OnIconRemoved(AbstractLauncherIcon* icon); void OnLauncherAddRequest(char* path, AbstractLauncherIcon* before); - void OnLauncherAddRequestSpecial(char* path, AbstractLauncherIcon* before, char* aptdaemon_trans_id, char* icon_path); + void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon* before, std::string const& aptdaemon_trans_id, std::string const& icon_path); void OnLauncherRemoveRequest(AbstractLauncherIcon* icon); void OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry); @@ -122,7 +122,7 @@ public: AbstractLauncherIcon* CreateFavorite(const char* file_path); - SoftwareCenterLauncherIcon* CreateSCLauncherIcon(const char* file_path, const char* aptdaemon_trans_id, char* icon_path); + SoftwareCenterLauncherIcon* CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path); void SetupBamf(); @@ -130,6 +130,8 @@ public: void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors); + void OnWindowFocusChanged (guint32 xid); + void ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags); void ReceiveLauncherKeyPress(unsigned long eventType, @@ -168,6 +170,7 @@ public: bool launcher_grabbed; bool reactivate_keynav; int reactivate_index; + bool keynav_restore_window_; UBusManager ubus; @@ -196,6 +199,7 @@ Controller::Impl::Impl(Display* display, Controller* parent) launcher_keynav = false; launcher_grabbed = false; reactivate_keynav = false; + keynav_restore_window_ = true; int i = 0; for (auto monitor : monitors) @@ -242,6 +246,9 @@ Controller::Impl::Impl(Display* display, Controller* parent) uscreen->changed.connect(sigc::mem_fun(this, &Controller::Impl::OnScreenChanged)); + WindowManager& plugin_adapter = *(WindowManager::Default()); + plugin_adapter.window_focus_changed.connect (sigc::mem_fun (this, &Controller::Impl::OnWindowFocusChanged)); + launcher_key_press_time_ = { 0, 0 }; ubus.RegisterInterest(UBUS_QUICKLIST_END_KEY_NAV, [&](GVariant * args) { @@ -268,7 +275,8 @@ void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector<nux::Geo { unsigned int num_monitors = monitors.size(); - for (unsigned int i = 0; i < num_monitors; i++) + unsigned int i; + for (i = 0; i < num_monitors; i++) { if (i >= launchers.size()) launchers.push_back(nux::ObjectPtr<Launcher> (CreateLauncher(i))); @@ -276,9 +284,31 @@ void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector<nux::Geo launchers[i]->Resize(); } + for (; i < launchers.size(); ++i) + { + auto launcher = launchers[i]; + if (launcher.IsValid()) + launcher->GetParent()->UnReference(); + } launchers.resize(num_monitors); } +void Controller::Impl::OnWindowFocusChanged (guint32 xid) +{ + static bool keynav_first_focus = false; + + if (keynav_first_focus) + { + keynav_first_focus = false; + keynav_restore_window_ = false; + parent_->KeyNavTerminate(false); + } + else if (launcher_keynav) + { + keynav_first_focus = true; + } +} + Launcher* Controller::Impl::CreateLauncher(int monitor) { nux::BaseWindow* launcher_window = new nux::BaseWindow(TEXT("LauncherWindow")); @@ -314,7 +344,7 @@ void Controller::Impl::OnLauncherAddRequest(char* path, AbstractLauncherIcon* be { for (auto it : model_->GetSublist<BamfLauncherIcon> ()) { - if (!g_strcmp0(path, it->DesktopFile())) + if (path && path == it->DesktopFile()) { it->Stick(); model_->ReorderBefore(it, before, false); @@ -345,25 +375,27 @@ void Controller::Impl::Save() if (!icon->IsSticky()) continue; - const char* desktop_file = icon->DesktopFile(); + std::string const& desktop_file = icon->DesktopFile(); - if (desktop_file && strlen(desktop_file) > 0) - desktop_paths.push_back(desktop_file); + if (!desktop_file.empty()) + desktop_paths.push_back(desktop_file.c_str()); } unity::FavoriteStore::GetDefault().SetFavorites(desktop_paths); } void -Controller::Impl::OnLauncherAddRequestSpecial(char* path, AbstractLauncherIcon* before, char* aptdaemon_trans_id, char* icon_path) +Controller::Impl::OnLauncherAddRequestSpecial(std::string const& path, + AbstractLauncherIcon* before, + std::string const& aptdaemon_trans_id, + std::string const& icon_path) { std::list<BamfLauncherIcon*> launchers; - std::list<BamfLauncherIcon*>::iterator it; - launchers = model_->GetSublist<BamfLauncherIcon> (); - for (it = launchers.begin(); it != launchers.end(); it++) + launchers = model_->GetSublist<BamfLauncherIcon>(); + for (auto icon : launchers) { - if (g_strcmp0(path, (*it)->DesktopFile()) == 0) + if (icon->DesktopFile() == path) return; } @@ -381,22 +413,21 @@ Controller::Impl::OnLauncherAddRequestSpecial(char* path, AbstractLauncherIcon* void Controller::Impl::SortAndUpdate() { gint shortcut = 1; - gchar* buff; std::list<BamfLauncherIcon*> launchers = model_->GetSublist<BamfLauncherIcon> (); - for (auto it : launchers) + for (auto icon : launchers) { - if (shortcut < 11 && it->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE)) + if (shortcut <= 10 && icon->IsVisible()) { - buff = g_strdup_printf("%d", shortcut % 10); - it->SetShortcut(buff[0]); - g_free(buff); + std::stringstream shortcut_string; + shortcut_string << (shortcut % 10); + icon->SetShortcut(shortcut_string.str()[0]); shortcut++; } // reset shortcut else { - it->SetShortcut(0); + icon->SetShortcut(0); } } } @@ -610,10 +641,9 @@ void Controller::Impl::RegisterIcon(AbstractLauncherIcon* icon) if (bamf_icon) { LauncherEntryRemote* entry = NULL; - const char* path; - path = bamf_icon->DesktopFile(); - if (path) - entry = remote_model_.LookupByDesktopFile(path); + std::string const& path = bamf_icon->DesktopFile(); + if (!path.empty()) + entry = remote_model_.LookupByDesktopFile(path.c_str()); if (entry) icon->InsertEntryRemote(entry); } @@ -669,12 +699,14 @@ AbstractLauncherIcon* Controller::Impl::CreateFavorite(const char* file_path) } SoftwareCenterLauncherIcon* -Controller::Impl::CreateSCLauncherIcon(const char* file_path, const char* aptdaemon_trans_id, char* icon_path) +Controller::Impl::CreateSCLauncherIcon(std::string const& file_path, + std::string const& aptdaemon_trans_id, + std::string const& icon_path) { BamfApplication* app; SoftwareCenterLauncherIcon* icon; - app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path, true); + app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path.c_str(), true); if (!BAMF_IS_APPLICATION(app)) return NULL; @@ -687,7 +719,7 @@ Controller::Impl::CreateSCLauncherIcon(const char* file_path, const char* aptdae 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); - icon = new SoftwareCenterLauncherIcon(app, (char*)aptdaemon_trans_id, icon_path); + icon = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path); icon->SetIconType(LauncherIcon::TYPE_APPLICATION); icon->SetSortPriority(sort_priority_++); @@ -1002,6 +1034,7 @@ void Controller::KeyNavActivate() pimpl->reactivate_keynav = false; pimpl->launcher_keynav = true; + pimpl->keynav_restore_window_ = true; pimpl->keyboard_launcher_ = pimpl->launchers[pimpl->MonitorWithMouse()]; pimpl->keyboard_launcher_->ShowShortcuts(false); @@ -1009,6 +1042,7 @@ void Controller::KeyNavActivate() 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); } void Controller::KeyNavNext() @@ -1043,6 +1077,7 @@ void Controller::KeyNavTerminate(bool activate) 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 @@ -1096,7 +1131,11 @@ void Controller::Impl::ReceiveLauncherKeyPress(unsigned long eventType, parent_->KeyNavNext(); break; - // esc/left (close quicklist or exit laucher key-focus) + // super/control/alt/esc/left (close quicklist or exit laucher key-focus) + case NUX_VK_LWIN: + case NUX_VK_RWIN: + case NUX_VK_CONTROL: + case NUX_VK_MENU: case NUX_VK_LEFT: case NUX_KP_LEFT: case NUX_VK_ESCAPE: diff --git a/plugins/unityshell/src/LauncherIcon.cpp b/plugins/unityshell/src/LauncherIcon.cpp index 108859c6a..f895b9efb 100644 --- a/plugins/unityshell/src/LauncherIcon.cpp +++ b/plugins/unityshell/src/LauncherIcon.cpp @@ -42,6 +42,7 @@ #include "QuicklistMenuItemCheckmark.h" #include "QuicklistMenuItemRadio.h" +#include "MultiMonitor.h" #include "WindowManager.h" #include "ubus-server.h" @@ -91,7 +92,6 @@ LauncherIcon::LauncherIcon() _saved_center.resize(max_num_monitors); _last_stable.resize(max_num_monitors); _parent_geo.resize(max_num_monitors); - transform_map.resize(max_num_monitors); for (int i = 0; i < QUIRK_LAST; i++) { @@ -783,7 +783,7 @@ LauncherIcon::Type() } bool -LauncherIcon::GetQuirk(LauncherIcon::Quirk quirk) +LauncherIcon::GetQuirk(LauncherIcon::Quirk quirk) const { return _quirks[quirk]; } @@ -915,19 +915,6 @@ LauncherIcon::SetEmblemIconName(const char* name) emblem->UnReference(); } -std::vector<nux::Vector4> & -LauncherIcon::GetTransform(TransformIndex index, int monitor) -{ - auto iter = transform_map[monitor].find(index); - if (iter == transform_map[monitor].end()) - { - auto iter2 = transform_map[monitor].insert(std::map<TransformIndex, std::vector<nux::Vector4> >::value_type(index, std::vector<nux::Vector4>(4))); - return iter2.first->second; - } - - return iter->second; -} - void LauncherIcon::SetEmblemText(const char* text) { diff --git a/plugins/unityshell/src/LauncherIcon.h b/plugins/unityshell/src/LauncherIcon.h index e67241cc4..09db019a1 100644 --- a/plugins/unityshell/src/LauncherIcon.h +++ b/plugins/unityshell/src/LauncherIcon.h @@ -51,8 +51,6 @@ namespace unity namespace launcher { -const int max_num_monitors = 6; - class Launcher; class LauncherIcon : public AbstractLauncherIcon @@ -137,7 +135,7 @@ public: return 0; } - bool GetQuirk(Quirk quirk); + bool GetQuirk(Quirk quirk) const; void SetQuirk(Quirk quirk, bool value); @@ -186,8 +184,6 @@ public: void SetIconType(IconType type); - std::vector<nux::Vector4> & GetTransform(TransformIndex index, int monitor); - protected: std::vector<nux::Point3> GetCenters(); @@ -308,7 +304,7 @@ private: int _last_monitor; nux::Color _background_color; nux::Color _glow_color; - + gint64 _shortcut; std::vector<nux::Point3> _center; @@ -325,8 +321,6 @@ private: struct timespec _quirk_times[QUIRK_LAST]; std::list<LauncherEntryRemote*> _entry_list; - std::vector<std::map<TransformIndex, std::vector<nux::Vector4> > > transform_map; - }; } diff --git a/plugins/unityshell/src/MockLauncherIcon.h b/plugins/unityshell/src/MockLauncherIcon.h index 835a54197..eddce171a 100644 --- a/plugins/unityshell/src/MockLauncherIcon.h +++ b/plugins/unityshell/src/MockLauncherIcon.h @@ -47,7 +47,6 @@ public: : icon_(0) { tooltip_text = "Mock Icon"; - transform_map.resize(10); sort_priority_ = 0; type_ = TYPE_APPLICATION; } @@ -123,18 +122,6 @@ public: void SaveCenter() {} - std::vector<nux::Vector4> & GetTransform(TransformIndex index, int monitor) - { - auto iter = transform_map[monitor].find(index); - if (iter == transform_map[monitor].end()) - { - auto iter2 = transform_map[monitor].insert(std::map<TransformIndex, std::vector<nux::Vector4> >::value_type(index, std::vector<nux::Vector4>(4))); - return iter2.first->second; - } - - return iter->second; - } - void Activate(ActionArg arg) {} void OpenInstance(ActionArg arg) {} @@ -183,7 +170,7 @@ public: return 0; } - bool GetQuirk(Quirk quirk) + bool GetQuirk(Quirk quirk) const { return false; } @@ -300,8 +287,6 @@ private: return result; } - - std::vector<std::map<TransformIndex, std::vector<nux::Vector4> > > transform_map; nux::BaseTexture* icon_; int sort_priority_; IconType type_; diff --git a/plugins/unityshell/src/MultiMonitor.h b/plugins/unityshell/src/MultiMonitor.h new file mode 100644 index 000000000..e93881334 --- /dev/null +++ b/plugins/unityshell/src/MultiMonitor.h @@ -0,0 +1,25 @@ +// -*- 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Jason Smith <jason.smith@canonical.com> + */ + +#ifndef MULTIMONITOR_H +#define MULTIMONITOR_H + +const int max_num_monitors = 6; + +#endif \ No newline at end of file diff --git a/plugins/unityshell/src/OverlayRenderer.cpp b/plugins/unityshell/src/OverlayRenderer.cpp index d0cecee8c..88cde19f5 100644 --- a/plugins/unityshell/src/OverlayRenderer.cpp +++ b/plugins/unityshell/src/OverlayRenderer.cpp @@ -36,6 +36,8 @@ namespace unity namespace { nux::logging::Logger logger("unity.overlayrenderer"); + +const int INNER_CORNER_RADIUS = 5; } // Impl class @@ -48,7 +50,7 @@ public: void Init(); void OnBackgroundColorChanged(GVariant* args); - void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry); + void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_draw); void DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry); void DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry); @@ -116,12 +118,12 @@ void OverlayRendererImpl::OnBackgroundColorChanged(GVariant* args) parent->need_redraw.emit(); } -void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry) +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; - if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) + if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges) { // Paint the edges { @@ -254,7 +256,7 @@ void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry c 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() && paint_blur) + if (bg_blur_texture_.IsValid()) { nux::Geometry bg_clip = geo; gfx_context.PushClippingRectangle(bg_clip); @@ -268,7 +270,35 @@ void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry c gfx_context.PopClippingRectangle(); } } + + // Draw the left and top lines + gfx_context.GetRenderStates().SetColorMask(true, true, true, true); + gfx_context.GetRenderStates().SetBlend(true); + gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); + + const double line_opacity = 0.22; + nux::Color line_color = nux::color::White * line_opacity; + nux::GetPainter().Paint2DQuadColor(gfx_context, + nux::Geometry(geometry.x, + geometry.y, + 1, + 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, + 1), + 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_); @@ -287,54 +317,38 @@ void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry c content_geo.width, content_geo.height, bg_shine_texture_, texxform_absolute_bg, nux::color::White); - // Make round corners - 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); - - gfx_context.GetRenderStates().SetColorMask(true, true, true, true); - gfx_context.GetRenderStates().SetBlend(true); - gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - - geo = geometry; - nux::GetPainter().Paint2DQuadColor(gfx_context, - nux::Geometry(geo.x, - geo.y, - 1, - content_geo.height + 5), - nux::Color(0.0f, 0.0f, 0.0f, 0.0f), - nux::Color(0.15f, 0.15f, 0.15f, 0.15f), - nux::Color(0.15f, 0.15f, 0.15f, 0.15f), - nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); - nux::GetPainter().Paint2DQuadColor(gfx_context, - nux::Geometry(geo.x, - geo.y, - content_geo.width + 5, - 1), - nux::Color(0.0f, 0.0f, 0.0f, 0.0f), - nux::Color(0.0f, 0.0f, 0.0f, 0.0f), - nux::Color(0.15f, 0.15f, 0.15f, 0.15f), - nux::Color(0.15f, 0.15f, 0.15f, 0.15f)); - - geo = content_geo; - // Fill in corners (meh) - for (int i = 1; i < 6; ++i) + if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) { - nux::Geometry fill_geo (geo.x + geo.width, geo.y + i - 1, 6 - 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 - 1 , geo.y + geo.height, 1, 6 - i); - nux::GetPainter().Paint2DQuadColor(gfx_context, fill_geo, dark); + // 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); + } } } @@ -403,18 +417,21 @@ void OverlayRendererImpl::DrawContentCleanup(nux::GraphicsEngine& gfx_context, n gfx_context.GetRenderStates().SetBlend(false); gfx_context.PopClippingRectangle(); - // Make round corners - 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); + 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; } @@ -458,9 +475,9 @@ void OverlayRenderer::DisableBlur() pimpl_->bg_effect_helper_.blur_type = BLUR_NONE; } -void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo) +void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges) { - pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo); + pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo, force_edges); } void OverlayRenderer::DrawInner(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo) diff --git a/plugins/unityshell/src/OverlayRenderer.h b/plugins/unityshell/src/OverlayRenderer.h index f4bd624f1..25290f5e5 100644 --- a/plugins/unityshell/src/OverlayRenderer.h +++ b/plugins/unityshell/src/OverlayRenderer.h @@ -70,7 +70,7 @@ public: * absolute_geo: your views GetAbsoluteGeometry() * geo: your views GetGeometry() */ - void DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo); + void DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges=false); /* * Draws just the stack that is overlay behind the inner_geometry using push/pop layers, call in DrawContent() before drawing your content diff --git a/plugins/unityshell/src/PanelMenuView.cpp b/plugins/unityshell/src/PanelMenuView.cpp index d4491f4d8..562033d23 100644 --- a/plugins/unityshell/src/PanelMenuView.cpp +++ b/plugins/unityshell/src/PanelMenuView.cpp @@ -155,10 +155,10 @@ PanelMenuView::PanelMenuView(int padding) // Register for all the interesting events UBusServer* ubus = ubus_server_get_default(); - _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN, + _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_PLACE_VIEW_HIDDEN, + _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN, (UBusCallback)PanelMenuView::OnPlaceViewHidden, this)); diff --git a/plugins/unityshell/src/PanelTray.cpp b/plugins/unityshell/src/PanelTray.cpp index 562ff3e4c..6900a4cd7 100644 --- a/plugins/unityshell/src/PanelTray.cpp +++ b/plugins/unityshell/src/PanelTray.cpp @@ -95,7 +95,6 @@ PanelTray::~PanelTray() if (_tray) { g_signal_handler_disconnect(na_tray_get_manager(_tray), _tray_icon_added_id); - g_object_unref (_tray); _tray = NULL; } @@ -104,9 +103,7 @@ PanelTray::~PanelTray() if (_tray_expose_id) g_signal_handler_disconnect(_window, _tray_expose_id); - // DISABLED to see if we can get compiz to cleanly exit. - // This currently blocks on X. - // gtk_widget_destroy(_window); + gtk_widget_destroy(_window); g_strfreev(_whitelist); g_object_unref(_settings); } diff --git a/plugins/unityshell/src/PanelView.cpp b/plugins/unityshell/src/PanelView.cpp index acaec1889..5eb7b1933 100644 --- a/plugins/unityshell/src/PanelView.cpp +++ b/plugins/unityshell/src/PanelView.cpp @@ -103,11 +103,11 @@ PanelView::PanelView(NUX_FILE_LINE_DECL) (UBusCallback)&PanelView::OnBackgroundUpdate, this); - _handle_dash_hidden = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_HIDDEN, + _handle_dash_hidden = ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN, (UBusCallback)&PanelView::OnDashHidden, this); - _handle_dash_shown = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN, + _handle_dash_shown = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN, (UBusCallback)&PanelView::OnDashShown, this); // request the latest colour from bghash @@ -182,7 +182,13 @@ void PanelView::OnDashHidden(GVariant* data, PanelView* self) void PanelView::OnDashShown(GVariant* data, PanelView* self) { - if (self->_monitor == g_variant_get_int32(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); + + if (self->_monitor == overlay_monitor) { self->bg_effect_helper_.enabled = true; self->_dash_is_open = true; diff --git a/plugins/unityshell/src/PlacesGroup.cpp b/plugins/unityshell/src/PlacesGroup.cpp index 5da93b3ce..fae8bdc63 100644 --- a/plugins/unityshell/src/PlacesGroup.cpp +++ b/plugins/unityshell/src/PlacesGroup.cpp @@ -100,8 +100,8 @@ PlacesGroup::PlacesGroup() _expand_label->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); _expand_label->SetTextColor(kExpandDefaultTextColor); _expand_label->SetAcceptKeyNavFocus(true); - _expand_label->OnKeyNavFocusActivate.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelActivated)); - _expand_label->OnKeyNavFocusChange.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged)); + _expand_label->key_nav_focus_activate.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelActivated)); + _expand_label->key_nav_focus_change.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged)); _expand_layout->AddView(_expand_label, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); @@ -144,7 +144,7 @@ PlacesGroup::OnLabelActivated(nux::Area* label) } void -PlacesGroup::OnLabelFocusChanged(nux::Area* label) +PlacesGroup::OnLabelFocusChanged(nux::Area* label, bool has_focus, nux::KeyNavDirection direction) { if (_expand_label->HasKeyFocus() || _expand_icon->HasKeyFocus()) { @@ -255,7 +255,7 @@ PlacesGroup::RefreshLabel() if (_expand_icon->IsVisible()) { _expand_icon->SetAcceptKeyNavFocus(true); - _expand_icon->OnKeyNavFocusChange.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged)); + _expand_icon->key_nav_focus_change.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged)); } } diff --git a/plugins/unityshell/src/PlacesGroup.h b/plugins/unityshell/src/PlacesGroup.h index 91b5f8671..9f4c6295a 100644 --- a/plugins/unityshell/src/PlacesGroup.h +++ b/plugins/unityshell/src/PlacesGroup.h @@ -82,7 +82,7 @@ private: void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnLabelActivated(nux::Area* label); - void OnLabelFocusChanged(nux::Area* label); + void OnLabelFocusChanged(nux::Area* label, bool has_focus, nux::KeyNavDirection direction); void RefreshLabel(); private: diff --git a/plugins/unityshell/src/PlacesTile.cpp b/plugins/unityshell/src/PlacesTile.cpp index 40f05c971..ec8531001 100644 --- a/plugins/unityshell/src/PlacesTile.cpp +++ b/plugins/unityshell/src/PlacesTile.cpp @@ -48,8 +48,8 @@ PlacesTile::PlacesTile(NUX_FILE_LINE_DECL, const void* id) : mouse_click.connect(sigc::mem_fun(this, &PlacesTile::RecvMouseClick)); mouse_enter.connect(sigc::mem_fun(this, &PlacesTile::RecvMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &PlacesTile::RecvMouseLeave)); - OnKeyNavFocusChange.connect(sigc::mem_fun(this, &PlacesTile::OnFocusChanged)); - OnKeyNavFocusActivate.connect(sigc::mem_fun(this, &PlacesTile::OnFocusActivated)); + key_nav_focus_change.connect(sigc::mem_fun(this, &PlacesTile::OnFocusChanged)); + key_nav_focus_activate.connect(sigc::mem_fun(this, &PlacesTile::OnFocusActivated)); } PlacesTile::~PlacesTile() @@ -68,7 +68,7 @@ PlacesTile::GetId() } void -PlacesTile::OnFocusChanged(nux::Area* label) +PlacesTile::OnFocusChanged(nux::Area* label, bool has_focus, nux::KeyNavDirection direction) { QueueDraw(); } diff --git a/plugins/unityshell/src/PlacesTile.h b/plugins/unityshell/src/PlacesTile.h index be7ddff7e..115399eef 100644 --- a/plugins/unityshell/src/PlacesTile.h +++ b/plugins/unityshell/src/PlacesTile.h @@ -62,7 +62,7 @@ private: nux::ObjectPtr<nux::BaseTexture> _hilight_background; nux::TextureLayer* _hilight_layer; - void OnFocusChanged(nux::Area* label); + void OnFocusChanged(nux::Area* label, bool has_focus, nux::KeyNavDirection direction); void OnFocusActivated(nux::Area* label); int _last_width; int _last_height; diff --git a/plugins/unityshell/src/PointerBarrier.cpp b/plugins/unityshell/src/PointerBarrier.cpp index 81fae0be9..ddfaf52b5 100644 --- a/plugins/unityshell/src/PointerBarrier.cpp +++ b/plugins/unityshell/src/PointerBarrier.cpp @@ -48,6 +48,11 @@ PointerBarrierWrapper::PointerBarrierWrapper() max_velocity_multiplier = 1.0f; } +PointerBarrierWrapper::~PointerBarrierWrapper() +{ + DestroyBarrier(); +} + void PointerBarrierWrapper::ConstructBarrier() { if (active) diff --git a/plugins/unityshell/src/PointerBarrier.h b/plugins/unityshell/src/PointerBarrier.h index 10af894ec..9ebde0918 100644 --- a/plugins/unityshell/src/PointerBarrier.h +++ b/plugins/unityshell/src/PointerBarrier.h @@ -60,6 +60,7 @@ public: nux::Property<float> max_velocity_multiplier; PointerBarrierWrapper(); + ~PointerBarrierWrapper(); void ConstructBarrier(); void DestroyBarrier(); diff --git a/plugins/unityshell/src/QuicklistMenuItemCheckmark.cpp b/plugins/unityshell/src/QuicklistMenuItemCheckmark.cpp index b6f4455c9..3b2686b25 100644 --- a/plugins/unityshell/src/QuicklistMenuItemCheckmark.cpp +++ b/plugins/unityshell/src/QuicklistMenuItemCheckmark.cpp @@ -110,13 +110,12 @@ QuicklistMenuItemCheckmark::PostLayoutManagement(long layoutResult) } void -QuicklistMenuItemCheckmark::Draw(nux::GraphicsEngine& gfxContext, - bool forceDraw) +QuicklistMenuItemCheckmark::Draw(nux::GraphicsEngine& gfxContext, bool forceDraw) { nux::ObjectPtr<nux::IOpenGLBaseTexture> texture; // Check if the texture have been computed. If they haven't, exit the function. - if (!_normalTexture[0]) + if (!_normalTexture[0] || !_prelightTexture[0]) return; nux::Geometry base = GetGeometry(); @@ -130,42 +129,19 @@ QuicklistMenuItemCheckmark::Draw(nux::GraphicsEngine& gfxContext, gfxContext.GetRenderStates().SetBlend(true); gfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - if (GetEnabled()) + unsigned int texture_idx = GetActive() ? 1 : 0; + + if (!_prelight || !GetEnabled()) { - if (GetActive() && _prelight) - { - texture = _prelightTexture[0]->GetDeviceTexture(); - } - else if (GetActive()) - { - texture = _normalTexture[0]->GetDeviceTexture(); - } - - if ((!GetActive()) && _prelight) - { - texture = _prelightTexture[1]->GetDeviceTexture(); - } - else if (!GetActive()) - { - texture = _normalTexture[1]->GetDeviceTexture(); - } - - _color = nux::color::White; + texture = _normalTexture[texture_idx]->GetDeviceTexture(); } else { - if (GetActive()) - { - texture = _prelightTexture[0]->GetDeviceTexture(); - } - else - { - texture = _normalTexture[0]->GetDeviceTexture(); - } - - _color = nux::Color(0.8f, 0.8f, 0.8f, 1.0f); + texture = _prelightTexture[texture_idx]->GetDeviceTexture(); } + _color = GetEnabled() ? nux::color::White : nux::Color(0.8f, 0.8f, 0.8f, 1.0f); + gfxContext.QRP_1Tex(base.x, base.y, base.width, diff --git a/plugins/unityshell/src/QuicklistMenuItemRadio.cpp b/plugins/unityshell/src/QuicklistMenuItemRadio.cpp index c4b8c164e..2092c40d5 100644 --- a/plugins/unityshell/src/QuicklistMenuItemRadio.cpp +++ b/plugins/unityshell/src/QuicklistMenuItemRadio.cpp @@ -109,15 +109,14 @@ QuicklistMenuItemRadio::PostLayoutManagement(long layoutResult) } void -QuicklistMenuItemRadio::Draw(nux::GraphicsEngine& gfxContext, - bool forceDraw) +QuicklistMenuItemRadio::Draw(nux::GraphicsEngine& gfxContext, bool forceDraw) { + nux::ObjectPtr<nux::IOpenGLBaseTexture> texture; + // Check if the texture have been computed. If they haven't, exit the function. - if (!_normalTexture[0]) + if (!_normalTexture[0] || !_prelightTexture[0]) return; - nux::ObjectPtr<nux::IOpenGLBaseTexture> texture; - nux::Geometry base = GetGeometry(); gfxContext.PushClippingRectangle(base); @@ -129,42 +128,19 @@ QuicklistMenuItemRadio::Draw(nux::GraphicsEngine& gfxContext, gfxContext.GetRenderStates().SetBlend(true); gfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER); - if (GetEnabled()) + unsigned int texture_idx = GetActive() ? 1 : 0; + + if (!_prelight || !GetEnabled()) { - if (GetActive() && _prelight) - { - texture = _prelightTexture[0]->GetDeviceTexture(); - } - else if (GetActive()) - { - texture = _normalTexture[0]->GetDeviceTexture(); - } - - if ((!GetActive()) && _prelight) - { - texture = _prelightTexture[1]->GetDeviceTexture(); - } - else if (!GetActive()) - { - texture = _normalTexture[1]->GetDeviceTexture(); - } - - _color = nux::color::White; + texture = _normalTexture[texture_idx]->GetDeviceTexture(); } else { - if (GetActive()) - { - texture = _prelightTexture[0]->GetDeviceTexture(); - } - else - { - texture = _normalTexture[0]->GetDeviceTexture(); - } - - _color = nux::Color(0.8f, 0.8f, 0.8f, 1.0f); + texture = _prelightTexture[texture_idx]->GetDeviceTexture(); } + _color = GetEnabled() ? nux::color::White : nux::Color(0.8f, 0.8f, 0.8f, 1.0f); + gfxContext.QRP_1Tex(base.x, base.y, base.width, diff --git a/plugins/unityshell/src/QuicklistView.cpp b/plugins/unityshell/src/QuicklistView.cpp index fa783020e..7c3dead41 100644 --- a/plugins/unityshell/src/QuicklistView.cpp +++ b/plugins/unityshell/src/QuicklistView.cpp @@ -896,8 +896,7 @@ QuicklistMenuItemType QuicklistView::GetNthType(int index) std::list<QuicklistMenuItem*> QuicklistView::GetChildren() { - std::list<QuicklistMenuItem*> l; - return l; + return _item_list; } void QuicklistView::DefaultToFirstItem() diff --git a/plugins/unityshell/src/ResultViewGrid.cpp b/plugins/unityshell/src/ResultViewGrid.cpp index 0511b8f53..0c96d7aec 100644 --- a/plugins/unityshell/src/ResultViewGrid.cpp +++ b/plugins/unityshell/src/ResultViewGrid.cpp @@ -72,8 +72,8 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL) vertical_spacing.changed.connect(needredraw_lambda); padding.changed.connect(needredraw_lambda); - OnKeyNavFocusChange.connect (sigc::mem_fun (this, &ResultViewGrid::OnOnKeyNavFocusChange)); - OnKeyNavFocusActivate.connect ([&] (nux::Area *area) { UriActivated.emit (focused_uri_); }); + key_nav_focus_change.connect (sigc::mem_fun (this, &ResultViewGrid::OnOnKeyNavFocusChange)); + key_nav_focus_activate.connect ([&] (nux::Area *area) { UriActivated.emit (focused_uri_); }); key_down.connect (sigc::mem_fun (this, &ResultViewGrid::OnKeyDown)); mouse_move.connect(sigc::mem_fun(this, &ResultViewGrid::MouseMove)); mouse_click.connect(sigc::mem_fun(this, &ResultViewGrid::MouseClick)); @@ -489,7 +489,7 @@ nux::Area* ResultViewGrid::KeyNavIteration(nux::KeyNavDirection direction) } // crappy name. -void ResultViewGrid::OnOnKeyNavFocusChange(nux::Area *area) +void ResultViewGrid::OnOnKeyNavFocusChange(nux::Area *area, bool has_focus, nux::KeyNavDirection direction) { if (HasKeyFocus()) { @@ -499,9 +499,29 @@ void ResultViewGrid::OnOnKeyNavFocusChange(nux::Area *area) selected_index_ = 0; } + int focused_x = 0; + int focused_y = 0; + int items_per_row = GetItemsPerRow(); - int focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); - int focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); + + if (direction == nux::KEY_NAV_UP) + { + // This View just got focused through keyboard navigation and the + // focus is comming from the bottom. We want to focus the + // first item (on the left) of the last row in this grid. + + int total_rows = std::ceil(results_.size() / (double)items_per_row); + selected_index_ = items_per_row * (total_rows-1); + + focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); + focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); + + } + else + { + focused_x = (renderer_->width + horizontal_spacing) * (selected_index_ % items_per_row); + focused_y = (renderer_->height + vertical_spacing) * (selected_index_ / items_per_row); + } ubus_.SendMessage(UBUS_RESULT_VIEW_KEYNAV_CHANGED, g_variant_new("(iiii)", focused_x, focused_y, renderer_->width(), renderer_->height())); @@ -717,7 +737,7 @@ uint ResultViewGrid::GetIndexAtPosition(int x, int y) int x_bound = items_per_row * column_size + padding; - if (x < padding || x > x_bound) + if ((x < padding) || (x >= x_bound)) return -1; if (y < padding) diff --git a/plugins/unityshell/src/ResultViewGrid.h b/plugins/unityshell/src/ResultViewGrid.h index e440438e6..7eea40425 100644 --- a/plugins/unityshell/src/ResultViewGrid.h +++ b/plugins/unityshell/src/ResultViewGrid.h @@ -69,7 +69,7 @@ protected: virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); virtual bool AcceptKeyNavFocus(); virtual nux::Area* KeyNavIteration(nux::KeyNavDirection direction); - virtual void OnOnKeyNavFocusChange(nux::Area *); + virtual void OnOnKeyNavFocusChange(nux::Area* area, bool has_focus, nux::KeyNavDirection direction); void OnKeyDown(unsigned long event_type, unsigned long event_keysym, unsigned long event_state, const TCHAR* character, unsigned short key_repeat_count); virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);; diff --git a/plugins/unityshell/src/DashSearchBar.cpp b/plugins/unityshell/src/SearchBar.cpp index 090d70ebc..a72647ae6 100644 --- a/plugins/unityshell/src/DashSearchBar.cpp +++ b/plugins/unityshell/src/SearchBar.cpp @@ -25,6 +25,7 @@ #include <Nux/VLayout.h> #include <Nux/Layout.h> #include <Nux/WindowCompositor.h> +#include <NuxCore/Logger.h> #include <NuxImage/CairoGraphics.h> #include <NuxImage/ImageSurface.h> @@ -36,7 +37,7 @@ #include <glib.h> #include <glib/gi18n-lib.h> -#include "DashSearchBar.h" +#include "SearchBar.h" #include <UnityCore/Variant.h> #include "CairoTexture.h" @@ -48,11 +49,16 @@ namespace { const float kExpandDefaultIconOpacity = 1.0f; +const int external_margin_vertical = 8; +const int external_margin_horizontal = 7; } -namespace unity +namespace { -namespace dash + nux::logging::Logger logger("unity"); +} + +namespace unity { NUX_IMPLEMENT_OBJECT_TYPE(SearchBar); @@ -62,18 +68,53 @@ SearchBar::SearchBar(NUX_FILE_LINE_DECL) , search_hint("") , showing_filters(false) , can_refine_search(false) + , disable_glow(false) + , show_filter_hint_(true) , search_bar_width_(642) , live_search_timeout_(0) , start_spinner_timeout_(0) { + Init(); +} + +SearchBar::SearchBar(int search_bar_width, 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_) + , 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) + , search_bar_width_(search_bar_width) + , live_search_timeout_(0) + , start_spinner_timeout_(0) +{ + Init(); +} + +void SearchBar::Init() +{ nux::BaseTexture* icon = dash::Style::Instance().GetSearchMagnifyIcon(); bg_layer_ = new nux::ColorLayer(nux::Color(0xff595853), true); layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); layout_->SetHorizontalInternalMargin(0); - layout_->SetVerticalExternalMargin(8); - layout_->SetHorizontalExternalMargin(7); + layout_->SetVerticalExternalMargin(external_margin_vertical); + layout_->SetHorizontalExternalMargin(external_margin_horizontal); SetLayout(layout_); spinner_ = new SearchBarSpinner(); @@ -102,42 +143,44 @@ SearchBar::SearchBar(NUX_FILE_LINE_DECL) layered_layout_->SetMaximumWidth(search_bar_width_); layout_->AddView(layered_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); - std::string filter_str = _("<small><b>Filter results</b></small>"); - show_filters_ = new nux::StaticCairoText(filter_str.c_str()); - show_filters_->SetVisible(false); - show_filters_->SetFont("Ubuntu 10"); - show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); - show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); - show_filters_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; }); - - nux::BaseTexture* arrow; - arrow = dash::Style::Instance().GetGroupExpandIcon(); - expand_icon_ = new IconTexture(arrow, - arrow->GetWidth(), - arrow->GetHeight()); - expand_icon_->SetOpacity(kExpandDefaultIconOpacity); - expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight()); - expand_icon_->SetVisible(false); - expand_icon_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; }); - - filter_layout_ = new nux::HLayout(); - filter_layout_->SetHorizontalInternalMargin(8); - filter_layout_->SetHorizontalExternalMargin(6); - filter_space_ = new nux::SpaceLayout(100, 10000, 0, 1); - filter_layout_->AddLayout(filter_space_, 1); - filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER); - - arrow_layout_ = new nux::VLayout(); - arrow_top_space_ = new nux::SpaceLayout(2, 2, 12, 12); - arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 8, 8); - arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER); - arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER); - arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER); - - filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER); - - layout_->AddView(filter_layout_, 1, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL); - + if (show_filter_hint_) + { + std::string filter_str = _("<small><b>Filter results</b></small>"); + show_filters_ = new nux::StaticCairoText(filter_str.c_str()); + show_filters_->SetVisible(false); + show_filters_->SetFont("Ubuntu 10"); + show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT); + show_filters_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; }); + + nux::BaseTexture* arrow; + arrow = dash::Style::Instance().GetGroupExpandIcon(); + expand_icon_ = new IconTexture(arrow, + arrow->GetWidth(), + arrow->GetHeight()); + expand_icon_->SetOpacity(kExpandDefaultIconOpacity); + expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight()); + expand_icon_->SetVisible(false); + expand_icon_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; }); + + filter_layout_ = new nux::HLayout(); + filter_layout_->SetHorizontalInternalMargin(8); + filter_layout_->SetHorizontalExternalMargin(6); + filter_space_ = new nux::SpaceLayout(100, 10000, 0, 1); + filter_layout_->AddLayout(filter_space_, 1); + filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER); + + arrow_layout_ = new nux::VLayout(); + arrow_top_space_ = new nux::SpaceLayout(2, 2, 12, 12); + arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 8, 8); + arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER); + arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER); + arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER); + + filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER); + + layout_->AddView(filter_layout_, 1, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL); + } sig_manager_.Add(new Signal<void, GtkSettings*, GParamSpec*> (gtk_settings_get_default(), "notify::gtk-font-name", @@ -151,9 +194,21 @@ SearchBar::SearchBar(NUX_FILE_LINE_DECL) showing_filters.changed.connect(sigc::mem_fun(this, &SearchBar::OnShowingFiltersChanged)); can_refine_search.changed.connect([&] (bool can_refine) { - show_filters_->SetVisible(can_refine); - expand_icon_->SetVisible(can_refine); + if (show_filter_hint_) + { + show_filters_->SetVisible(can_refine); + expand_icon_->SetVisible(can_refine); + } }); + + disable_glow.changed.connect([&](bool disabled) + { + layout_->SetVerticalExternalMargin(0); + layout_->SetHorizontalExternalMargin(0); + UpdateBackground(true); + QueueDraw(); + }); + } SearchBar::~SearchBar() @@ -259,18 +314,21 @@ gboolean SearchBar::OnSpinnerStartCb(SearchBar* sef) void SearchBar::OnShowingFiltersChanged(bool is_showing) { - dash::Style& style = dash::Style::Instance(); - if (is_showing) - expand_icon_->SetTexture(style.GetGroupUnexpandIcon()); - else - expand_icon_->SetTexture(style.GetGroupExpandIcon()); + if (show_filter_hint_) + { + dash::Style& style = dash::Style::Instance(); + if (is_showing) + expand_icon_->SetTexture(style.GetGroupUnexpandIcon()); + else + expand_icon_->SetTexture(style.GetGroupExpandIcon()); + } } void SearchBar::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { nux::Geometry geo = GetGeometry(); - UpdateBackground(); + UpdateBackground(false); GfxContext.PushClippingRectangle(geo); @@ -344,21 +402,33 @@ SearchBar::SearchFinished() spinner_->SetState(is_empty ? STATE_READY : STATE_CLEAR); } -void SearchBar::UpdateBackground() +void SearchBar::UpdateBackground(bool force) { -#define PADDING 12 -#define RADIUS 5 + int PADDING = 12; + int RADIUS = 5; int x, y, width, height; nux::Geometry geo = GetGeometry(); geo.width = layered_layout_->GetGeometry().width; - if (geo.width == last_width_ && geo.height == last_height_) + LOG_DEBUG(logger) << "height: " + << geo.height << " - " + << layered_layout_->GetGeometry().height << " - " + << pango_entry_->GetGeometry().height; + + if (geo.width == last_width_ + && geo.height == last_height_ + && force == false) return; last_width_ = geo.width; last_height_ = geo.height; + if (disable_glow) + PADDING = 2; + + x = y = PADDING - 1; + width = last_width_ - (2 * PADDING); height = last_height_ - (2 * PADDING) + 1; @@ -473,5 +543,4 @@ void SearchBar::AddProperties(GVariantBuilder* builder) g_variant_builder_add (builder, "{sv}", "search_string", g_variant_new_string (pango_entry_->GetText().c_str()) ); } -} // namespace dash } // namespace unity diff --git a/plugins/unityshell/src/DashSearchBar.h b/plugins/unityshell/src/SearchBar.h index 7bc8c5e37..bb2d2fe86 100644 --- a/plugins/unityshell/src/DashSearchBar.h +++ b/plugins/unityshell/src/SearchBar.h @@ -17,8 +17,8 @@ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> */ -#ifndef DASH_SEARCH_BAR_H -#define DASH_SEARCH_BAR_H +#ifndef SEARCH_BAR_H +#define SEARCH_BAR_H #include <gtk/gtk.h> @@ -32,7 +32,7 @@ #include <Nux/TextEntry.h> #include <UnityCore/GLibSignal.h> -#include "DashSearchBarSpinner.h" +#include "SearchBarSpinner.h" #include "IconTexture.h" #include "IMTextEntry.h" #include "Introspectable.h" @@ -40,8 +40,6 @@ namespace unity { -namespace dash -{ using namespace unity::glib; @@ -49,7 +47,10 @@ class SearchBar : public unity::debug::Introspectable, public nux::View { NUX_DECLARE_OBJECT_TYPE(SearchBar, nux::View); public: + typedef nux::ObjectPtr<SearchBar> 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(); void SearchFinished(); @@ -59,6 +60,7 @@ public: nux::Property<std::string> search_hint; nux::Property<bool> showing_filters; nux::Property<bool> can_refine_search; + nux::Property<bool> disable_glow; nux::ROProperty<bool> im_active; sigc::signal<void> activated; @@ -67,6 +69,8 @@ public: private: + void Init(); + void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL); void OnSearchHintChanged(); @@ -76,7 +80,7 @@ private: void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnEndKeyFocus(); - void UpdateBackground(); + void UpdateBackground(bool force); void OnSearchChanged(nux::TextEntry* text_entry); void OnClearClicked(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnEntryActivated(); @@ -85,6 +89,7 @@ private: std::string get_search_string() const; bool set_search_string(std::string const& string); bool get_im_active() const; + bool show_filter_hint_; static gboolean OnLiveSearchTimeout(SearchBar* self); static gboolean OnSpinnerStartCb(SearchBar* self); @@ -110,7 +115,6 @@ private: IconTexture* expand_icon_; int search_bar_width_; - int last_width_; int last_height_; @@ -121,6 +125,5 @@ private: }; } -} #endif diff --git a/plugins/unityshell/src/DashSearchBarSpinner.cpp b/plugins/unityshell/src/SearchBarSpinner.cpp index 3efc7726e..66cdbca63 100644 --- a/plugins/unityshell/src/DashSearchBarSpinner.cpp +++ b/plugins/unityshell/src/SearchBarSpinner.cpp @@ -17,7 +17,7 @@ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> */ -#include "DashSearchBarSpinner.h" +#include "SearchBarSpinner.h" #include <Nux/VLayout.h> @@ -25,8 +25,6 @@ namespace unity { -namespace dash -{ NUX_IMPLEMENT_OBJECT_TYPE(SearchBarSpinner); @@ -236,4 +234,3 @@ SearchBarSpinner::AcceptKeyNavFocus() } } -} diff --git a/plugins/unityshell/src/DashSearchBarSpinner.h b/plugins/unityshell/src/SearchBarSpinner.h index 097693053..4435208bd 100644 --- a/plugins/unityshell/src/DashSearchBarSpinner.h +++ b/plugins/unityshell/src/SearchBarSpinner.h @@ -17,8 +17,8 @@ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> */ -#ifndef DASH_SEARCH_BAR_SPINNER_H -#define DASH_SEARCH_BAR_SPINNER_H +#ifndef SEARCH_BAR_SPINNER_H +#define SEARCH_BAR_SPINNER_H #include <Nux/Nux.h> #include <Nux/View.h> @@ -29,8 +29,6 @@ namespace unity { -namespace dash -{ enum SpinnerState { @@ -80,6 +78,5 @@ private: }; } -} #endif diff --git a/plugins/unityshell/src/ShortcutController.cpp b/plugins/unityshell/src/ShortcutController.cpp index b659633ef..0a1dbd6d8 100644 --- a/plugins/unityshell/src/ShortcutController.cpp +++ b/plugins/unityshell/src/ShortcutController.cpp @@ -51,7 +51,7 @@ Controller::Controller(std::list<AbstractHint*>& hints) enabled_ = true; }); - ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, [&] (GVariant*) { + ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&] (GVariant*) { Hide(); }); @@ -60,7 +60,6 @@ Controller::Controller(std::list<AbstractHint*>& hints) model_.reset(new Model(hints)); model_->Fill(); - ConstructView(); fade_in_animator_.animation_updated.connect(sigc::mem_fun(this, &Controller::OnFadeInUpdated)); fade_in_animator_.animation_ended.connect(sigc::mem_fun(this, &Controller::OnFadeInEnded)); @@ -132,10 +131,14 @@ gboolean Controller::OnShowTimer(gpointer data) return FALSE; } + if (!self->view_window_) + self->ConstructView(); + self->ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST); 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()); @@ -173,7 +176,6 @@ void Controller::ConstructView() void Controller::SetWorkspace(nux::Geometry const& geo) { workarea_ = geo; - view_window_->SetGeometry(workarea_); } void Controller::Hide() diff --git a/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp b/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp index d07060404..babbce605 100644 --- a/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp +++ b/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp @@ -15,28 +15,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Bilal Akhtar <bilalakhtar@ubuntu.com> + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ -#include "Nux/Nux.h" -#include "Nux/BaseWindow.h" - -#include "BamfLauncherIcon.h" -#include "Launcher.h" -#include "LauncherController.h" -#include "PluginAdapter.h" -#include "FavoriteStore.h" - -#include "ubus-server.h" -#include "UBusMessages.h" - -#include <glib.h> -#include <glib/gvariant.h> #include <glib/gi18n-lib.h> -#include <gio/gio.h> -#include <libindicator/indicator-desktop-shortcuts.h> -#include <core/core.h> -#include <core/atoms.h> - #include "SoftwareCenterLauncherIcon.h" namespace unity @@ -44,58 +26,48 @@ namespace unity namespace launcher { -SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(BamfApplication* app, char* aptdaemon_trans_id, char* icon_path) -: BamfLauncherIcon(app) +SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(BamfApplication* app, + std::string const& aptdaemon_trans_id, + std::string const& icon_path) +: BamfLauncherIcon(app), + _aptdaemon_trans("org.debian.apt", + aptdaemon_trans_id, + "org.debian.apt.transaction", + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) { - _aptdaemon_trans_id = aptdaemon_trans_id; - - g_debug("Aptdaemon transaction ID: %s", _aptdaemon_trans_id); - - _aptdaemon_trans = new unity::glib::DBusProxy("org.debian.apt", - _aptdaemon_trans_id, - "org.debian.apt.transaction", - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START); - - _aptdaemon_trans->Connect("Finished", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnFinished)); - _aptdaemon_trans->Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged)); - - icon_name = icon_path; -} - -SoftwareCenterLauncherIcon::~SoftwareCenterLauncherIcon() { - + _aptdaemon_trans.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged)); + _aptdaemon_trans.Connect("Finished", [&] (GVariant *) { + tooltip_text = BamfName(); + SetQuirk(QUIRK_PROGRESS, false); + SetProgress(0.0f); + }); + + icon_name = icon_path.c_str(); + tooltip_text = _("Waiting to install"); } void -SoftwareCenterLauncherIcon::OnFinished(GVariant* params) { - - tooltip_text = BamfName(); - - SetQuirk(LauncherIcon::QUIRK_PROGRESS, FALSE); -} +SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params) +{ + gint32 progress; + glib::String property_name; + GVariant* property_value; -void -SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params) { + g_variant_get_child(params, 0, "s", property_name.AsOutParam()); - gint32 progress; - gchar* property_name; - GVariant* property_value; + if (property_name.Str() == "Progress") + { + g_variant_get_child(params, 1, "v", &property_value); + g_variant_get(property_value, "i", &progress); - g_variant_get_child (params, 0, "s", &property_name); - if (g_strcmp0 (property_name, "Progress") == 0) { - g_variant_get_child (params,1,"v",&property_value); - g_variant_get (property_value, "i", &progress); + if (progress < 100) + SetQuirk(QUIRK_PROGRESS, true); - if (progress < 100) { - SetQuirk(LauncherIcon::QUIRK_PROGRESS, TRUE); - tooltip_text = _("Waiting to install"); - } - SetProgress(((float)progress) / ((float)100)); - } - g_variant_unref(property_value); - g_free(property_name); + SetProgress(progress/100.0f); + } + g_variant_unref(property_value); } } diff --git a/plugins/unityshell/src/SoftwareCenterLauncherIcon.h b/plugins/unityshell/src/SoftwareCenterLauncherIcon.h index e12bc9918..258c3e947 100644 --- a/plugins/unityshell/src/SoftwareCenterLauncherIcon.h +++ b/plugins/unityshell/src/SoftwareCenterLauncherIcon.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2010 Canonical Ltd + * 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 @@ -15,46 +15,34 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Bilal Akhtar <bilalakhtar@ubuntu.com> + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ -#ifndef SOFTWARECENTERLAUNCHERICON_H -#define SOFTWARECENTERLAUNCHERICON_H +#ifndef SOFTWARE_CENTER_LAUNCHERICON_H +#define SOFTWARE_CENTER_LAUNCHERICON_H #include "BamfLauncherIcon.h" -#include <Nux/BaseWindow.h> -#include <NuxCore/Math/MathInc.h> -#include <core/core.h> -#include <gio/gio.h> -#include <glib.h> -#include <glib/gvariant.h> #include <UnityCore/GLibDBusProxy.h> - namespace unity { namespace launcher { - class SoftwareCenterLauncherIcon : public BamfLauncherIcon { public: - - SoftwareCenterLauncherIcon(BamfApplication* app, char* aptdaemon_trans_id, char* icon_path); - virtual ~SoftwareCenterLauncherIcon(); - - gchar* original_tooltip_text; + SoftwareCenterLauncherIcon(BamfApplication* app, + std::string const& aptdaemon_trans_id, + std::string const& icon_path); private: - char* _aptdaemon_trans_id; - unity::glib::DBusProxy* _aptdaemon_trans; - - void OnFinished(GVariant* params); + void OnPropertyChanged(GVariant* params); - void OnPropertyChanged(GVariant* params); + glib::DBusProxy _aptdaemon_trans; }; } } -#endif +#endif //SOFTWARE_CENTER_LAUNCHERICON_H diff --git a/plugins/unityshell/src/UBusMessages.h b/plugins/unityshell/src/UBusMessages.h index ccdfb4bd2..1200e3045 100644 --- a/plugins/unityshell/src/UBusMessages.h +++ b/plugins/unityshell/src/UBusMessages.h @@ -34,9 +34,11 @@ #define UBUS_PLACE_ENTRY_ACTIVATE_REQUEST "PLACE_ENTRY_ACTIVATE_REQUEST" #define UBUS_DASH_ABOUT_TO_SHOW "DASH_ABOUT_TO_SHOW" -// Signal send when places are shown or hidden -#define UBUS_PLACE_VIEW_HIDDEN "PLACE_VIEW_HIDDEN" -#define UBUS_PLACE_VIEW_SHOWN "PLACE_VIEW_SHOWN" +// Signal sent when an overlay interface is shown, includes a gvariant +// gvariant format is (sb), (interface-name, can_maximize?) +#define UBUS_OVERLAY_FORMAT_STRING "(sbi)" +#define UBUS_OVERLAY_HIDDEN "OVERLAY_HIDDEN" +#define UBUS_OVERLAY_SHOWN "OVERLAY_SHOWN" #define UBUS_PLACE_VIEW_QUEUE_DRAW "PLACE_VIEW_QUEUE_DRAW" @@ -76,6 +78,8 @@ // FIXME - fix the nux focus api so we don't need this #define UBUS_RESULT_VIEW_KEYNAV_CHANGED "RESULT_VIEW_KEYNAV_CHANGED" +#define UBUS_HUD_CLOSE_REQUEST "HUD_CLOSE_REQUEST" + // Signals sent when the switcher is shown, hidden or changes selection #define UBUS_SWITCHER_SHOWN "SWITCHER_SHOWN" #define UBUS_SWITCHER_SELECTION_CHANGED "SWITCHER_SELECTION_CHANGED" diff --git a/plugins/unityshell/src/WindowButtons.cpp b/plugins/unityshell/src/WindowButtons.cpp index 663677123..e552870b8 100644 --- a/plugins/unityshell/src/WindowButtons.cpp +++ b/plugins/unityshell/src/WindowButtons.cpp @@ -54,7 +54,7 @@ public: _normal_dash_tex(NULL), _prelight_dash_tex(NULL), _pressed_dash_tex(NULL), - _dash_is_open(false), + _overlay_is_open(false), _mouse_is_down(false), _place_shown_interest(0), _place_hidden_interest(0), @@ -66,11 +66,11 @@ public: dash::Settings::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::UpdateDashUnmaximize)); UBusServer* ubus = ubus_server_get_default(); - _place_shown_interest = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_SHOWN, - (UBusCallback)&WindowButton::OnPlaceViewShown, + _place_shown_interest = ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN, + (UBusCallback)&WindowButton::OnOverlayShown, this); - _place_hidden_interest = ubus_server_register_interest(ubus, UBUS_PLACE_VIEW_HIDDEN, - (UBusCallback)&WindowButton::OnPlaceViewHidden, + _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 */ @@ -106,7 +106,7 @@ public: GfxContext.PushClippingRectangle(geo); - if (_dash_is_open) + if (_overlay_is_open) { //FIXME should use HasMouseFocus() if (_mouse_is_down && IsMouseInside()) @@ -163,7 +163,7 @@ public: _prelight_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRELIGHT); _pressed_dash_tex = GetDashWindowButton(_type, panel::WindowState::PRESSED); - if (_dash_is_open) + if (_overlay_is_open) { if (_normal_dash_tex) SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight()); @@ -190,6 +190,7 @@ public: if (_pressed_dash_tex) _pressed_dash_tex->UnReference(); + //!!FIXME!! - don't have disabled instances of the (un)maximize buttons if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP) { // get maximize buttons @@ -208,7 +209,7 @@ public: // still check if the dash is really opened, // someone could change the form factor through dconf // when the dash is closed - if (_dash_is_open) + if (_overlay_is_open) { if (_normal_dash_tex) SetMinMaxSize(_normal_dash_tex->GetWidth(), _normal_dash_tex->GetHeight()); @@ -239,28 +240,37 @@ private: nux::BaseTexture* _normal_dash_tex; nux::BaseTexture* _prelight_dash_tex; nux::BaseTexture* _pressed_dash_tex; - bool _dash_is_open; + bool _overlay_is_open; + bool _overlay_can_maximize; bool _mouse_is_down; guint32 _place_shown_interest; guint32 _place_hidden_interest; double _opacity; - static void OnPlaceViewShown(GVariant* data, void* val) + static void OnOverlayShown(GVariant* data, void* val) { + 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); + WindowButton* self = (WindowButton*)val; - self->_dash_is_open = true; + self->_overlay_is_open = true; if (self->_normal_dash_tex) self->SetMinMaxSize(self->_normal_dash_tex->GetWidth(), self->_normal_dash_tex->GetHeight()); + self->_overlay_can_maximize = (can_maximise) ? true : false; + self->QueueDraw(); } - static void OnPlaceViewHidden(GVariant* data, void* val) + static void OnOverlayHidden(GVariant* data, void* val) { WindowButton* self = (WindowButton*)val; - self->_dash_is_open = false; + self->_overlay_is_open = false; if (self->_normal_tex) self->SetMinMaxSize(self->_normal_tex->GetWidth(), self->_normal_tex->GetHeight()); diff --git a/plugins/unityshell/src/nux-area-accessible.cpp b/plugins/unityshell/src/nux-area-accessible.cpp index 2c13fdfc8..ca4d02696 100644 --- a/plugins/unityshell/src/nux-area-accessible.cpp +++ b/plugins/unityshell/src/nux-area-accessible.cpp @@ -83,6 +83,8 @@ static void nux_area_accessible_focus_handler(AtkObject* accessible, gboolean focus_in); /* private */ static void on_focus_changed_cb(nux::Area* area, + bool has_focus, + nux::KeyNavDirection direction, AtkObject* accessible); static void on_parent_window_activate_cb(AtkObject* parent_window, NuxAreaAccessible* self); @@ -172,7 +174,7 @@ nux_area_accessible_initialize(AtkObject* accessible, area = dynamic_cast<nux::Area*>(nux_object); /* focus support based on Focusable, used on the Dash */ - area->OnKeyNavFocusChange.connect(sigc::bind(sigc::ptr_fun(on_focus_changed_cb), accessible)); + area->key_nav_focus_change.connect(sigc::bind(sigc::ptr_fun(on_focus_changed_cb), accessible)); atk_component_add_focus_handler(ATK_COMPONENT(accessible), nux_area_accessible_focus_handler); @@ -457,6 +459,8 @@ nux_area_accessible_parent_window_active(NuxAreaAccessible* self) static void on_focus_changed_cb(nux::Area* area, + bool has_focus, + nux::KeyNavDirection direction, AtkObject* accessible) { check_focus(NUX_AREA_ACCESSIBLE(accessible)); diff --git a/plugins/unityshell/src/unity-search-bar-accessible.cpp b/plugins/unityshell/src/unity-search-bar-accessible.cpp index 82ad67293..2e3fbabbb 100644 --- a/plugins/unityshell/src/unity-search-bar-accessible.cpp +++ b/plugins/unityshell/src/unity-search-bar-accessible.cpp @@ -20,7 +20,7 @@ * SECTION:unity-search_bar-accessible * @Title: UnitySearchBarAccessible * @short_description: Implementation of the ATK interfaces for #SearchBar - * @see_also: SearchBar at DashSearchBar.h + * @see_also: SearchBar at SearchBar.h * * #UnitySearchBarAccessible implements the required ATK interfaces for * #SearchBar, ie: exposing the different SearchBarIcon on the model as @@ -33,9 +33,9 @@ #include "unity-search-bar-accessible.h" #include "unitya11y.h" -#include "DashSearchBar.h" +#include "SearchBar.h" -using namespace unity::dash; +using namespace unity; /* GObject */ static void unity_search_bar_accessible_class_init(UnitySearchBarAccessibleClass* klass); diff --git a/plugins/unityshell/src/unitya11y.cpp b/plugins/unityshell/src/unitya11y.cpp index c37ae14dc..f5b310b53 100644 --- a/plugins/unityshell/src/unitya11y.cpp +++ b/plugins/unityshell/src/unitya11y.cpp @@ -299,7 +299,7 @@ unity_a11y_create_accessible(nux::Object* object) if (object->Type().IsDerivedFromType(unity::dash::ResultViewGrid::StaticObjectType)) return unity_rvgrid_accessible_new(object); - if (object->Type().IsDerivedFromType(unity::dash::SearchBar::StaticObjectType)) + if (object->Type().IsDerivedFromType(unity::SearchBar::StaticObjectType)) return unity_search_bar_accessible_new(object); if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType)) diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp index 568e238e6..b235a1a86 100644 --- a/plugins/unityshell/src/unityshell.cpp +++ b/plugins/unityshell/src/unityshell.cpp @@ -52,7 +52,6 @@ #include "unitya11y.h" -#include "ubus-server.h" #include "UBusMessages.h" #include "UScreen.h" @@ -119,6 +118,7 @@ UnityScreen::UnityScreen(CompScreen* screen) , dash_is_open_ (false) , grab_index_ (0) , painting_tray_ (false) + , last_hud_show_time_(0) { Timer timer; gfloat version; @@ -258,6 +258,8 @@ UnityScreen::UnityScreen(CompScreen* screen) } #endif + optionSetShowHudInitiate(boost::bind(&UnityScreen::ShowHudInitiate, this, _1, _2, _3)); + optionSetShowHudTerminate(boost::bind(&UnityScreen::ShowHudTerminate, this, _1, _2, _3)); optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); optionSetBacklightModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); @@ -333,12 +335,12 @@ UnityScreen::UnityScreen(CompScreen* screen) BackgroundEffectHelper::updates_enabled = true; - ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, [&](GVariant * args) { + ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&](GVariant * args) { dash_is_open_ = true; dash_monitor_ = g_variant_get_int32(args); RaiseInputWindows(); }); - ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, [&](GVariant * args) { dash_is_open_ = false; }); + ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, [&](GVariant * args) { dash_is_open_ = false; }); LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s"; } } @@ -371,7 +373,7 @@ void UnityScreen::initAltTabNextWindow() sout << "<Alt>" << XKeysymToString(above_tab_keysym); screen->removeAction(&optionGetAltTabNextWindow()); - + CompAction action = CompAction(); action.keyFromString(sout.str()); action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab); @@ -386,7 +388,7 @@ void UnityScreen::initAltTabNextWindow() sout << "<Alt><Shift>" << XKeysymToString(above_tab_keysym); screen->removeAction(&optionGetAltTabPrevWindow()); - + CompAction action = CompAction(); action.keyFromString(sout.str()); action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab); @@ -820,8 +822,8 @@ void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transfo bool UnityScreen::forcePaintOnTop () { return !allowWindowPaint || - ((switcher_controller_->Visible() || - dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL)))); + ((switcher_controller_->Visible() || + dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL)))); } void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha) @@ -967,7 +969,7 @@ bool UnityWindow::handleAnimations (unsigned int ms) { if (mShowdesktopHandler) if (mShowdesktopHandler->animate (ms)) - { + { delete mShowdesktopHandler; mShowdesktopHandler = NULL; return true; @@ -996,7 +998,7 @@ bool UnityShowdesktopHandler::shouldHide (CompWindow *w) return false; if (w->state () & (CompWindowStateSkipPagerMask | - CompWindowStateSkipTaskbarMask)) + CompWindowStateSkipTaskbarMask)) return false; if ((w->state () & CompWindowStateHiddenMask)) @@ -1669,7 +1671,7 @@ bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State altTabInitiateCommon(action, state, options); switcher_controller_->Select(1); // always select the current application } - + switcher_controller_->NextDetail(); action->setState(action->state() | CompAction::StateTermKey); @@ -1680,7 +1682,7 @@ bool UnityScreen::altTabPrevWindowInitiate(CompAction* action, CompAction::State { if (switcher_controller_->Visible()) switcher_controller_->PrevDetail(); - + return false; } @@ -1735,6 +1737,44 @@ void UnityScreen::OnLauncherEndKeyNav(GVariant* data) PluginAdapter::Default ()->restoreInputFocus (); } +bool UnityScreen::ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options) +{ + // to receive the Terminate event + if (state & CompAction::StateInitKey) + action->setState(action->state() | CompAction::StateTermKey); + + last_hud_show_time_ = g_get_monotonic_time(); + + return false; +} + +bool UnityScreen::ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options) +{ + if (optionGetShowHud().key().toString() == action->key().toString()) + { + if (switcher_controller_->Visible()) + return false; // early exit if the switcher is open + + gint64 current_time = g_get_monotonic_time(); + if (current_time - last_hud_show_time_ < 150 * 1000) + { + if (hud_controller_->IsVisible()) + { + ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST); + } + else + { + hud_controller_->ShowHud(); + } + last_hud_show_time_ = 0; + } + } + + action->setState(action->state() & ~CompAction::StateTermKey); + + return false; +} + gboolean UnityScreen::initPluginActions(gpointer data) { CompPlugin* p = CompPlugin::find("expo"); @@ -1821,7 +1861,7 @@ bool UnityScreen::initPluginForScreen(CompPlugin* p) bool result = screen->initPluginForScreen(p); if (p->vTable->name() == "unityshell") initAltTabNextWindow(); - + return result; } @@ -1834,8 +1874,8 @@ std::string UnityScreen::GetName() const return "Unity"; } -bool isNuxWindow (CompWindow* value) -{ +bool isNuxWindow (CompWindow* value) +{ std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList(); auto id = value->id(); @@ -1862,7 +1902,7 @@ const CompWindowList& UnityScreen::getWindowPaintList() void UnityScreen::RaiseInputWindows() { std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList(); - + for (auto window : xwns) { CompWindow* cwin = screen->findWindow(window); @@ -1995,7 +2035,7 @@ UnityWindow::focus () if (!window->onCurrentDesktop ()) return false; - /* Only withdrawn windows + /* Only withdrawn windows * which are marked hidden * are excluded */ if (!window->shaded () && @@ -2003,8 +2043,8 @@ UnityWindow::focus () (window->state () & CompWindowStateHiddenMask)) return false; - if (window->geometry ().x () + window->geometry ().width () <= 0 || - window->geometry ().y () + window->geometry ().height () <= 0 || + if (window->geometry ().x () + window->geometry ().width () <= 0 || + window->geometry ().y () + window->geometry ().height () <= 0 || window->geometry ().x () >= (int) screen->width ()|| window->geometry ().y () >= (int) screen->height ()) return false; @@ -2110,7 +2150,7 @@ void UnityWindow::stateChangeNotify(unsigned int lastState) !(lastState & CompWindowStateFullscreenMask)) UnityScreen::get (screen)->fullscreen_windows_.push_back(window); else if (lastState & CompWindowStateFullscreenMask && - !(window->state () & CompWindowStateFullscreenMask)) + !(window->state () & CompWindowStateFullscreenMask)) UnityScreen::get (screen)->fullscreen_windows_.remove(window); PluginAdapter::Default()->NotifyStateChange(window, window->state(), lastState); @@ -2259,9 +2299,9 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num) { case UnityshellOptions::BackgroundColor: { - nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f, - optionGetBackgroundColorGreen() / 65535.0f, - optionGetBackgroundColorBlue() / 65535.0f, + nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f, + optionGetBackgroundColorGreen() / 65535.0f, + optionGetBackgroundColorBlue() / 65535.0f, optionGetBackgroundColorAlpha() / 65535.0f); override_color.red = override_color.red / override_color.alpha; @@ -2309,7 +2349,10 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num) launcher_options->icon_size = optionGetIconSize(); launcher_options->tile_size = optionGetIconSize() + 6; - dash_controller_->launcher_width = optionGetIconSize() + 18; + hud_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1; + /* The launcher geometry includes 1px used to draw the right margin + * that must not be considered when drawing the dash */ + dash_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1; if (p) { @@ -2495,6 +2538,11 @@ void UnityScreen::initLauncher() /* Setup Places */ dash_controller_.reset(new dash::Controller()); dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized)); + + /* Setup Hud */ + hud_controller_.reset(new hud::Controller()); + AddChild(hud_controller_.get()); + LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s"; // Setup Shortcut Hint InitHints(); @@ -2644,7 +2692,7 @@ UnityWindow::~UnityWindow() if (mShowdesktopHandler) delete mShowdesktopHandler; - + if (focusdesktop_handle_) g_source_remove(focusdesktop_handle_); diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h index 0b05ef4f4..98d70542b 100644 --- a/plugins/unityshell/src/unityshell.h +++ b/plugins/unityshell/src/unityshell.h @@ -58,6 +58,8 @@ #include <compiztoolbox/compiztoolbox.h> #include <dlfcn.h> +#include "HudController.h" + namespace unity { @@ -202,6 +204,9 @@ public: bool altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); + /* handle hud key activations */ + bool ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); + bool ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options); bool launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options); @@ -268,6 +273,7 @@ private: dash::Controller::Ptr dash_controller_; panel::Controller::Ptr panel_controller_; switcher::Controller::Ptr switcher_controller_; + hud::Controller::Ptr hud_controller_; shortcut::Controller::Ptr shortcut_controller_; std::list<shortcut::AbstractHint*> hints_; @@ -322,6 +328,7 @@ private: CompWindowList fullscreen_windows_; bool painting_tray_; unsigned int tray_paint_mask_; + gint64 last_hud_show_time_; #ifndef USE_GLES ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP; @@ -396,7 +403,7 @@ public: UnityMinimizedHandler *mMinimizeHandler; UnityShowdesktopHandler *mShowdesktopHandler; - + private: guint focusdesktop_handle_; diff --git a/plugins/unityshell/unityshell.xml.in b/plugins/unityshell/unityshell.xml.in index f59218603..4dd37d46b 100644 --- a/plugins/unityshell/unityshell.xml.in +++ b/plugins/unityshell/unityshell.xml.in @@ -40,9 +40,14 @@ </requirement> </deps> <options> - <group> + <group> <_short>Behaviour</_short> - <option name="launcher_hide_mode" type="int"> + <option name="show_hud" type="key"> + <_short>Key to show the HUD</_short> + <_long>Make the HUD appear with this key</_long> + <default><Alt></default> + </option> + <option name="launcher_hide_mode" type="int"> <_short>Hide Launcher</_short> <_long>Make the launcher hide automatically after some time of inactivity: always or just when the focussed window is not over the launcher</_long> <min>0</min> @@ -64,16 +69,16 @@ <value>3</value> <_name>Dodge Active Window</_name> </desc> - </option> - <option name="show_launcher" type="key"> + </option> + <option name="show_launcher" type="key"> <_short>Key to show the launcher</_short> <_long>Make the launcher appear with that key</_long> <default><Super></default> </option> <option name="keyboard_focus" type="key"> - <_short>Key to put keyboard-focus on launcher</_short> - <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long> - <default><Alt>F1</default> + <_short>Key to put keyboard-focus on launcher</_short> + <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long> + <default><Alt>F1</default> </option> <option name="execute_command" type="key"> <_short>Key to execute a command</_short> @@ -118,37 +123,37 @@ <_long>fixme</_long> <default><Alt><Shift>Tab</default> </option> - <option name="alt_tab_right" type="key"> - <_short>Go right in the switcher</_short> - <_long>fixme</_long> - <default><Alt>Right</default> - <passive_grab>false</passive_grab> - <internal/> - </option> - <option name="alt_tab_left" type="key"> - <_short>Go left in the switcher</_short> - <_long>fixme</_long> - <default><Alt>Left</default> - <passive_grab>false</passive_grab> - <internal/> - </option> + <option name="alt_tab_right" type="key"> + <_short>Go right in the switcher</_short> + <_long>fixme</_long> + <default><Alt>Right</default> + <passive_grab>false</passive_grab> + <internal/> + </option> + <option name="alt_tab_left" type="key"> + <_short>Go left in the switcher</_short> + <_long>fixme</_long> + <default><Alt>Left</default> + <passive_grab>false</passive_grab> + <internal/> + </option> <option name="alt_tab_detail_start" type="key"> - <_short>Key to expose the windows in the switcher</_short> - <_long>fixme</_long> - <default><Alt>Down</default> - <passive_grab>false</passive_grab> - <internal/> + <_short>Key to expose the windows in the switcher</_short> + <_long>fixme</_long> + <default><Alt>Down</default> + <passive_grab>false</passive_grab> + <internal/> </option> - <option name="alt_tab_detail_stop" type="key"> - <_short>Key to collapse windows in the switcher</_short> - <_long>fixme</_long> - <default><Alt>Up</default> - <passive_grab>false</passive_grab> - <internal/> - </option> + <option name="alt_tab_detail_stop" type="key"> + <_short>Key to collapse windows in the switcher</_short> + <_long>fixme</_long> + <default><Alt>Up</default> + <passive_grab>false</passive_grab> + <internal/> + </option> <option name="alt_tab_next_window" type="key"> - <_short>Key to flip through windows in the switcher</_short> - <_long>fixme</_long> + <_short>Key to flip through windows in the switcher</_short> + <_long>fixme</_long> <passive_grab>false</passive_grab> </option> <option name="alt_tab_prev_window" type="key"> @@ -156,11 +161,11 @@ <_long>fixme</_long> <passive_grab>false</passive_grab> </option> - <option name="show_minimized_windows" type="bool"> - <_short>Show minimized windows in switcher</_short> - <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long> - <default>true</default> - </option> + <option name="show_minimized_windows" type="bool"> + <_short>Show minimized windows in switcher</_short> + <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long> + <default>true</default> + </option> </group> <group> <_short>Experimental</_short> @@ -359,7 +364,7 @@ <max>100</max> <default>75</default> </option> - + <option name="devices_option" type="int"> <_short>Show Devices</_short> <_long>Show devices in the launcher</_long> diff --git a/po/POTFILES.in b/po/POTFILES.in index 9154d35f1..18a88b12e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,7 +6,7 @@ plugins/unityshell/src/PlacesGroup.cpp plugins/unityshell/src/SpacerLauncherIcon.cpp plugins/unityshell/src/TrashLauncherIcon.cpp plugins/unityshell/src/BFBLauncherIcon.cpp -plugins/unityshell/src/DashSearchBar.cpp +plugins/unityshell/src/SearchBar.cpp plugins/unityshell/src/DashView.cpp plugins/unityshell/src/DesktopLauncherIcon.cpp plugins/unityshell/src/FilterExpanderLabel.cpp diff --git a/standalone-clients/CMakeLists.txt b/standalone-clients/CMakeLists.txt index 8a763eec9..3345dc4e3 100644 --- a/standalone-clients/CMakeLists.txt +++ b/standalone-clients/CMakeLists.txt @@ -8,7 +8,7 @@ set(UNITY_SRC ../plugins/unityshell/src) # Unit tests # find_package (PkgConfig) -set (TEST_DEPS "${UNITY_PLUGIN_DEPS};unity>=4.0.0") +set (TEST_DEPS "${UNITY_PLUGIN_DEPS};unity>=4.0.0 xtst") pkg_check_modules (TEST_UNIT_DEPS REQUIRED ${TEST_DEPS}) set (TESTDATADIR "${CMAKE_CURRENT_SOURCE_DIR}/data") @@ -26,7 +26,7 @@ set (CFLAGS ) add_definitions (${CFLAGS}) -set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm -lGL -lGLU") +set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm -lGL -lGLU -lXtst") link_libraries (${LIBS}) set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS}) @@ -47,10 +47,10 @@ add_executable (dash ${UNITY_SRC}/BackgroundEffectHelper.h ${UNITY_SRC}/BGHash.cpp ${UNITY_SRC}/BGHash.h - ${UNITY_SRC}/DashSearchBar.cpp - ${UNITY_SRC}/DashSearchBar.h - ${UNITY_SRC}/DashSearchBarSpinner.cpp - ${UNITY_SRC}/DashSearchBarSpinner.h + ${UNITY_SRC}/SearchBar.cpp + ${UNITY_SRC}/SearchBar.h + ${UNITY_SRC}/SearchBarSpinner.cpp + ${UNITY_SRC}/SearchBarSpinner.h ${UNITY_SRC}/DashView.cpp ${UNITY_SRC}/DashView.h ${UNITY_SRC}/DashViewPrivate.cpp @@ -84,6 +84,10 @@ add_executable (dash ${UNITY_SRC}/PlacesSimpleTile.h ${UNITY_SRC}/PlacesVScrollBar.cpp ${UNITY_SRC}/PlacesVScrollBar.h + ${UNITY_SRC}/DashView.cpp + ${UNITY_SRC}/DashView.h + ${UNITY_SRC}/DashViewPrivate.cpp + ${UNITY_SRC}/DashViewPrivate.h ${UNITY_SRC}/DashStyle.cpp ${UNITY_SRC}/IconLoader.cpp ${UNITY_SRC}/IconLoader.h @@ -178,6 +182,8 @@ add_executable (switcher ${UNITY_SRC}/WindowManager.cpp ${UNITY_SRC}/IconRenderer.cpp ${UNITY_SRC}/IconRenderer.h + ${UNITY_SRC}/Introspectable.cpp + ${UNITY_SRC}/Introspectable.h ${UNITY_SRC}/MockLauncherIcon.h ${UNITY_SRC}/BackgroundEffectHelper.h ${UNITY_SRC}/BackgroundEffectHelper.cpp @@ -251,6 +257,8 @@ add_executable (launcher ${UNITY_SRC}/BackgroundEffectHelper.cpp ${UNITY_SRC}/StaticCairoText.cpp ${UNITY_SRC}/StaticCairoText.h + ${UNITY_SRC}/SoftwareCenterLauncherIcon.cpp + ${UNITY_SRC}/SoftwareCenterLauncherIcon.h ${UNITY_SRC}/Introspectable.cpp ${UNITY_SRC}/Introspectable.h ${UNITY_SRC}/QuicklistMenuItem.cpp @@ -286,8 +294,10 @@ add_dependencies (keyutil unity-core-${UNITY_API_VERSION}) add_executable (quicklist ui/TestQuicklist.cpp - ui/EventFaker.cpp - ui/EventFaker.h + nux_test_framework.cpp + nux_test_framework.h + nux_automated_test_framework.cpp + nux_automated_test_framework.h ${UNITY_SRC}/Introspectable.cpp ${UNITY_SRC}/Introspectable.h ${UNITY_SRC}/QuicklistMenuItem.cpp @@ -347,16 +357,18 @@ add_dependencies(filters unity-core-${UNITY_API_VERSION}) add_executable (filter-bar TestFilterBar.cpp + ${UNITY_SRC}/FilterAllButton.cpp + ${UNITY_SRC}/FilterBar.cpp + ${UNITY_SRC}/FilterBasicButton.cpp ${UNITY_SRC}/FilterExpanderLabel.cpp ${UNITY_SRC}/FilterFactory.cpp - ${UNITY_SRC}/FilterBasicButton.cpp - ${UNITY_SRC}/FilterRatingsButton.cpp - ${UNITY_SRC}/FilterRatingsWidget.cpp ${UNITY_SRC}/FilterMultiRangeWidget.cpp ${UNITY_SRC}/FilterMultiRangeButton.cpp ${UNITY_SRC}/FilterGenreButton.cpp ${UNITY_SRC}/FilterGenreWidget.cpp - ${UNITY_SRC}/FilterBar.cpp + ${UNITY_SRC}/FilterRatingsButton.cpp + ${UNITY_SRC}/FilterRatingsWidget.cpp + ${UNITY_SRC}/FilterWidget.cpp ${UNITY_SRC}/DashStyle.cpp ${UNITY_SRC}/JSONParser.cpp ) @@ -456,6 +468,39 @@ add_executable (bg-hash ) add_dependencies (bg-hash unity-core-${UNITY_API_VERSION}) +add_executable (hud + StandaloneHud.cpp + ${UNITY_SRC}/BackgroundEffectHelper.cpp + ${UNITY_SRC}/BackgroundEffectHelper.h + ${UNITY_SRC}/DashSettings.cpp + ${UNITY_SRC}/DashSettings.h + ${UNITY_SRC}/DashStyle.cpp + ${UNITY_SRC}/HudButton.cpp + ${UNITY_SRC}/HudIcon.cpp + ${UNITY_SRC}/HudIcon.h + ${UNITY_SRC}/HudIconTextureSource.cpp + ${UNITY_SRC}/HudIconTextureSource.h + ${UNITY_SRC}/HudView.cpp + ${UNITY_SRC}/IMTextEntry.cpp + ${UNITY_SRC}/Introspectable.cpp + ${UNITY_SRC}/IconTexture.cpp + ${UNITY_SRC}/IconLoader.cpp + ${UNITY_SRC}/IconRenderer.cpp + ${UNITY_SRC}/IconTextureSource.cpp + ${UNITY_SRC}/JSONParser.cpp + ${UNITY_SRC}/OverlayRenderer.cpp + ${UNITY_SRC}/SearchBar.cpp + ${UNITY_SRC}/SearchBarSpinner.cpp + ${UNITY_SRC}/StaticCairoText.cpp + ${UNITY_SRC}/TextureCache.cpp + ${UNITY_SRC}/Timer.cpp + ${UNITY_SRC}/UBusWrapper.cpp + ${UNITY_SRC}/ubus-server.cpp + ${UNITY_SRC}/UScreen.cpp + ${UNITY_SRC}/UScreen.h + ) +add_dependencies (hud unity-core-${UNITY_API_VERSION}) + add_executable (test-shortcut TestShortcut.cpp ${UNITY_SRC}/AbstractSeparator.cpp diff --git a/standalone-clients/StandaloneHud.cpp b/standalone-clients/StandaloneHud.cpp new file mode 100644 index 000000000..03d1aab85 --- /dev/null +++ b/standalone-clients/StandaloneHud.cpp @@ -0,0 +1,171 @@ +/* + * Copyright 2010 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 + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include <sstream> +#include "Nux/Nux.h" +#include "Nux/VLayout.h" +#include "Nux/Button.h" +#include "Nux/TextureArea.h" +#include "Nux/WindowThread.h" +#include "NuxGraphics/GraphicsEngine.h" +#include <gtk/gtk.h> + +#include "HudView.h" +#include "DashStyle.h" +#include "DashSettings.h" +#include <NuxCore/Logger.h> + +namespace +{ + nux::logging::Logger logger("unity.tests.Hud"); +} + +class TestRunner +{ +public: + TestRunner (); + ~TestRunner (); + + static void InitWindowThread (nux::NThread* thread, void* InitData); + void Init (); + nux::Layout *layout; + unity::hud::View* hud_view_; + unity::dash::Settings dash_settings_; + +private: + unity::hud::Hud hud_service_; +}; + +TestRunner::TestRunner () + : hud_service_("com.canonical.hud", "/com/canonical/hud") +{ +} + +TestRunner::~TestRunner () +{ +} + +void TestRunner::Init () +{ + LOG_WARNING(logger) << "test init"; + layout = new nux::VLayout(); + + hud_view_ = new unity::hud::View(); + + layout->AddView (hud_view_, 1, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL); + nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus()); + + nux::GetWindowThread()->SetLayout (layout); + + // things the controller normally does + hud_service_.queries_updated.connect([&] (unity::hud::Hud::Queries queries) { + hud_view_->SetQueries(queries); + std::string icon_name = ""; + for (auto query = queries.begin(); query != queries.end(); query++) + { + if (!(*query)->icon_name.empty()) + { + LOG_DEBUG(logger) << "Setting icon name to: " << (*query)->icon_name; + icon_name = (*query)->icon_name; + break; + } + } + + hud_view_->SetIcon(icon_name); + + }); + + hud_view_->query_activated.connect([&] (unity::hud::Query::Ptr query) { + hud_service_.ExecuteQuery(query, 0); + }); + + hud_view_->query_selected.connect([&] (unity::hud::Query::Ptr query) { + hud_view_->SetIcon(query->icon_name); + }); + + hud_view_->search_changed.connect([&] (std::string search_string) { + hud_service_.RequestQuery(search_string); + }); + + hud_view_->search_activated.connect([&] (std::string search_string) { + hud_service_.ExecuteQueryBySearch(search_string, 0); + }); + + hud_service_.RequestQuery(""); + + hud_view_->SetWindowGeometry(layout->GetAbsoluteGeometry(), layout->GetGeometry()); + +} + +void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) +{ + TestRunner *self = (TestRunner *) InitData; + self->Init (); +} + +void +ControlThread (nux::NThread* thread, + void* data) +{ + // sleep for 3 seconds + nux::SleepForMilliseconds (3000); + printf ("ControlThread successfully started\n"); +} + + +int main(int argc, char **argv) +{ + nux::SystemThread* st = NULL; + nux::WindowThread* wt = NULL; + + // no real tests right now, just make sure we don't get any criticals and such + // waiting on nice perceptual diff support before we can build real tests + // for views + + g_type_init (); + gtk_init (&argc, &argv); + + nux::NuxInitialize(0); + + // Slightly higher as we're more likely to test things we know will fail + nux::logging::configure_logging("unity.hud=debug"); + + nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY")); + LOG_DEBUG(logger) << "starting the standalone hud"; + // The instances for the pseudo-singletons. + unity::dash::Style dash_style; + + TestRunner *test_runner = new TestRunner (); + wt = nux::CreateGUIThread(TEXT("Hud Prototype Test"), + 1200, 768, + 0, + &TestRunner::InitWindowThread, + test_runner); + + st = nux::CreateSystemThread (NULL, ControlThread, wt); + + if (st) + st->Start (NULL); + + wt->Run (NULL); + delete st; + delete wt; + return 0; +} diff --git a/standalone-clients/TestFilterBar.cpp b/standalone-clients/TestFilterBar.cpp index 020a4ffb7..e12e2dd06 100644 --- a/standalone-clients/TestFilterBar.cpp +++ b/standalone-clients/TestFilterBar.cpp @@ -53,7 +53,7 @@ TestRunner::~TestRunner () void TestRunner::Init () { - unity::FilterBar *filterbar = new unity::FilterBar(NUX_TRACKER_LOCATION); + auto *filterbar = new unity::dash::FilterBar(NUX_TRACKER_LOCATION); layout = new nux::VLayout(NUX_TRACKER_LOCATION); diff --git a/standalone-clients/TestFilters.cpp b/standalone-clients/TestFilters.cpp index 1e4689b13..cddf2ac0d 100644 --- a/standalone-clients/TestFilters.cpp +++ b/standalone-clients/TestFilters.cpp @@ -57,13 +57,13 @@ TestRunner::~TestRunner () void TestRunner::Init () { - unity::FilterBasicButton *button = new unity::FilterBasicButton ("hello world", NUX_TRACKER_LOCATION); - unity::FilterRatingsWidget *ratings = new unity::FilterRatingsWidget (NUX_TRACKER_LOCATION); - unity::FilterGenreButton *genre_button = new unity::FilterGenreButton ("genre button", NUX_TRACKER_LOCATION); + auto *button = new unity::dash::FilterBasicButton ("hello world", NUX_TRACKER_LOCATION); + auto *ratings = new unity::dash::FilterRatingsWidget (NUX_TRACKER_LOCATION); + auto *genre_button = new unity::dash::FilterGenreButton ("genre button", NUX_TRACKER_LOCATION); - unity::FilterGenre *genre = new unity::FilterGenre(NUX_TRACKER_LOCATION); + auto *genre = new unity::dash::FilterGenre(3, NUX_TRACKER_LOCATION); - unity::FilterMultiRange *multi_range = new unity::FilterMultiRange (NUX_TRACKER_LOCATION); + auto *multi_range = new unity::dash::FilterMultiRange (NUX_TRACKER_LOCATION); layout = new nux::VLayout(NUX_TRACKER_LOCATION); diff --git a/standalone-clients/nux_automated_test_framework.cpp b/standalone-clients/nux_automated_test_framework.cpp new file mode 100644 index 000000000..970db58ea --- /dev/null +++ b/standalone-clients/nux_automated_test_framework.cpp @@ -0,0 +1,461 @@ +/* + * Copyright 2010 Inalogic Inc. + * + * 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 + * <http://www.gnu.org/licenses/> + * + * Authored by: Jay Taoko <jaytaoko@inalogic.com> + * + */ + +#include "Nux/Nux.h" +#include <X11/extensions/XTest.h> +#include <X11/keysym.h> +#include "nux_automated_test_framework.h" + + +int NuxAutomatedTestFramework::mouse_motion_time_span = 1000; // milliseconds +int NuxAutomatedTestFramework::mouse_click_time_span = 300; // milliseconds +int NuxAutomatedTestFramework::minimum_sleep_time = 600; // milliseconds +int NuxAutomatedTestFramework::safety_border_inside_view = 1; // pixels + +NuxAutomatedTestFramework::NuxAutomatedTestFramework(nux::WindowThread *window_thread) +{ + ready_to_start_ = false; + display_ = NULL; + window_thread_ = window_thread; + window_x_ = 0; + window_y_ = 0; + window_width_ = 0; + window_height_ = 0; + terminate_when_test_over_ = false; +} + +NuxAutomatedTestFramework::~NuxAutomatedTestFramework() +{ + XCloseDisplay(display_); +} + +void NuxAutomatedTestFramework::SetTerminateProgramWhenDone(bool terminate) +{ + terminate_when_test_over_ = terminate; +} + +bool NuxAutomatedTestFramework::WhenDoneTerminateProgram() +{ + return terminate_when_test_over_; +} + +void NuxAutomatedTestFramework::Startup() +{ + display_ = XOpenDisplay(NULL); + nux::Geometry rect = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); + //nuxDebugMsg("Window geometry: (%d, %d, %d, %d)", rect.x, rect.y, rect.width, rect.height); + + window_x_ = rect.x; + window_y_ = rect.y; + window_width_ = rect.width; + window_height_ = rect.height; +} + +void NuxAutomatedTestFramework::ViewSendMouseClick(nux::View *view, int button) +{ + nux::Rect r; + if (view) + { + r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2); + } + else + { + r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); + r.OffsetPosition(r.width/2, r.height/2); + } + + SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); + SendFakeMouseEvent(button, true); + nux::SleepForMilliseconds(NuxAutomatedTestFramework::mouse_click_time_span); + SendFakeMouseEvent(button, false); + + XSync(display_, False); + nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); +} + +void NuxAutomatedTestFramework::ViewSendMouseDoubleClick(nux::View *view, int button) +{ + nux::Rect r; + if (view) + { + r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2); + } + else + { + r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); + r.OffsetPosition(r.width/2, r.height/2); + } + + // Send the mouse to the center of the view + SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); + + XTestFakeButtonEvent(display_, button, true, CurrentTime); + XTestFakeButtonEvent(display_, button, false, CurrentTime); + XTestFakeButtonEvent(display_, button, true, CurrentTime); + XTestFakeButtonEvent(display_, button, false, CurrentTime); + XSync(display_, False); + nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); +} + +void NuxAutomatedTestFramework::ViewSendMouseDown(nux::View *view, int button) +{ + XEvent event; + /* Get the current pointer position */ + XQueryPointer(display_, RootWindow(display_, 0), + &event.xbutton.root, &event.xbutton.window, + &event.xbutton.x_root, &event.xbutton.y_root, + &event.xbutton.x, &event.xbutton.y, + &event.xbutton.state); + + int current_x = event.xbutton.x - window_x_; + int current_y = event.xbutton.y - window_y_; + + nux::Rect r = view->GetAbsoluteGeometry(); + + if (!r.IsInside(nux::Point(current_x, current_y))) + { + // The mouse pointer is not inside the view. + // Move the mouse pointer to the center of the view. + r.OffsetPosition(window_x_, window_y_); + + // Go to the center of the view + int view_center_x = r.x + r.width/2; + int view_center_y = r.y + r.height/2; + SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span); + nux::SleepForMilliseconds(minimum_sleep_time); + } + SendFakeMouseEvent(button, true); +} + +void NuxAutomatedTestFramework::ViewSendMouseUp(nux::View *view, int button) +{ + // nux::Rect r = view->GetAbsoluteGeometry(); + // r.OffsetPosition(window_x_, window_y_); + + // int view_center_x = r.x + r.width/2; + // int view_center_y = r.y + r.height/2; + + // SendFakeMouseMotionEvent(view_center_x, view_center_y, 1000); + // nux::SleepForMilliseconds(minimum_sleep_time); + SendFakeMouseEvent(button, false); +} + +void NuxAutomatedTestFramework::ViewSendMouseDrag(nux::View *view, int button_index, int x0, int y0, int x1, int y1) +{ + nux::Rect r0 = view->GetAbsoluteGeometry(); + nux::Rect r1 = view->GetAbsoluteGeometry(); + r0.OffsetPosition(window_x_ + x0, window_y_ + y0); + r1.OffsetPosition(window_x_ + x1, window_y_ + y1); + + // Go to first point + SendFakeMouseMotionEvent(r0.x, r0.y, NuxAutomatedTestFramework::mouse_motion_time_span); + nux::SleepForMilliseconds(minimum_sleep_time); + + // Mouse down + ViewSendMouseDown(view, button_index); + + // Drag to second point + SendFakeMouseMotionEvent(r1.x, r1.y, NuxAutomatedTestFramework::mouse_motion_time_span); + nux::SleepForMilliseconds(minimum_sleep_time); + + // Mouse up + ViewSendMouseUp(view, button_index); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionTo(nux::View *view, int x, int y) +{ + nux::Rect r; + if (view) + { + r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_ + x, window_y_ + y); + } + else + { + r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); + r.OffsetPosition(x, y); + } + + SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionToCenter(nux::View *view) +{ + nux::Rect r; + if (view) + { + r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_, window_y_); + } + else + { + r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); + } + + int view_center_x = r.x + r.width/2; + int view_center_y = r.y + r.height/2; + + SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionToTopLeft(nux::View *view) +{ + nux::Rect r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_, window_y_); + + SendFakeMouseMotionEvent(r.x + safety_border_inside_view, r.y + safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionToTopRight(nux::View *view) +{ + nux::Rect r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_, window_y_); + + SendFakeMouseMotionEvent(r.x + r.width-1, r.y+safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomLeft(nux::View *view) +{ + nux::Rect r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_, window_y_); + + SendFakeMouseMotionEvent(r.x+safety_border_inside_view, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomRight(nux::View *view) +{ + nux::Rect r = view->GetAbsoluteGeometry(); + r.OffsetPosition(window_x_, window_y_); + + SendFakeMouseMotionEvent(r.x + r.width-1, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span); +} + +void NuxAutomatedTestFramework::ViewSendChar(const char c) +{ + KeySym modifier = 0; + + if ((c >= 'A') && (c <= 'Z')) + { + modifier = XK_Shift_L; + } + + std::string s(1, c); + SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier); + nux::SleepForMilliseconds(300); +} + +void NuxAutomatedTestFramework::ViewSendString(const std::string &str) +{ + int l = str.length(); + if (l == 0) + return; + + int i = 0; + + while (i < l) + { + KeySym modifier = 0; + char c = str[i++]; + + if ((c >= 'A') && (c <= 'Z')) + { + modifier = XK_Shift_L; + } + + std::string s(1, c); + SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier); + nux::SleepForMilliseconds(300); + } +} + +void NuxAutomatedTestFramework::ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c) +{ + KeyCode keycode = 0; + KeyCode modcode0 = 0; + KeyCode modcode1 = 0; + KeyCode modcode2 = 0; + + std::string s(1, c); + keycode = XKeysymToKeycode(display_, XStringToKeysym(s.c_str())); + XTestGrabControl(display_, True); + + /* Generate modkey press */ + if (modsym0 != 0) + { + modcode0 = XKeysymToKeycode(display_, modsym0); + XTestFakeKeyEvent(display_, modcode0, True, 0); + } + if (modsym1 != 0) + { + modcode1 = XKeysymToKeycode(display_, modsym1); + XTestFakeKeyEvent(display_, modcode1, True, 0); + } + if (modsym2 != 0) + { + modcode2 = XKeysymToKeycode(display_, modsym2); + XTestFakeKeyEvent(display_, modcode2, True, 0); + } + + /* Generate regular key press and release */ + XTestFakeKeyEvent(display_, keycode, True, 0); + XTestFakeKeyEvent(display_, keycode, False, 0); + + /* Generate modkey release */ + if (modsym0 != 0) + { + XTestFakeKeyEvent(display_, modcode0, False, 0); + } + if (modsym1 != 0) + { + XTestFakeKeyEvent(display_, modcode1, False, 0); + } + if (modsym2 != 0) + { + XTestFakeKeyEvent(display_, modcode2, False, 0); + } + + XSync(display_, False); + XTestGrabControl(display_, False); +} + +void NuxAutomatedTestFramework::ViewSendCtrlA() +{ + ViewSendKeyCombo(XK_Control_L, 0, 0, 'a'); +} + +void NuxAutomatedTestFramework::ViewSendDelete() +{ + SendFakeKeyEvent(XK_Delete, 0); +} + +void NuxAutomatedTestFramework::ViewSendBackspace() +{ + SendFakeKeyEvent(XK_BackSpace, 0); +} + +void NuxAutomatedTestFramework::ViewSendEscape() +{ + SendFakeKeyEvent(XK_Escape, 0); +} + +void NuxAutomatedTestFramework::ViewSendTab() +{ + SendFakeKeyEvent(XK_Tab, 0); +} + +void NuxAutomatedTestFramework::ViewSendReturn() +{ + SendFakeKeyEvent(XK_Return, 0); +} + +void NuxAutomatedTestFramework::PutMouseAt(int x, int y) +{ + XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime); + XSync(display_, False); +} + +void NuxAutomatedTestFramework::SendFakeKeyEvent(KeySym keysym, KeySym modsym) +{ + KeyCode keycode = 0; + KeyCode modcode = 0; + + keycode = XKeysymToKeycode(display_, keysym); + XTestGrabControl(display_, True); + + /* Generate modkey press */ + if (modsym != 0) + { + modcode = XKeysymToKeycode(display_, modsym); + XTestFakeKeyEvent(display_, modcode, True, 0); + } + + /* Generate regular key press and release */ + XTestFakeKeyEvent(display_, keycode, True, 0); + XTestFakeKeyEvent(display_, keycode, False, 0); + + /* Generate modkey release */ + if (modsym != 0) + { + XTestFakeKeyEvent(display_, modcode, False, 0); + } + + XSync(display_, False); + XTestGrabControl(display_, False); +} + +void NuxAutomatedTestFramework::SendFakeMouseEvent(int mouse_button_index, bool pressed) +{ + XTestFakeButtonEvent(display_, mouse_button_index, pressed, CurrentTime); + XSync(display_, False); +} + +void NuxAutomatedTestFramework::SendFakeMouseMotionEvent(int x, int y, int ms_delay) +{ + XEvent event; + /* Get the current pointer position */ + XQueryPointer(display_, RootWindow(display_, 0), + &event.xbutton.root, &event.xbutton.window, + &event.xbutton.x_root, &event.xbutton.y_root, + &event.xbutton.x, &event.xbutton.y, + &event.xbutton.state); + + int old_x = event.xbutton.x; + int old_y = event.xbutton.y; + + int n_iteration = ms_delay / 16.0f; + + //nuxDebugMsg("n_iteration: %d", n_iteration); + + if (n_iteration < 1) + { + n_iteration = 1; + } + + XSync(display_, False); + + for (int i = 0; i < n_iteration; i++) + { + float t = ((float)i + 1.0f) / n_iteration; + + int cx = (1.0f - t) * old_x + t * x; + int cy = (1.0f - t) * old_y + t * y; + XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), cx, cy, CurrentTime); + XSync(display_, False); + usleep(16*1000); + } + + XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime); + XSync(display_, False); + nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); +} + +void NuxAutomatedTestFramework::TestReportMsg(bool b, const char* msg) +{ + if (b) + { + nuxOkMsg("%s: %s", msg, "Ok"); + } + else + { + nuxAlertMsg("%s: %s", msg, "Failed"); + } +} \ No newline at end of file diff --git a/standalone-clients/nux_automated_test_framework.h b/standalone-clients/nux_automated_test_framework.h new file mode 100644 index 000000000..63c9b52d7 --- /dev/null +++ b/standalone-clients/nux_automated_test_framework.h @@ -0,0 +1,127 @@ +/* + * Copyright 2010 Inalogic Inc. + * + * 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 + * <http://www.gnu.org/licenses/> + * + * Authored by: Jay Taoko <jaytaoko@inalogic.com> + * + */ + +#include <X11/extensions/XTest.h> +#include <X11/keysym.h> + +#ifndef NUX_AUTOMATED_TEST_FRAMEWORK_H +#define NUX_AUTOMATED_TEST_FRAMEWORK_H + +class NuxAutomatedTestFramework +{ +public: + NuxAutomatedTestFramework(nux::WindowThread *window_thread); + virtual ~NuxAutomatedTestFramework(); + + //! Initialize the testing framework. + void Startup(); + + //! Simulate a mouse click event on a view. + /*! + Move the mouse to the middle of the view (if it isn't there already) and perform a click event. + */ + void ViewSendMouseClick(nux::View *view, int button); + //! Simulate a mouse double click event on a view. + /*! + Move the mouse to the middle of the view (if it isn't there already) and perform a double click event. + */ + void ViewSendMouseDoubleClick(nux::View *view, int button); + //! Simulate a mouse down event on a view. + void ViewSendMouseDown(nux::View *view, int button); + //! Simulate a mouse up event on a view. + void ViewSendMouseUp(nux::View *view, int button); + //! Simulate a drag event on a view from (x0, y0) to (x1, y1). + void ViewSendMouseDrag(nux::View *view, int button, int x0, int y0, int x1, int y1); + //! Simulate mouse motion to (x, y). + void ViewSendMouseMotionTo(nux::View *view, int x, int y); + //! Simulate mouse motion to the center of a view. + void ViewSendMouseMotionToCenter(nux::View *view); + //! Simulate mouse motion to the top left corner of a view. + void ViewSendMouseMotionToTopLeft(nux::View *view); + //! Simulate mouse motion to the top right corner of a view. + void ViewSendMouseMotionToTopRight(nux::View *view); + //! Simulate mouse motion to the bottom left corner of a view. + void ViewSendMouseMotionToBottomLeft(nux::View *view); + //! Simulate mouse motion to the bottom right corner of a view. + void ViewSendMouseMotionToBottomRight(nux::View *view); + + //! Simulate a key event. + void ViewSendChar(const char c); + //! Simulate a succession of key events. + void ViewSendString(const std::string &str); + //! Simulate a key combo. + void ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c); + //! Simulate Ctrl+a. + void ViewSendCtrlA(); + //! Simulate Delete key. + void ViewSendDelete(); + //! Simulate Backspace key. + void ViewSendBackspace(); + //! Simulate Escape key. + void ViewSendEscape(); + //! Simulate Tab key. + void ViewSendTab(); + //! Simulate Return key. + void ViewSendReturn(); + + //! Put the mouse pointer anywhere on the display. + void PutMouseAt(int x, int y); + + //! Simulate a mouse event. + void SendFakeMouseEvent(int mouse_button_index, bool pressed); + //! Simulate a key event. + void SendFakeKeyEvent(KeySym keysym, KeySym modsym); + //! Simulate a mouse motion event. + void SendFakeMouseMotionEvent(int x, int y, int ms_delay); + + /*! + Set the test thread to terminae the program when testing is over. + */ + void SetTerminateProgramWhenDone(bool terminate); + /*! + Return true if the test thread is allowed to terminate the program after testing is over. + */ + bool WhenDoneTerminateProgram(); + + /*! + Print a report message to the console. + */ + void TestReportMsg(bool b, const char* msg); + +private: + void WindowConfigSignal(int x, int y, int width, int height); + + bool ready_to_start_; + Display* display_; + nux::WindowThread *window_thread_; + int window_x_; + int window_y_; + int window_width_; + int window_height_; + bool terminate_when_test_over_; + + static int mouse_motion_time_span; // in milliseconds + static int mouse_click_time_span; // in milliseconds + static int minimum_sleep_time; // in milliseconds + static int safety_border_inside_view; // in pixels +}; + +#endif // NUX_AUTOMATED_TEST_FRAMEWORK_H + diff --git a/standalone-clients/nux_test_framework.cpp b/standalone-clients/nux_test_framework.cpp new file mode 100644 index 000000000..f839e169e --- /dev/null +++ b/standalone-clients/nux_test_framework.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2010 Inalogic Inc. + * + * 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 + * <http://www.gnu.org/licenses/> + * + * Authored by: Jay Taoko <jaytaoko@inalogic.com> + * + */ + +#include "Nux/Nux.h" +#include "Nux/VLayout.h" +#include "Nux/HLayout.h" +#include "Nux/WindowThread.h" +#include "Nux/TextEntry.h" +#include "nux_test_framework.h" + + +NuxTestFramework::NuxTestFramework(const char* program_name, + int window_width, + int window_height, + int program_life_span) +{ + ready_to_go_ = false; + window_width_ = window_width; + window_height_ = window_height; + + if (window_width_ < 100) + window_width_ = 100; + + if (window_height_ < 100) + window_height_ = 100; + + timeout_signal_ = NULL; + window_thread_ = NULL; + program_name_ = program_name; + program_life_span_ = program_life_span; + + if (program_life_span_ > 0 && program_life_span_ < 1000) + { + // Minimum life span is 1 second. + program_life_span_ = 1000; + } +} + +NuxTestFramework::~NuxTestFramework() +{ + if (window_thread_) + delete window_thread_; +} + +void NuxTestFramework::Startup() +{ + nux::NuxInitialize(0); + window_thread_ = nux::CreateGUIThread(program_name_.c_str(), window_width_, window_height_, NULL, NULL, NULL); + + window_thread_->window_configuration.connect(sigc::mem_fun(this, &NuxTestFramework::WaitForConfigureEvent)); +} + +void NuxTestFramework::UserInterfaceSetup() +{ + // nux::VLayout *MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); + // nux::TextEntry *text_entry_0 = new nux::TextEntry(TEXT("0123456789abcdefghij"), NUX_TRACKER_LOCATION); + + // MainVLayout->AddView(text_entry_0, 0, nux::eCenter, nux::eFull); + // MainVLayout->SetVerticalInternalMargin(10); + // MainVLayout->SetContentDistribution(nux::eStackCenter); + + // nux::GetWindowThread()->SetLayout(MainVLayout); + // nux::ColorLayer background(nux::Color(0xFF4D4D4D)); + // window_thread_->SetWindowBackgroundPaintLayer(&background); +} + +void NuxTestFramework::Run() +{ + if (window_thread_ == NULL) + return; + + if (program_life_span_ > 0) + { + timeout_signal_ = new nux::TimeOutSignal(); + timeout_signal_->time_expires.connect(sigc::mem_fun(this, &NuxTestFramework::ProgramExitCall)); + window_thread_->GetTimerHandler().AddTimerHandler(program_life_span_, timeout_signal_, NULL, NULL); + } + + window_thread_->Run(NULL); +} + +bool NuxTestFramework::ReadyToGo() +{ + return window_thread_; +} + +nux::WindowThread* NuxTestFramework::GetWindowThread() +{ + return window_thread_; +} + +void NuxTestFramework::ProgramExitCall(void *data) +{ + if (window_thread_) + window_thread_->ExitMainLoop(); +} + +void NuxTestFramework::WaitForConfigureEvent(int x, int y, int width, int height) +{ + ready_to_go_ = true; +} + + +// int main(int argc, char **argv) +// { +// NuxTestFramework test("Text Entry", 300, 300, 3000); +// test.Startup(); +// test.UserInterfaceSetup(); +// test.Run(); + +// return 0; +// } diff --git a/standalone-clients/nux_test_framework.h b/standalone-clients/nux_test_framework.h new file mode 100644 index 000000000..59855c986 --- /dev/null +++ b/standalone-clients/nux_test_framework.h @@ -0,0 +1,61 @@ +/* + * Copyright 2010 Inalogic Inc. + * + * 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 + * <http://www.gnu.org/licenses/> + * + * Authored by: Jay Taoko <jaytaoko@inalogic.com> + * + */ + +#include "Nux/Nux.h" +#include "Nux/VLayout.h" +#include "Nux/HLayout.h" +#include "Nux/WindowThread.h" +#include "Nux/TextEntry.h" + +#ifndef NUXTESTFRAMEWORK_H +#define NUXTESTFRAMEWORK_H + +class NuxTestFramework +{ +public: + NuxTestFramework(const char* program_name, int window_width, int window_height, int program_life_span); + virtual ~NuxTestFramework(); + + virtual void Startup(); + virtual void UserInterfaceSetup(); + virtual void Run(); + + bool ReadyToGo(); + + nux::WindowThread* GetWindowThread(); + +public: + std::string program_name_; + int program_life_span_; //!< The program will auto-terminate after a delay in milliseconds. + nux::TimeOutSignal *timeout_signal_; + + nux::WindowThread *window_thread_; + + int window_width_; + int window_height_; + +private: + void ProgramExitCall(void *data); + void WaitForConfigureEvent(int x, int y, int width, int height); + bool ready_to_go_; +}; + +#endif // NUXTESTFRAMEWORK_H + diff --git a/standalone-clients/ui/TestQuicklist.cpp b/standalone-clients/ui/TestQuicklist.cpp index 7b484e5af..75ac309fc 100644 --- a/standalone-clients/ui/TestQuicklist.cpp +++ b/standalone-clients/ui/TestQuicklist.cpp @@ -14,11 +14,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Mirco Müller <mirco.mueller@canonical.com> + * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> */ #include <glib.h> #include <gtk/gtk.h> -#include <dbus/dbus-glib.h> #include "Nux/Nux.h" #include "Nux/VLayout.h" @@ -31,101 +31,175 @@ #include "QuicklistMenuItemCheckmark.h" #include "QuicklistMenuItemRadio.h" -#include "EventFaker.h" -#include <X11/Xlib.h> +#include "nux_test_framework.h" +#include "nux_automated_test_framework.h" #define WIN_WIDTH 400 -#define WIN_HEIGHT 300 +#define WIN_HEIGHT 400 -gboolean gResult[3] = {false, false, false}; +class TestQuicklist: public NuxTestFramework +{ +public: + TestQuicklist(const char *program_name, int window_width, int window_height, int program_life_span); + ~TestQuicklist(); + + virtual void UserInterfaceSetup(); + int ItemNaturalPosition(QuicklistMenuItem* item); + bool HasNthItemActivated(unsigned int index); + + QuicklistView* quicklist_; + std::map<QuicklistMenuItem*,bool> activated_; + +private: + QuicklistMenuItemSeparator* createSeparatorItem(); + QuicklistMenuItemLabel* createLabelItem(std::string const& label, bool enabled = true); + QuicklistMenuItemCheckmark* createCheckmarkItem(std::string const& label, bool enabled, bool checked); + QuicklistMenuItemRadio* createRadioItem(std::string const& label, bool enabled, bool checked); + void AddItem(QuicklistMenuItem* item); + + void connectToActivatedSignal(DbusmenuMenuitem* item); + static void activatedCallback(DbusmenuMenuitem* item, int time, gpointer data); + + std::map<DbusmenuMenuitem*, QuicklistMenuItem*> menus2qitem_; +}; + +TestQuicklist::TestQuicklist(const char *program_name, int window_width, int window_height, int program_life_span) + : NuxTestFramework(program_name, window_width, window_height, program_life_span), + quicklist_(nullptr) +{} + +TestQuicklist::~TestQuicklist() +{ + if (quicklist_) + quicklist_->UnReference(); +} + +int TestQuicklist::ItemNaturalPosition(QuicklistMenuItem* item) +{ + int pos = 1; + + for (auto it : quicklist_->GetChildren()) + { + if (it == item) + return pos; + + if (it->GetItemType() != MENUITEM_TYPE_SEPARATOR) + pos++; + } -QuicklistView* gQuicklist = NULL; -QuicklistMenuItemCheckmark* gCheckmark = NULL; -QuicklistMenuItemRadio* gRadio = NULL; -QuicklistMenuItemLabel* gLabel = NULL; + return -1; +} -void -activatedCallback (DbusmenuMenuitem* item, - int time, - gpointer data) +bool TestQuicklist::HasNthItemActivated(unsigned int index) { - gboolean* result = (gboolean*) data; + return activated_[quicklist_->GetNthItems(index)]; +} - *result = true; +void TestQuicklist::activatedCallback(DbusmenuMenuitem* item, int time, gpointer data) +{ + auto self = static_cast<TestQuicklist*>(data); + QuicklistMenuItem* qitem = self->menus2qitem_[item]; + + if (!self->activated_[qitem]) + { + self->activated_[qitem] = true; + g_debug("Quicklist-item %d activated", self->ItemNaturalPosition(qitem)); + } +} - g_print ("Quicklist-item activated\n"); +void TestQuicklist::connectToActivatedSignal(DbusmenuMenuitem* item) +{ + g_signal_connect (item, + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (&TestQuicklist::activatedCallback), + this); } -QuicklistMenuItemCheckmark* -createCheckmarkItem () +QuicklistMenuItemSeparator* TestQuicklist::createSeparatorItem() { DbusmenuMenuitem* item = NULL; - QuicklistMenuItemCheckmark* checkmark = NULL; + QuicklistMenuItemSeparator* separator = NULL; + + item = dbusmenu_menuitem_new (); + + dbusmenu_menuitem_property_set_bool (item, + DBUSMENU_MENUITEM_PROP_ENABLED, + true); + + separator = new QuicklistMenuItemSeparator (item, true); + menus2qitem_[item] = separator; + + return separator; +} + +QuicklistMenuItemRadio* TestQuicklist::createRadioItem(std::string const& label, bool enabled, bool checked) +{ + DbusmenuMenuitem* item = NULL; + QuicklistMenuItemRadio* radio = NULL; item = dbusmenu_menuitem_new (); dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, - "Unchecked"); + label.c_str()); dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, - DBUSMENU_MENUITEM_TOGGLE_CHECK); + DBUSMENU_MENUITEM_TOGGLE_RADIO); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, - true); + enabled); dbusmenu_menuitem_property_set_int (item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED); + (checked ? + DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : + DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED + )); - checkmark = new QuicklistMenuItemCheckmark (item, true); - - g_signal_connect (item, - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activatedCallback), - &gResult[0]); + connectToActivatedSignal(item); + radio = new QuicklistMenuItemRadio (item, true); + menus2qitem_[item] = radio; - return checkmark; + return radio; } -QuicklistMenuItemRadio* -createRadioItem () +QuicklistMenuItemCheckmark* TestQuicklist::createCheckmarkItem(std::string const& label, bool enabled, bool checked) { - DbusmenuMenuitem* item = NULL; - QuicklistMenuItemRadio* radio = NULL; + DbusmenuMenuitem* item = NULL; + QuicklistMenuItemCheckmark* checkmark = NULL; item = dbusmenu_menuitem_new (); dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, - "Radio Active"); + label.c_str()); dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, - DBUSMENU_MENUITEM_TOGGLE_RADIO); + DBUSMENU_MENUITEM_TOGGLE_CHECK); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, - false); + enabled); dbusmenu_menuitem_property_set_int (item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); + (checked ? + DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : + DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED + )); - radio = new QuicklistMenuItemRadio (item, true); + connectToActivatedSignal(item); - g_signal_connect (item, - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activatedCallback), - &gResult[1]); + checkmark = new QuicklistMenuItemCheckmark (item, true); + menus2qitem_[item] = checkmark; - return radio; + return checkmark; } -QuicklistMenuItemLabel* -createLabelItem () +QuicklistMenuItemLabel* TestQuicklist::createLabelItem(std::string const& title, bool enabled) { DbusmenuMenuitem* item = NULL; QuicklistMenuItemLabel* label = NULL; @@ -134,172 +208,144 @@ createLabelItem () dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, - "A Label"); + title.c_str()); dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, - true); + enabled); - label = new QuicklistMenuItemLabel (item, true); + connectToActivatedSignal(item); - g_signal_connect (item, - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activatedCallback), - &gResult[2]); + label = new QuicklistMenuItemLabel (item, true); + menus2qitem_[item] = label; return label; } -void -ThreadWidgetInit (nux::NThread* thread, - void* initData) +void TestQuicklist::AddItem(QuicklistMenuItem* item) { - gQuicklist = new QuicklistView (); - gQuicklist->Reference (); + if (!quicklist_) + return; - gCheckmark = createCheckmarkItem (); - gQuicklist->AddMenuItem (gCheckmark); - gRadio = createRadioItem (); - gQuicklist->AddMenuItem (gRadio); - gLabel = createLabelItem (); - gQuicklist->AddMenuItem (gLabel); + quicklist_->AddMenuItem(item); +} + +void TestQuicklist::UserInterfaceSetup() +{ + QuicklistMenuItem *item; - gQuicklist->EnableQuicklistForTesting (true); + quicklist_ = new QuicklistView(); + quicklist_->EnableQuicklistForTesting(true); + quicklist_->SetBaseXY(0, 0); - gQuicklist->SetBaseXY (0, 0); - gQuicklist->ShowWindow (true); + item = createLabelItem("Item1, normal"); + AddItem(item); + + item = createSeparatorItem(); + AddItem(item); + + item = createRadioItem("Item2, radio, checked", true, true); + AddItem(item); + + item = createRadioItem("Item3, radio, unchecked", true, false); + AddItem(item); + + item = createRadioItem("Item4, disabled radio, checked", false, true); + AddItem(item); + + item = createRadioItem("Item5, disabled radio, unchecked", false, false); + AddItem(item); + + item = createCheckmarkItem("Item6, checkmark, checked", true, true); + AddItem(item); + + item = createCheckmarkItem("Item7, checkmark, unchecked", true, false); + AddItem(item); + + item = createCheckmarkItem("Item8, disabled checkmark, checked", false, true); + AddItem(item); + + item = createCheckmarkItem("Item9, disabled checkmark, unchecked", false, false); + AddItem(item); + + item = createLabelItem("Item10, disabled", false); + AddItem(item); + + quicklist_->ShowWindow(true); + + auto wt = static_cast<nux::WindowThread*>(window_thread_); + nux::ColorLayer background (nux::Color (0x772953)); + wt->SetWindowBackgroundPaintLayer(&background); } -void -ControlThread (nux::NThread* thread, - void* data) +TestQuicklist *test_quicklist = NULL; + +void TestingThread(nux::NThread *thread, void *user_data) { - // sleep for 3 seconds - nux::SleepForMilliseconds (3000); - printf ("ControlThread successfully started\n"); - - nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, - data); - - mainWindowThread->SetFakeEventMode (true); - Display* display = mainWindowThread->GetWindow ().GetX11Display (); - - // assemble first button-click event - XEvent buttonPressEvent; - buttonPressEvent.xbutton.type = ButtonPress; - buttonPressEvent.xbutton.serial = 0; - buttonPressEvent.xbutton.send_event = False; - buttonPressEvent.xbutton.display = display; - buttonPressEvent.xbutton.window = 0; - buttonPressEvent.xbutton.root = 0; - buttonPressEvent.xbutton.subwindow = 0; - buttonPressEvent.xbutton.time = CurrentTime; - buttonPressEvent.xbutton.x = 50; - buttonPressEvent.xbutton.y = 30; - buttonPressEvent.xbutton.x_root = 0; - buttonPressEvent.xbutton.y_root = 0; - buttonPressEvent.xbutton.state = 0; - buttonPressEvent.xbutton.button = Button1; - buttonPressEvent.xbutton.same_screen = True; - - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonPressEvent); - - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - XEvent buttonReleaseEvent; - buttonReleaseEvent.xbutton.type = ButtonRelease; - buttonReleaseEvent.xbutton.serial = 0; - buttonReleaseEvent.xbutton.send_event = False; - buttonReleaseEvent.xbutton.display = display; - buttonReleaseEvent.xbutton.window = 0; - buttonReleaseEvent.xbutton.root = 0; - buttonReleaseEvent.xbutton.subwindow = 0; - buttonReleaseEvent.xbutton.time = CurrentTime; - buttonReleaseEvent.xbutton.x = 50; - buttonReleaseEvent.xbutton.y = 30; - buttonReleaseEvent.xbutton.x_root = 0; - buttonReleaseEvent.xbutton.y_root = 0; - buttonReleaseEvent.xbutton.state = 0; - buttonReleaseEvent.xbutton.button = Button1; - buttonReleaseEvent.xbutton.same_screen = True; - - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonReleaseEvent); - - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - // assemble second button-click event - buttonPressEvent.xbutton.time = CurrentTime; - buttonPressEvent.xbutton.x = 50; - buttonPressEvent.xbutton.y = 50; - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonPressEvent); - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - buttonReleaseEvent.xbutton.time = CurrentTime; - buttonReleaseEvent.xbutton.x = 50; - buttonReleaseEvent.xbutton.y = 50; - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonReleaseEvent); - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - // assemble third button-click event - buttonPressEvent.xbutton.time = CurrentTime; - buttonPressEvent.xbutton.x = 50; - buttonPressEvent.xbutton.y = 70; - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonPressEvent); - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - buttonReleaseEvent.xbutton.time = CurrentTime; - buttonReleaseEvent.xbutton.x = 50; - buttonReleaseEvent.xbutton.y = 70; - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonReleaseEvent); - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - mainWindowThread->SetFakeEventMode (false); + while (test_quicklist->ReadyToGo() == false) + { + nuxDebugMsg("Waiting to start"); + nux::SleepForMilliseconds(300); + } + + nux::SleepForMilliseconds(1300); + + auto *wnd_thread = static_cast<nux::WindowThread*>(user_data); + + NuxAutomatedTestFramework test(wnd_thread); + + test.Startup(); + + for (auto child : test_quicklist->quicklist_->GetChildren()) + { + test.ViewSendMouseMotionToCenter(child); + test.ViewSendMouseClick(child, 1); + bool activated = test_quicklist->activated_[child]; + bool should_be_activated = (child->GetItemType() != MENUITEM_TYPE_SEPARATOR && child->GetEnabled()); + + std::string msg = std::string(child->GetLabel()); + msg += should_be_activated ? " | Activated" : " | NOT Activated"; + + test.TestReportMsg(activated == should_be_activated, msg.c_str()); + nux::SleepForMilliseconds(200); + } + + if (test.WhenDoneTerminateProgram()) + { + wnd_thread->ExitMainLoop(); + } + nuxDebugMsg("Exit testing thread"); } int main (int argc, char **argv) { - nux::WindowThread* wt = NULL; - nux::SystemThread* st = NULL; - - g_type_init (); - - gtk_init (&argc, &argv); - dbus_g_thread_init (); - nux::NuxInitialize (0); - - wt = nux::CreateGUIThread (TEXT ("Unity Quicklist"), - WIN_WIDTH, - WIN_HEIGHT, - 0, - &ThreadWidgetInit, - NULL); - - st = nux::CreateSystemThread (NULL, ControlThread, wt); - if (st) - st->Start (NULL); - - wt->Run (NULL); - - gQuicklist->UnReference (); - delete st; - delete wt; - - g_assert_cmpint (gResult[0], ==, true); - g_assert_cmpint (gResult[1], ==, true); - g_assert_cmpint (gResult[2], ==, true); + gtk_init(&argc, &argv); + nuxAssertMsg(XInitThreads() > 0, "XInitThreads has failed"); + + test_quicklist = new TestQuicklist("Quicklist Test", WIN_WIDTH, WIN_HEIGHT, 100000); + test_quicklist->Startup(); + test_quicklist->UserInterfaceSetup(); + + auto *test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_quicklist->GetWindowThread()); + test_thread->Start(test_quicklist); + + test_quicklist->Run(); + + g_assert_cmpint (test_quicklist->HasNthItemActivated(0), ==, true); + g_assert_cmpint (test_quicklist->HasNthItemActivated(1), ==, false); + g_assert_cmpint (test_quicklist->HasNthItemActivated(2), ==, true); + g_assert_cmpint (test_quicklist->HasNthItemActivated(3), ==, true); + g_assert_cmpint (test_quicklist->HasNthItemActivated(4), ==, false); + g_assert_cmpint (test_quicklist->HasNthItemActivated(5), ==, false); + g_assert_cmpint (test_quicklist->HasNthItemActivated(6), ==, true); + g_assert_cmpint (test_quicklist->HasNthItemActivated(7), ==, true); + g_assert_cmpint (test_quicklist->HasNthItemActivated(8), ==, false); + g_assert_cmpint (test_quicklist->HasNthItemActivated(9), ==, false); + g_assert_cmpint (test_quicklist->HasNthItemActivated(10), ==, false); + + delete test_thread; + delete test_quicklist; return 0; } diff --git a/standalone-clients/ui/TestQuicklistVisuals.cpp b/standalone-clients/ui/TestQuicklistVisuals.cpp index 03ff93672..107412668 100644 --- a/standalone-clients/ui/TestQuicklistVisuals.cpp +++ b/standalone-clients/ui/TestQuicklistVisuals.cpp @@ -18,7 +18,6 @@ #include <glib.h> #include <gtk/gtk.h> -#include <dbus/dbus-glib.h> #include "Nux/Nux.h" #include "Nux/VLayout.h" @@ -60,14 +59,12 @@ createRadioItem (const gchar* label, DBUSMENU_MENUITEM_PROP_ENABLED, enabled); - if (checked) - dbusmenu_menuitem_property_set_int (item, - DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); - else - dbusmenu_menuitem_property_set_int (item, - DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED); + dbusmenu_menuitem_property_set_int (item, + DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, + (checked ? + DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : + DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED + )); radio = new QuicklistMenuItemRadio (item, true); @@ -96,14 +93,12 @@ createCheckmarkItem (const gchar* label, DBUSMENU_MENUITEM_PROP_ENABLED, enabled); - if (checked) - dbusmenu_menuitem_property_set_int (item, - DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); - else - dbusmenu_menuitem_property_set_int (item, - DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, - DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED); + dbusmenu_menuitem_property_set_int (item, + DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, + (checked ? + DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : + DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED + )); checkmark = new QuicklistMenuItemCheckmark (item, true); @@ -111,7 +106,7 @@ createCheckmarkItem (const gchar* label, } QuicklistMenuItemLabel* -createLabelItem (const gchar* string) +createLabelItem (const gchar* string, bool enabled = true) { DbusmenuMenuitem* item = NULL; QuicklistMenuItemLabel* label = NULL; @@ -124,7 +119,7 @@ createLabelItem (const gchar* string) dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, - true); + enabled); label = new QuicklistMenuItemLabel (item, true); @@ -170,7 +165,8 @@ ThreadWidgetInit (nux::NThread* thread, gQuicklists[0]->AddMenuItem (radio); separator = createSeparatorItem (); gQuicklists[0]->AddMenuItem (separator); - label = createLabelItem ("Application Name"); + label = createLabelItem ("<b>Application Name</b>"); + label->EnableLabelMarkup(true); gQuicklists[0]->AddMenuItem (label); separator = createSeparatorItem (); gQuicklists[0]->AddMenuItem (separator); @@ -193,7 +189,8 @@ ThreadWidgetInit (nux::NThread* thread, gQuicklists[1]->AddMenuItem (checkmark); separator = createSeparatorItem (); gQuicklists[1]->AddMenuItem (separator); - label = createLabelItem ("Application Name"); + label = createLabelItem ("<b>Application Name</b>"); + label->EnableLabelMarkup(true); gQuicklists[1]->AddMenuItem (label); separator = createSeparatorItem (); gQuicklists[1]->AddMenuItem (separator); @@ -214,11 +211,12 @@ ThreadWidgetInit (nux::NThread* thread, gQuicklists[2]->AddMenuItem (separator); checkmark = createCheckmarkItem ("Option 03", false, true); gQuicklists[2]->AddMenuItem (checkmark); - checkmark = createCheckmarkItem ("Option 04", false, true); - gQuicklists[2]->AddMenuItem (checkmark); + label = createLabelItem ("Option 04", false); + gQuicklists[2]->AddMenuItem (label); separator = createSeparatorItem (); gQuicklists[2]->AddMenuItem (separator); - label = createLabelItem ("Application Name"); + label = createLabelItem ("<b>Application Name</b>"); + label->EnableLabelMarkup(true); gQuicklists[2]->AddMenuItem (label); separator = createSeparatorItem (); gQuicklists[2]->AddMenuItem (separator); @@ -227,6 +225,9 @@ ThreadWidgetInit (nux::NThread* thread, gQuicklists[2]->EnableQuicklistForTesting (true); gQuicklists[2]->SetBaseXY (45, 290); gQuicklists[2]->ShowWindow (true); + + nux::ColorLayer background (nux::Color (0x772953)); + static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background); } int @@ -234,10 +235,7 @@ main (int argc, char **argv) { nux::WindowThread* wt = NULL; - g_type_init (); - gtk_init (&argc, &argv); - dbus_g_thread_init (); nux::NuxInitialize (0); wt = nux::CreateGUIThread (TEXT ("Unity visual Quicklist-test"), diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c7e2bd3f9..1759638f2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -99,6 +99,8 @@ if (GTEST_FOUND AND # The service that provides DBus services to test against add_executable(test-gtest-service + test_service_hud.c + test_service_hud.h test_service_lens.c test_service_lens.h test_service_main.c @@ -139,6 +141,8 @@ if (GTEST_FOUND AND ${UNITY_SRC}/FavoriteStore.h ${UNITY_SRC}/FavoriteStoreGSettings.cpp ${UNITY_SRC}/FavoriteStoreGSettings.h + ${UNITY_SRC}/IconTextureSource.h + ${UNITY_SRC}/IconTextureSource.cpp ${UNITY_SRC}/LauncherModel.cpp ${UNITY_SRC}/LauncherModel.h ${UNITY_SRC}/FavoriteStorePrivate.cpp @@ -181,7 +185,8 @@ if (GTEST_FOUND AND test_utils.h test_ratings_filter.cpp test_results.cpp - ) + test_hud.cpp + ) target_link_libraries(test-gtest-dbus ${GTEST_BOTH_LIBRARIES}) add_test(UnityGTestDBus test-gtest-dbus) add_dependencies(test-gtest-dbus unity-core-${UNITY_API_VERSION} test-gtest-service) diff --git a/tests/autopilot/autopilot/emulators/unity.py b/tests/autopilot/autopilot/emulators/unity.py index c85329e27..ba0a5ec20 100644 --- a/tests/autopilot/autopilot/emulators/unity.py +++ b/tests/autopilot/autopilot/emulators/unity.py @@ -81,7 +81,7 @@ class SimpleLauncherIcon(Unity): self.x = state_from_unity['x'] self.z = state_from_unity['z'] self.id = state_from_unity['id'] - self.tooltip_text = state_from_unity['tooltip-text'] + self.tooltip_text = unicode(state_from_unity['tooltip-text']) def get_quicklist(self): """Get the quicklist for this launcher icon. @@ -137,6 +137,7 @@ def make_launcher_icon(dbus_tuple): class_type = _icon_type_registry[name] return class_type(state) except KeyError: + import pdb; pdb.set_trace() print name, "is not a valid icon type!" return None diff --git a/tests/test_hud.cpp b/tests/test_hud.cpp new file mode 100644 index 000000000..36f2c876b --- /dev/null +++ b/tests/test_hud.cpp @@ -0,0 +1,104 @@ +#include <gtest/gtest.h> +#include <glib-object.h> +#include <UnityCore/GLibWrapper.h> +#include <UnityCore/Hud.h> + +using namespace std; + +namespace +{ + +GMainLoop* loop_ = NULL; +unity::hud::Hud *hud; + +class TestHud : public ::testing::Test +{ +public: + TestHud() + : query_return_result(false) + , connected_result(false) + { + } + unity::hud::Hud::Queries queries; + bool query_return_result; + bool connected_result; +}; + +TEST_F(TestHud, TestConstruction) +{ + loop_ = g_main_loop_new(NULL, FALSE); + hud = new unity::hud::Hud("com.canonical.Unity.Test", "/com/canonical/hud"); + + // performs a check on the hud, if the hud is connected, report a sucess + auto timeout_check = [] (gpointer data) -> gboolean + { + TestHud* self = static_cast<TestHud*>(data); + if (hud->connected) + { + self->connected_result = true; + g_main_loop_quit(loop_); + return FALSE; + } + else + { + self->connected_result = false; + return TRUE; + } + }; + + + // if the hud is not connected when this lambda runs, fail. + auto timeout_bailout = [] (gpointer data) -> gboolean + { + TestHud* self = static_cast<TestHud*>(data); + // reached timeout, failed testing + self->connected_result = false; + g_main_loop_quit(loop_); + return FALSE; + }; + + g_timeout_add_seconds(1, timeout_check, this); + g_timeout_add_seconds(10, timeout_bailout, this); + + g_main_loop_run(loop_); + + EXPECT_EQ(connected_result, true); +} + +TEST_F(TestHud, TestQueryReturn) +{ + query_return_result = false; + + // make sure we receive the queries + auto query_connection = [this](unity::hud::Hud::Queries queries_) + { + query_return_result = true; + g_main_loop_quit(loop_); + queries = queries_; + }; + + auto timeout_bailout = [] (gpointer data) -> gboolean + { + TestHud* self = static_cast<TestHud*>(data); + self->query_return_result = false; + g_main_loop_quit(loop_); + return FALSE; + }; + + hud->queries_updated.connect(query_connection); + + guint source_id = g_timeout_add_seconds(10, timeout_bailout, this); + + // next check we get 30 entries from this specific known callback + hud->RequestQuery("Request30Queries"); + g_main_loop_run(loop_); + EXPECT_EQ(query_return_result, true); + EXPECT_NE(queries.size(), 0); + g_source_remove(source_id); + + // finally close the connection - Nothing to check for here + hud->CloseQuery(); +} + + +} diff --git a/tests/test_service_hud.c b/tests/test_service_hud.c new file mode 100644 index 000000000..bfdf47ce1 --- /dev/null +++ b/tests/test_service_hud.c @@ -0,0 +1,268 @@ +#include "test_service_hud.h" +#include <unity.h> +#include <gio/gio.h> + +const char * hud_interface = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<node name=\"/\">\n" +" <interface name=\"com.canonical.hud\">\n" +"<!-- Properties -->\n" +" <!-- None -->\n" +"\n" +"<!-- Functions -->\n" +" <method name=\"StartQuery\">\n" +" <!-- in -->\n" +" <arg type=\"s\" name=\"query\" direction=\"in\" />\n" +" <arg type=\"i\" name=\"entries\" direction=\"in\" />\n" +" <!-- out -->\n" +" <arg type=\"s\" name=\"target\" direction=\"out\" />\n" +" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n" +" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n" +" </method>\n" +"\n" +" <method name=\"ExecuteQuery\">\n" +" <arg type=\"v\" name=\"key\" direction=\"in\" />\n" +" <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n" +" </method>\n" +"\n" +" <method name=\"CloseQuery\">\n" +" <arg type=\"v\" name=\"querykey\" direction=\"in\" />\n" +" </method>\n" +"\n" +"<!-- Signals -->\n" +" <signal name=\"UpdatedQuery\">\n" +" <arg type=\"s\" name=\"target\" direction=\"out\" />\n" +" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n" +" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n" +" </signal>\n" +"\n" +"<!-- End of interesting stuff -->\n" +"\n" +" </interface>\n" +"</node>\n" +; +static void bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data); +static void bus_method (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data); + +G_DEFINE_TYPE(ServiceHud, service_hud, G_TYPE_OBJECT); +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * iface_info = NULL; +static GDBusInterfaceVTable bus_vtable = { + method_call: bus_method, + get_property: NULL, + set_property: NULL, +}; + + +struct _ServiceHudPrivate +{ + GDBusConnection * bus; + GCancellable * bus_lookup; + guint bus_registration; +}; + +static void +service_hud_dispose(GObject* object) +{ + ServiceHud* self = SERVICE_HUD(object); + if (self->priv->bus_lookup != NULL) { + g_cancellable_cancel(self->priv->bus_lookup); + g_object_unref(self->priv->bus_lookup); + self->priv->bus_lookup = NULL; + } + + if (self->priv->bus_registration != 0) { + g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration); + self->priv->bus_registration = 0; + } + + if (self->priv->bus != NULL) { + g_object_unref(self->priv->bus); + self->priv->bus = NULL; + } + +} + +static void +service_hud_class_init(ServiceHudClass* klass) +{ + G_OBJECT_CLASS(klass)->dispose = service_hud_dispose; + g_type_class_add_private (klass, sizeof (ServiceHudPrivate)); + + if (node_info == NULL) + { + GError * error = NULL; + + node_info = g_dbus_node_info_new_for_xml(hud_interface, &error); + if (error != NULL) + { + g_error("Unable to parse HUD interface: %s", error->message); + g_error_free(error); + } + } + + if (node_info != NULL && iface_info == NULL) + { + iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.hud"); + if (iface_info == NULL) + { + g_error("Unable to find interface 'com.canonical.hud'"); + } + } + +} + +static void +service_hud_init(ServiceHud* self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_HUD, ServiceHudPrivate); + self->priv->bus = NULL; + self->priv->bus_lookup = NULL; + self->priv->bus_registration = 0; + + self->priv->bus_lookup = g_cancellable_new(); + g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self); + +} + +ServiceHud* +service_hud_new() +{ + return g_object_new(SERVICE_TYPE_HUD, NULL); +} + +static void +bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + ServiceHud * self = SERVICE_HUD(user_data); + GDBusConnection * bus; + + bus = g_bus_get_finish(res, &error); + if (error != NULL) { + g_critical("Unable to get bus: %s", error->message); + g_error_free(error); + return; + } + + self->priv->bus = bus; + + /* Register object */ + self->priv->bus_registration = g_dbus_connection_register_object(bus, + /* path */ "/com/canonical/hud", + /* interface */ iface_info, + /* vtable */ &bus_vtable, + /* userdata */ self, + /* destroy */ NULL, + /* error */ &error); + + if (error != NULL) { + g_critical ("Unable to create bus connection object, %s", error->message); + g_error_free(error); + return; + } + + return; +} + +static void +bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) +{ + if (g_strcmp0(method_name, "StartQuery") == 0) + { + GVariant * ret = NULL; + gchar * query = NULL; + int num_entries = 0; + + g_variant_get(parameters, "(si)", &query, &num_entries); + + /* Build into into a variant */ + GVariantBuilder ret_builder; + g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&ret_builder, g_variant_new_string("target")); + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + + int i = 0; + for (i = 0; i < num_entries; i++) + { + gchar* target = g_strdup_printf("test-%i", i); + gchar* icon = g_strdup_printf("icon-%i", i); + gchar* future_icon = g_strdup(icon); + gchar* completion_text = g_strdup_printf("completion-%i", i); + gchar* accelerator = g_strdup_printf("<alt>+whatever"); + + GVariantBuilder tuple; + g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&tuple, g_variant_new_string(target)); + g_variant_builder_add_value(&tuple, g_variant_new_string(icon)); + g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon)); + g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text)); + g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator)); + // build a fake key + GVariant* key; + { + GVariantBuilder keybuilder; + g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986)); + + key = g_variant_new_variant(g_variant_builder_end(&keybuilder)); + } + g_variant_ref_sink(key); + g_variant_builder_add_value(&tuple, key); + g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple)); + g_free(target); + g_free(icon); + g_free(future_icon); + g_free(completion_text); + } + g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder)); + + GVariant* query_key; + { + GVariantBuilder keybuilder; + g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string")); + g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986)); + + query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder)); + } + g_variant_ref_sink(query_key); + g_variant_builder_add_value(&ret_builder, query_key); + + ret = g_variant_builder_end(&ret_builder); + + g_dbus_method_invocation_return_value(invocation, ret); + g_free(query); + } + else if (g_strcmp0(method_name, "ExecuteQuery") == 0) + { + GVariant * key = NULL; + key = g_variant_get_child_value(parameters, 0); + g_dbus_method_invocation_return_value(invocation, NULL); + g_variant_unref(key); + } + else if (g_strcmp0(method_name, "CloseQuery") == 0) + { + GVariant * key = NULL; + key = g_variant_get_child_value(parameters, 0); + g_dbus_method_invocation_return_value(invocation, NULL); + g_variant_unref(key); + } + + return; +} + diff --git a/tests/test_service_hud.h b/tests/test_service_hud.h new file mode 100644 index 000000000..df069962a --- /dev/null +++ b/tests/test_service_hud.h @@ -0,0 +1,46 @@ +#ifndef _SERVICE_HUD_H_ +#define _SERVICE_HUD_H_ + +#include <glib-object.h> +G_BEGIN_DECLS + +#define SERVICE_TYPE_HUD (service_hud_get_type ()) + +#define SERVICE_HUD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\ + SERVICE_TYPE_HUD, ServiceHud)) + +#define SERVICE_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\ + SERVICE_TYPE_HUD, ServiceHudClass)) + +#define SERVICE_IS_HUD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\ + SERVICE_TYPE_HUD)) + +#define SERVICE_IS_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\ + SERVICE_TYPE_HUD)) + +#define ServiceHud_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\ + SERVICE_TYPE_HUD, ServiceHudClass)) + +typedef struct _ServiceHud ServiceHud; +typedef struct _ServiceHudClass ServiceHudClass; +typedef struct _ServiceHudPrivate ServiceHudPrivate; + +struct _ServiceHud +{ + GObject parent; + + ServiceHudPrivate *priv; +}; + +struct _ServiceHudClass +{ + GObjectClass parent_class; +}; + +GType service_hud_get_type(void) G_GNUC_CONST; + +ServiceHud* service_hud_new(void); + +G_END_DECLS + +#endif /* _SERVICE_HUD_H_ */ diff --git a/tests/test_service_main.c b/tests/test_service_main.c index 7e2bdc15c..e03bef41c 100644 --- a/tests/test_service_main.c +++ b/tests/test_service_main.c @@ -2,6 +2,7 @@ #include "test_service_lens.h" #include "test_service_model.h" +#include "test_service_hud.h" static void on_bus_aquired(GDBusConnection* conn, const gchar* name, gpointer null); static void handle_method_call(GDBusConnection *connection, @@ -34,6 +35,7 @@ static const GDBusInterfaceVTable interface_vtable = static GMainLoop* loop_ = NULL; static ServiceLens* lens_ = NULL; static ServiceModel* model_ = NULL; +static ServiceHud* hud_ = NULL; gint main(gint argc, gchar** argv) @@ -44,6 +46,7 @@ main(gint argc, gchar** argv) lens_ = service_lens_new(); model_ = service_model_new(); + hud_ = service_hud_new(); g_bus_own_name(G_BUS_TYPE_SESSION, "com.canonical.Unity.Test", @@ -57,8 +60,9 @@ main(gint argc, gchar** argv) g_main_loop_run(loop_); g_main_loop_unref(loop_); - g_object_unref(lens_); - g_object_unref(model_); + //g_object_unref(lens_); + //g_object_unref(model_); + g_object_unref(hud_); g_dbus_node_info_unref(introspection_data); return 0; diff --git a/tests/unit/TestQuicklistMenuitems.cpp b/tests/unit/TestQuicklistMenuitems.cpp index 823715f8e..716e0dc03 100644 --- a/tests/unit/TestQuicklistMenuitems.cpp +++ b/tests/unit/TestQuicklistMenuitems.cpp @@ -241,6 +241,7 @@ TestQuicklistMenuItem() g_assert_cmpstr(quicklist->GetNthItems(2)->GetLabel(), == , "label 1"); g_assert_cmpstr(quicklist->GetNthItems(3)->GetLabel(), == , "check mark 0"); + g_assert_cmpint(quicklist->GetChildren().size(), == , 4); quicklist->Dispose(); } diff --git a/tools/unity-introspection-visualiser.py b/tools/unity-introspection-visualiser.py index fae236e2c..bdefe0b51 100755 --- a/tools/unity-introspection-visualiser.py +++ b/tools/unity-introspection-visualiser.py @@ -2,7 +2,9 @@ # # Script to generate a nice PNG file of the currently running unity introspection tree. -from sys import argv +from argparse import ArgumentParser +from os import remove +from os.path import splitext import dbus try: @@ -21,6 +23,7 @@ except ImportError: NEXT_NODE_ID=1 + def string_rep(dbus_type): """Get a string representation of various dbus types.""" if type(dbus_type) == dbus.Boolean: @@ -60,16 +63,17 @@ def traverse_tree(state, parent, graph): graph.add_edge(pydot.Edge(parent, child)) traverse_tree(child_state, child, graph) - + if __name__ == '__main__': - if len(argv) != 2: - print """Usage: %s output_file.png. + parser = ArgumentParser() + mg = parser.add_mutually_exclusive_group(required=True) + mg.add_argument('-o', '--output', nargs=1, + help='Store output in specified file on disk.') + mg.add_argument('-d','--display', action='store_true', + help='Display output in image viewer.') -This script queries the currently running Unity process and dumps the entire -introspection tree into a graph, and renders this to a PNG file. -""" % (argv[0]) - exit(1) + args = parser.parse_args() u = Unity() introspection_tree = u.get_state() @@ -78,10 +82,27 @@ introspection tree into a graph, and renders this to a PNG file. graph.set_node_defaults(shape='Mrecord') graph.set_fontname('Ubuntu') graph.set_fontsize('10') - + gnode_unity = pydot.Node("Unity") gnode_unity.set_comment("Unity") traverse_tree(introspection_tree[0], gnode_unity, graph) - graph.write(argv[1], format='png') + if args.output: + base, extension = splitext(args.output[0]) + write_method_name = 'write_' + extension[1:] + if hasattr(graph, write_method_name): + getattr(graph, write_method_name)(args.output[0]) + else: + print "Error: unsupported format: '%s'" % (extension) + elif args.display: + from tempfile import NamedTemporaryFile + from subprocess import call + tf = NamedTemporaryFile(suffix='.png', delete=False) + tf.write(graph.create_png()) + tf.close() + call(["eog", tf.name]) + remove(tf.name) + else: + print 'unknown output mode!' + |
