diff -u unity-5.12/plugins/unityshell/src/Launcher.cpp unity-5.12/plugins/unityshell/src/Launcher.cpp --- unity-5.12/plugins/unityshell/src/Launcher.cpp +++ unity-5.12/plugins/unityshell/src/Launcher.cpp @@ -1350,7 +1350,7 @@ gint32 overlay_monitor = 0; g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor); - std::string identity = overlay_identity.Str(); + std::string identity(overlay_identity.Str()); LOG_DEBUG(logger) << "Overlay shown: " << identity << ", " << (can_maximise ? "can maximise" : "can't maximise") @@ -1376,6 +1376,9 @@ LOG_DEBUG(logger) << "Desaturate on monitor " << monitor(); DesaturateIcons(); } + + if (_icon_under_mouse) + _icon_under_mouse->HideTooltip(); } EnsureAnimation(); } diff -u unity-5.12/debian/control unity-5.12/debian/control --- unity-5.12/debian/control +++ unity-5.12/debian/control @@ -42,7 +42,7 @@ libxfixes-dev (>= 1:5.0-4ubuntu4), Standards-Version: 3.9.3 Homepage: https://launchpad.net/unity -Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/unity/ubuntu +Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/unity/precise Package: unity Architecture: any diff -u unity-5.12/debian/changelog unity-5.12/debian/changelog --- unity-5.12/debian/changelog +++ unity-5.12/debian/changelog @@ -1,3 +1,20 @@ +unity (5.12-0ubuntu1.1) precise-proposed; urgency=low + + * Cherry pick upstream fixes. + - Fix UnityViewWindow background when blur is disabled (LP: #989291) + - App icon on the Unity Launcher lost track of running + instance (LP: #772063) + - No launcher icon or Alt+Tab entry for Gimp windows (LP: #995916) + - Locked smuxi launcher icon does not indicate smuxi running + status (LP: #999820) + - Fix dash search field hidden by tooltips (LP: #978030) + - Launcher is silent to screen reader users (LP: #949448) + - Fix 3D apps running much slower under Unity (LP: #987304) + - Reduced number of calls to ResultViewGrid::QueueDraw + - Reduced number of calls to BGHash::RefreshColor + + -- Alan Pope Wed, 23 May 2012 18:10:49 +0100 + unity (5.12-0ubuntu1) precise-proposed; urgency=low * New upstream release. only in patch2: unchanged: --- unity-5.12.orig/manual-tests/ShortcutsOverlay.txt +++ unity-5.12/manual-tests/ShortcutsOverlay.txt @@ -12,3 +12,4 @@ Outcome: The keyboard shortcuts overlay bottom is not truncated. + only in patch2: unchanged: --- unity-5.12.orig/tests/test_resultviewgrid.cpp +++ unity-5.12/tests/test_resultviewgrid.cpp @@ -0,0 +1,103 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2012 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 + * + * + * Authored by: Andrea Azzarone + * + */ + +#include +#include +using namespace testing; + +#include "ResultViewGrid.h" +using namespace unity; + +namespace +{ + +class MockResultViewGrid : public dash::ResultViewGrid +{ +public: + MockResultViewGrid(NUX_FILE_LINE_DECL) : dash::ResultViewGrid(NUX_FILE_LINE_PARAM) {} + + MOCK_METHOD0(QueueDraw, void()); + MOCK_METHOD2(GetIndexAtPosition, uint(int x, int y)); + + void FakeMouseMoveSignal(int x = 0, int y = 0, int dx = 0, int dy = 0, unsigned long mouse_button_state = 0, unsigned long special_keys_state = 0) + { + EmitMouseMoveSignal(x, y, dy, dy, mouse_button_state, special_keys_state); + } +}; + +class TestResultViewGrid : public Test +{ +public: + virtual void SetUp() + { + view.Adopt(new MockResultViewGrid(NUX_TRACKER_LOCATION)); + renderer.Adopt(new dash::ResultRenderer(NUX_TRACKER_LOCATION)); + + view->SetModelRenderer(renderer.GetPointer()); + nux::GetWindowCompositor().SetKeyFocusArea(view.GetPointer()); + } + + nux::ObjectPtr view; + nux::ObjectPtr renderer; +}; + + +TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveInsideUnfocusedIcon) +{ + EXPECT_CALL(*view, QueueDraw()) + .Times(1); + + EXPECT_CALL(*view, GetIndexAtPosition(_, _)) + .WillOnce(Return(7)); + + view->FakeMouseMoveSignal(); +} + + +TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveInsideFocusedIcon) +{ + EXPECT_CALL(*view, GetIndexAtPosition(_, _)) + .WillRepeatedly(Return(7)); + + view->FakeMouseMoveSignal(); + + EXPECT_CALL(*view, QueueDraw()) + .Times(0); + + view->FakeMouseMoveSignal(); +} + + +TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveOutside) +{ + EXPECT_CALL(*view, GetIndexAtPosition(_, _)) + .WillRepeatedly(Return(-1)); + + view->FakeMouseMoveSignal(); + + EXPECT_CALL(*view, QueueDraw()) + .Times(0); + + view->FakeMouseMoveSignal(); +} + +} only in patch2: unchanged: --- unity-5.12.orig/tests/CMakeLists.txt +++ unity-5.12/tests/CMakeLists.txt @@ -199,6 +199,7 @@ test_main.cpp test_lensview_impl.cpp test_icon_loader.cpp + test_resultviewgrid.cpp test_single_monitor_launcher_icon.cpp test_switcher_controller.cpp test_switcher_model.cpp @@ -249,10 +250,14 @@ ${UNITY_SRC}/ubus-server.cpp ${UNITY_SRC}/UScreen.cpp ${UNITY_SRC}/WindowManager.cpp + ${UNITY_SRC}/ResultView.cpp + ${UNITY_SRC}/ResultViewGrid.cpp + ${UNITY_SRC}/ResultRenderer.cpp + ${UNITY_SRC}/IntrospectableWrappers.cpp ) - target_link_libraries(test-gtest gtest ${LIBS}) + target_link_libraries(test-gtest gtest gmock ${LIBS}) add_test(UnityGTest test-gtest) - add_dependencies(test-gtest unity-core-${UNITY_API_VERSION} gtest) + add_dependencies(test-gtest unity-core-${UNITY_API_VERSION} gtest gmock) endif (GTEST_SRC_DIR AND GMOCK_LIB AND only in patch2: unchanged: --- unity-5.12.orig/tests/test_main.cpp +++ unity-5.12/tests/test_main.cpp @@ -9,6 +9,7 @@ g_type_init(); nux::NuxInitialize (0); + nux::WindowThread* wnd_thread = nux::CreateNuxWindow("Tests", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL); // Slightly higher as we're more likely to test things we know will fail nux::logging::configure_logging("=error"); @@ -18,6 +19,8 @@ int ret = RUN_ALL_TESTS(); + delete wnd_thread; + return ret; } only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/tests/test_shortcut_hint.py +++ unity-5.12/tests/autopilot/autopilot/tests/test_shortcut_hint.py @@ -85,6 +85,12 @@ self.shortcut_hint.cancel() self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False))) + def test_shortcut_hint_no_blur(self): + """""" + self.shortcut_hint.ensure_visible() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.assertThat(self.shortcut_hint.get_shortcut_view().bg_texture_is_valid, Eventually(Equals(True))) class ShortcutHintInteractionsTests(BaseShortcutHintTests): """Test the shortcuthint interactions with other Unity parts.""" only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/tests/test_launcher.py +++ unity-5.12/tests/autopilot/autopilot/tests/test_launcher.py @@ -417,7 +417,6 @@ sleep(1) [mah_win2] = [w for w in mahj.get_windows() if w.x_id != mah_win1.x_id] self.assertTrue(mah_win2.is_focused) - self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1]) mahj_icon = self.launcher.model.get_icon_by_desktop_id(mahj.desktop_file) @@ -446,6 +445,20 @@ self.assertTrue(mah_win2.is_hidden) self.assertVisibleWindowStack([mah_win1, calc_win]) + def test_icon_shows_on_quick_application_reopen(self): + """Icons should stay on launcher when an application is quickly closed/reopened.""" + calc = self.start_app("Calculator") + desktop_file = calc.desktop_file + calc_icon = self.launcher.model.get_icon_by_desktop_id(desktop_file) + self.assertThat(calc_icon.visible, Eventually(Equals(True))) + + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + sleep(2) + + calc_icon = self.launcher.model.get_icon_by_desktop_id(desktop_file) + self.assertThat(calc_icon, NotEquals(None)) + self.assertThat(calc_icon.visible, Eventually(Equals(True))) class LauncherRevealTests(LauncherTestCase): """Test the launcher reveal behavior when in autohide mode.""" @@ -579,6 +592,15 @@ self.start_app("Calculator") self.start_app("System Settings") + def start_desktopless_test_apps(self): + """Start test applications with no .desktop file associated.""" + test_apps = ["xclock"] + + for app in test_apps: + os.spawnlp(os.P_NOWAIT, app, app) + self.addCleanup(call, ["killall", app]) + self.wait_for_process_started(app) + def get_test_apps(self): """Return a tuple of test application instances. @@ -588,35 +610,75 @@ """ [calc] = self.get_app_instances("Calculator") [sys_settings] = self.get_app_instances("System Settings") - return (calc, sys_settings) + return [calc, sys_settings] + + def get_desktopless_test_apps(self): + """Return a tuple of test application with no .desktop files instances.""" + [xclock_win] = [w for w in self.bamf.get_open_windows() if w.name == "xclock"] + return [xclock_win.application] def assertOnlyOneLauncherIcon(self, **kwargs): """Asserts that there is only one launcher icon with the given filter.""" icons = self.launcher.model.get_icons_by_filter(**kwargs) self.assertThat(len(icons), Equals(1)) - def wait_for_bamf_daemon(self): - """Wait until the bamf daemon has been started.""" + def wait_for_process_started(self, app): + """Wait until the application app has been started.""" for i in range(10): + sleep(1) #pgrep returns 0 if it matched something: - if call(["pgrep", "bamfdaemon"]) == 0: + if call(["pgrep", app]) == 0: return - sleep(1) - def test_killing_bamfdaemon_does_not_duplicate_desktop_ids(self): - """Killing bamfdaemon should not duplicate any desktop ids in the model.""" - self.start_test_apps() + def wait_for_process_killed(self, app): + """Wait until the application app has been killed.""" + for i in range(10): + #pgrep returns 0 if it matched something: + if call(["pgrep", app]) != 0: + return + sleep(1) + def kill_and_restart_bamfdaemon(self): + """Kills and resumes bamfdaemon.""" call(["pkill", "bamfdaemon"]) - sleep(1) + self.wait_for_process_killed("bamfdaemon") # trigger the bamfdaemon to be reloaded again, and wait for it to appear: self.bamf = Bamf() - self.wait_for_bamf_daemon() + self.wait_for_process_started("bamfdaemon") + + def test_killing_bamfdaemon_does_not_duplicate_desktop_ids(self): + """Killing bamfdaemon should not duplicate any desktop ids in the model.""" + self.start_test_apps() + self.kill_and_restart_bamfdaemon() for test_app in self.get_test_apps(): + logger.info("Checking for duplicated launcher icon for application %s", test_app.name) self.assertOnlyOneLauncherIcon(desktop_id=test_app.desktop_file) + def test_killing_bamfdaemon_does_not_duplicate_application_xids(self): + """Killing bamfdaemon should not duplicate any xid in the model.""" + self.start_test_apps() + self.start_desktopless_test_apps() + self.kill_and_restart_bamfdaemon() + + test_apps = self.get_test_apps() + self.get_desktopless_test_apps() + + for test_app in test_apps: + logger.info("Checking for duplicated launcher icon for application %s", test_app.name) + test_windows = [w.x_id for w in test_app.get_windows()] + self.assertOnlyOneLauncherIcon(xids=test_windows) + + def test_killing_bamfdaemon_does_not_duplicate_any_icon_application_id(self): + """Killing bamfdaemon should not duplicate any application ids in the model.""" + self.start_test_apps() + self.start_desktopless_test_apps() + self.kill_and_restart_bamfdaemon() + + for icon in self.launcher.model.get_bamf_launcher_icons(): + logger.info("Checking for duplicated launcher icon %s", icon.tooltip_text) + self.assertOnlyOneLauncherIcon(application_id=icon.application_id) + class LauncherCaptureTests(AutopilotTestCase): """Test the launchers ability to capture/not capture the mouse.""" @@ -717,3 +779,31 @@ x_fin, y_fin = self.mouse.position() # The launcher should have held the mouse a little bit self.assertThat(x_fin, LessThan(x + width * 1.5)) + + +class LauncherTooltipTests(AutopilotTestCase): + """Test the launcher tooltips""" + + def setUp(self): + super(LauncherTooltipTests, self).setUp() + self.set_unity_option('launcher_hide_mode', 0) + + def test_bfb_tooltip_disappear_when_dash_is_opened(self): + """Tests that the bfb tooltip disappear when the dash is opened.""" + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False))) + + def test_bfb_tooltip_is_disabled_when_dash_is_open(self): + """Tests the that bfb tooltip is disabled when the dash is open.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + + self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False))) only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/tests/__init__.py +++ unity-5.12/tests/autopilot/autopilot/tests/__init__.py @@ -277,8 +277,9 @@ def close_all_app(self, app_name): """Close all instances of the app_name.""" app = self.KNOWN_APPS[app_name] - self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True) - super(LoggedTestCase, self).tearDown() + pids = check_output(["pidof", app['process-name']]).split() + if len(pids): + call(["kill"] + pids) def get_app_instances(self, app_name): """Get BamfApplication instances for app_name.""" only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/emulators/bamf.py +++ unity-5.12/tests/autopilot/autopilot/emulators/bamf.py @@ -75,6 +75,14 @@ """ return [a for a in self.get_running_applications() if a.desktop_file == desktop_file] + def get_application_by_xid(self, xid): + """Return the application that has a child with the requested xid or None.""" + + app_path = self.matcher_interface.ApplicationForXid(xid) + if len(app_path): + return BamfApplication(app_path) + return None + def get_open_windows(self, user_visible_only=True): """Get a list of currently open windows. @@ -85,17 +93,16 @@ """ - # Get the stacking order from the root window. - root_win = _X_DISPLAY.screen().root - prop = root_win.get_full_property( - _X_DISPLAY.get_atom('_NET_CLIENT_LIST_STACKING'), X.AnyPropertyType) - stack = prop.value.tolist() - - windows = [BamfWindow(w) for w in self.matcher_interface.WindowPaths()] + windows = [BamfWindow(w) for w in self.matcher_interface.WindowStackForMonitor(-1)] if user_visible_only: windows = filter(_filter_user_visible, windows) # Now sort on stacking order. - return sorted(windows, key=lambda w: stack.index(w.x_id), reverse=True) + return reversed(windows) + + def get_window_by_xid(self, xid): + """Get the BamfWindow that matches the provided 'xid'.""" + windows = [BamfWindow(w) for w in self.matcher_interface.WindowPaths() if BamfWindow(w).x_id == xid] + return windows[0] if windows else None def wait_until_application_is_running(self, desktop_file, timeout): """Wait until a given application is running. only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/emulators/unity/icons.py +++ unity-5.12/tests/autopilot/autopilot/emulators/unity/icons.py @@ -9,6 +9,7 @@ from autopilot.emulators.unity import UnityIntrospectionObject from autopilot.emulators.unity.quicklist import Quicklist +from autopilot.emulators.unity.tooltip import ToolTip class SimpleLauncherIcon(UnityIntrospectionObject): """Holds information about a simple launcher icon. @@ -20,7 +21,7 @@ @property def center_position(self): - """Get the center point of an icon, returns a tuple with (x, y, z)""" + """Get the center point of an icon, returns a tuple with (x, y, z).""" return (self.center_x, self.center_y, self.center_z) def get_quicklist(self): @@ -33,13 +34,28 @@ matches = self.get_children_by_type(Quicklist) return matches[0] if matches else None + def get_tooltip(self): + """Get the tooltip for this launcher icon. + + This may return None, if there is no tooltip associated with this + launcher icon. + + """ + matches = self.get_children_by_type(ToolTip) + return matches[0] if matches else None + def is_on_monitor(self, monitor): - """Returns True if the icon is available in the defined monitor""" + """Returns True if the icon is available in the defined monitor.""" if monitor >= 0 and monitor < len(self.monitors_visibility): return self.monitors_visibility[monitor] return False + def controls_window(self, xid): + """Returns true if the icon controls the specified xid.""" + + return self.xids.contains(xid) + class BFBLauncherIcon(SimpleLauncherIcon): """Represents the BFB button in the launcher.""" only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py +++ unity-5.12/tests/autopilot/autopilot/emulators/unity/shortcut_hint.py @@ -15,10 +15,16 @@ logger = logging.getLogger(__name__) +class ShortcutView(UnityIntrospectionObject): + """Proxy object for the shortcut view child of the controller.""" class ShortcutController(UnityIntrospectionObject, KeybindingsHelper): """ShortcutController proxy class.""" + def get_shortcut_view(self): + views = self.get_children_by_type(ShortcutView) + return views[0] if views else None + def show(self): """Push the keys necessary to reveal the shortcut hint, but don't block.""" logger.debug("Revealing shortcut hint with keyboard.") only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/emulators/unity/tooltip.py +++ unity-5.12/tests/autopilot/autopilot/emulators/unity/tooltip.py @@ -0,0 +1,20 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Andrea Azzarone +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +import logging +from time import sleep + +from autopilot.emulators.unity import UnityIntrospectionObject + + +logger = logging.getLogger(__name__) + + +class ToolTip(UnityIntrospectionObject): + """Represents a tooltip.""" only in patch2: unchanged: --- unity-5.12.orig/tests/autopilot/autopilot/emulators/unity/launcher.py +++ unity-5.12/tests/autopilot/autopilot/emulators/unity/launcher.py @@ -338,6 +338,14 @@ return None + def get_icon_by_window_xid(self, xid): + """Gets a launcher icon that controls the specified window xid.""" + icons = [i for i in self.get_children_by_type(SimpleLauncherIcon) if i.xids.contains(xid)] + if (len(icons)): + return icons[0] + + return None + def get_icons_by_filter(self, **kwargs): """Get a list of icons that satisfy the given filters. only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/LauncherIcon.h +++ unity-5.12/plugins/unityshell/src/LauncherIcon.h @@ -324,6 +324,8 @@ void LoadTooltip(); void LoadQuicklist(); + void OnTooltipEnabledChanged(bool value); + bool _remote_urgent; float _present_urgency; float _progress; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/unity-launcher-accessible.cpp +++ unity-5.12/plugins/unityshell/src/unity-launcher-accessible.cpp @@ -63,7 +63,7 @@ gint i); /* private */ -static void on_selection_change_cb(UnityLauncherAccessible* launcher_accessible); +static void on_selection_change_cb(AbstractLauncherIcon::Ptr selection, UnityLauncherAccessible* launcher_accessible); static void on_icon_added_cb(AbstractLauncherIcon::Ptr icon, UnityLauncherAccessible* self); static void on_icon_removed_cb(AbstractLauncherIcon::Ptr icon, UnityLauncherAccessible* self); static void on_order_change_cb(UnityLauncherAccessible* self); @@ -158,13 +158,13 @@ launcher = dynamic_cast(nux_object); - self->priv->on_selection_change_connection = - launcher->selection_change.connect(sigc::bind(sigc::ptr_fun(on_selection_change_cb), self)); - model = launcher->GetModel(); if (model) { + self->priv->on_selection_change_connection = + model->selection_changed.connect(sigc::bind(sigc::ptr_fun(on_selection_change_cb), self)); + self->priv->on_icon_added_connection = model->icon_added.connect(sigc::bind(sigc::ptr_fun(on_icon_added_cb), self)); @@ -365,7 +365,7 @@ } /* private */ -static void on_selection_change_cb(UnityLauncherAccessible* launcher_accessible) +static void on_selection_change_cb(AbstractLauncherIcon::Ptr selection, UnityLauncherAccessible* launcher_accessible) { g_signal_emit_by_name(ATK_OBJECT(launcher_accessible), "selection-changed"); } @@ -386,6 +386,7 @@ return; icon_accessible = unity_a11y_get_accessible(icon.GetPointer()); + atk_object_set_parent(icon_accessible, ATK_OBJECT(self)); update_children_index(self); only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ResultView.cpp +++ unity-5.12/plugins/unityshell/src/ResultView.cpp @@ -74,6 +74,7 @@ { renderer_->Unload(result); } + renderer_->UnReference(); } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp +++ unity-5.12/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp @@ -101,6 +101,9 @@ void unity::ScreenEffectFramebufferObject::bind (const nux::Geometry &output) { + if (!BackgroundEffectHelper::HasDirtyHelpers()) + return; + /* Clear the error bit */ glGetError (); only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ResultViewGrid.cpp +++ unity-5.12/plugins/unityshell/src/ResultViewGrid.cpp @@ -70,9 +70,11 @@ { NeedRedraw(); }; + horizontal_spacing.changed.connect(needredraw_lambda); vertical_spacing.changed.connect(needredraw_lambda); padding.changed.connect(needredraw_lambda); + selected_index_.changed.connect(needredraw_lambda); key_nav_focus_change.connect(sigc::mem_fun(this, &ResultViewGrid::OnKeyNavFocusChange)); key_nav_focus_activate.connect([&] (nux::Area *area) { UriActivated.emit (focused_uri_); }); @@ -103,7 +105,6 @@ }); SetDndEnabled(true, false); - NeedRedraw(); } ResultViewGrid::~ResultViewGrid() @@ -482,30 +483,30 @@ { case (nux::KEY_NAV_LEFT): { - --selected_index_; + selected_index_ = selected_index_ - 1; break; } case (nux::KEY_NAV_RIGHT): { - ++selected_index_; + selected_index_ = selected_index_ + 1; break; } case (nux::KEY_NAV_UP): { - selected_index_ -= items_per_row; + selected_index_ = selected_index_ - items_per_row; break; } case (nux::KEY_NAV_DOWN): { - selected_index_ += items_per_row; + selected_index_ = selected_index_ + items_per_row; break; } default: break; } - selected_index_ = std::max(0, selected_index_); - selected_index_ = std::min(static_cast(results_.size() - 1), selected_index_); + selected_index_ = std::max(0, selected_index_()); + selected_index_ = std::min(static_cast(results_.size() - 1), selected_index_()); focused_uri_ = results_[selected_index_].uri; int focused_x = (renderer_->width + horizontal_spacing + extra_horizontal_spacing_) * (selected_index_ % items_per_row); @@ -514,8 +515,6 @@ ubus_.SendMessage(UBUS_RESULT_VIEW_KEYNAV_CHANGED, g_variant_new("(iiii)", focused_x, focused_y, renderer_->width(), renderer_->height())); selection_change.emit(); - - NeedRedraw(); } nux::Area* ResultViewGrid::KeyNavIteration(nux::KeyNavDirection direction) @@ -527,7 +526,7 @@ { if (HasKeyFocus()) { - if (selected_index_ < 0) + if (selected_index_ < 0 and !results_.empty()) { focused_uri_ = results_.front().uri; selected_index_ = 0; @@ -573,8 +572,6 @@ selection_change.emit(); } - - NeedRedraw(); } long ResultViewGrid::ComputeContentSize() @@ -736,12 +733,11 @@ if (mouse_over_index_ != index) { selected_index_ = mouse_over_index_ = index; + nux::GetWindowCompositor().SetKeyFocusArea(this); } mouse_last_x_ = x; mouse_last_y_ = y; - - NeedRedraw(); } void ResultViewGrid::MouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags) only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/LauncherIcon.cpp +++ unity-5.12/plugins/unityshell/src/LauncherIcon.cpp @@ -99,6 +99,9 @@ for (int i = 0; i < max_num_monitors; ++i) _is_visible_on_monitor[i] = true; + tooltip_enabled = true; + tooltip_enabled.changed.connect(sigc::mem_fun(this, &LauncherIcon::OnTooltipEnabledChanged)); + tooltip_text.SetSetterFunction(sigc::mem_fun(this, &LauncherIcon::SetTooltipText)); tooltip_text = "blank"; @@ -481,6 +484,12 @@ return result; } +void LauncherIcon::OnTooltipEnabledChanged(bool value) +{ + if (!value) + HideTooltip(); +} + void LauncherIcon::SetShortcut(guint64 shortcut) { @@ -499,7 +508,7 @@ void LauncherIcon::ShowTooltip() { - if (_quicklist && _quicklist->IsVisible()) + if (!tooltip_enabled || (_quicklist && _quicklist->IsVisible())) return; int tip_x = 100; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/AbstractLauncherIcon.h +++ unity-5.12/plugins/unityshell/src/AbstractLauncherIcon.h @@ -119,6 +119,7 @@ virtual ~AbstractLauncherIcon() {} nux::Property tooltip_text; + nux::Property tooltip_enabled; virtual void HideTooltip() = 0; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/HudLauncherIcon.cpp +++ unity-5.12/plugins/unityshell/src/HudLauncherIcon.cpp @@ -101,6 +101,7 @@ SetMonitor(overlay_monitor); SetQuirk(QUIRK_VISIBLE, visible); SetQuirk(QUIRK_ACTIVE, visible); + tooltip_enabled = !visible; EmitNeedsRedraw(); } } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/LauncherController.cpp +++ unity-5.12/plugins/unityshell/src/LauncherController.cpp @@ -380,6 +380,7 @@ launcher->display = display_; launcher->monitor = monitor; launcher->options = parent_->options(); + launcher->SetModel(model_.get()); nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); layout->AddView(launcher, 1); @@ -394,7 +395,6 @@ launcher_window->InputWindowEnableStruts(false); launcher_window->SetEnterFocusInputArea(launcher); - launcher->SetModel(model_.get()); launcher->launcher_addrequest.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequest)); launcher->launcher_addrequest_special.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequestSpecial)); launcher->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest)); @@ -740,7 +740,6 @@ return; } - g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1)); AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app)); icon->visibility_changed.connect(sigc::mem_fun(self, &Impl::SortAndUpdate)); icon->SetSortPriority(self->sort_priority_++); @@ -764,7 +763,6 @@ } bamf_view_set_sticky(BAMF_VIEW(app), true); - g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1)); AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app)); icon->SetSortPriority(sort_priority_++); result = icon; @@ -790,7 +788,6 @@ } bamf_view_set_sticky(BAMF_VIEW(app), true); - g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1)); result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path); result->SetSortPriority(sort_priority_++); @@ -833,7 +830,6 @@ if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"))) continue; - g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1)); AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app)); icon->SetSortPriority(sort_priority_++); RegisterIcon(icon); only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/BFBLauncherIcon.cpp +++ unity-5.12/plugins/unityshell/src/BFBLauncherIcon.cpp @@ -65,6 +65,7 @@ if (overlay_identity.Str() == "dash" && IsVisibleOnMonitor(overlay_monitor)) { + tooltip_enabled = !visible; SetQuirk(QUIRK_ACTIVE, visible); EmitNeedsRedraw(); } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/BamfLauncherIcon.h +++ unity-5.12/plugins/unityshell/src/BamfLauncherIcon.h @@ -66,6 +66,7 @@ std::string NameForWindow(Window window); protected: + void Remove(); void UpdateIconGeometries(std::vector center); void OnCenterStabilized(std::vector center); void AddProperties(GVariantBuilder* builder); @@ -124,6 +125,7 @@ guint _dnd_hover_timer; bool _supported_types_filled; + guint _remove_timeout_id; guint _fill_supported_types_id; guint _window_moved_id; guint _quicklist_activated_id; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/UnityWindowView.h +++ unity-5.12/plugins/unityshell/src/UnityWindowView.h @@ -21,6 +21,7 @@ #define UNITYWINDOWVIEW_H #include "BackgroundEffectHelper.h" +#include "Introspectable.h" #include "UnityWindowStyle.h" #include @@ -32,7 +33,7 @@ namespace unity { namespace ui { -class UnityWindowView : public nux::View +class UnityWindowView : public debug::Introspectable, public nux::View { NUX_DECLARE_OBJECT_TYPE(UnityWindowView, nux::View) public: @@ -53,10 +54,15 @@ virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw) {}; virtual nux::Geometry GetBackgroundGeometry() = 0; + // Introspectable methods + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + private: void DrawBackground(nux::GraphicsEngine& GfxContext, nux::Geometry const& geo); BackgroundEffectHelper bg_helper_; + nux::ObjectPtr bg_texture_; }; } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/unitya11y.cpp +++ unity-5.12/plugins/unityshell/src/unitya11y.cpp @@ -218,6 +218,9 @@ { g_debug("Unity Oneiric accessibility started, using bridge on %s", bridge_path); + + atk_get_root(); + a11y_initialized = TRUE; } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ShortcutView.cpp +++ unity-5.12/plugins/unityshell/src/ShortcutView.cpp @@ -287,5 +287,13 @@ } } +// +// Introspectable methods +// +std::string View::GetName() const +{ + return "ShortcutView"; +} + } // namespace shortcut } // namespace unity only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/UnityWindowView.cpp +++ unity-5.12/plugins/unityshell/src/UnityWindowView.cpp @@ -17,6 +17,8 @@ * Authored by: Jason Smith */ +#include + #include "UnityWindowView.h" namespace unity { @@ -56,7 +58,7 @@ // clear region gPainter.PaintBackground(GfxContext, base); - nux::Geometry background_geo = GetBackgroundGeometry(); + nux::Geometry background_geo(GetBackgroundGeometry()); int internal_offset = style()->GetInternalOffset(); nux::Geometry internal_clip(background_geo.x + internal_offset, @@ -65,50 +67,54 @@ background_geo.height - internal_offset * 2); GfxContext.PushClippingRectangle(internal_clip); - nux::Geometry geo_absolute = GetAbsoluteGeometry (); + nux::Geometry const& geo_absolute = GetAbsoluteGeometry(); + nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, base.width, base.height); if (BackgroundEffectHelper::blur_type != BLUR_NONE) { - nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, base.width, base.height); - auto blur_texture = bg_helper_.GetBlurRegion(blur_geo); + bg_texture_ = bg_helper_.GetBlurRegion(blur_geo); + } + else + { + bg_texture_ = bg_helper_.GetRegion(blur_geo); + } - if (blur_texture.IsValid()) - { - nux::TexCoordXForm texxform_blur_bg; - texxform_blur_bg.flip_v_coord = true; - texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width; - texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height; - - nux::ROPConfig rop; - rop.Blend = false; - rop.SrcBlend = GL_ONE; - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + if (bg_texture_.IsValid()) + { + nux::TexCoordXForm texxform_blur_bg; + texxform_blur_bg.flip_v_coord = true; + texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width; + texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height; + + nux::ROPConfig rop; + rop.Blend = false; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; #ifndef NUX_OPENGLES_20 - if (GfxContext.UsingGLSLCodePath()) - gPainter.PushDrawCompositionLayer(GfxContext, base, - blur_texture, - texxform_blur_bg, - nux::color::White, - background_color, nux::LAYER_BLEND_MODE_OVERLAY, - true, rop); - else - gPainter.PushDrawTextureLayer(GfxContext, base, - blur_texture, - texxform_blur_bg, - nux::color::White, - true, - rop); + if (GfxContext.UsingGLSLCodePath()) + gPainter.PushDrawCompositionLayer(GfxContext, base, + bg_texture_, + texxform_blur_bg, + nux::color::White, + background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); + else + gPainter.PushDrawTextureLayer(GfxContext, base, + bg_texture_, + texxform_blur_bg, + nux::color::White, + true, + rop); #else - gPainter.PushDrawCompositionLayer(GfxContext, base, - blur_texture, - texxform_blur_bg, - nux::color::White, - background_color, nux::LAYER_BLEND_MODE_OVERLAY, - true, rop); + gPainter.PushDrawCompositionLayer(GfxContext, base, + bg_texture_, + texxform_blur_bg, + nux::color::White, + background_color, nux::LAYER_BLEND_MODE_OVERLAY, + true, rop); #endif - } } nux::ROPConfig rop; @@ -240,6 +246,18 @@ GfxContext.GetRenderStates().SetBlend (FALSE); } +// Introspectable methods +std::string UnityWindowView::GetName() const +{ + return "UnityWindowView"; +} + +void UnityWindowView::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper(builder) + .add("bg-texture-is-valid", bg_texture_.IsValid()); +} + } } only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ResultViewGrid.h +++ unity-5.12/plugins/unityshell/src/ResultViewGrid.h @@ -52,7 +52,9 @@ nux::Property padding; sigc::signal selection_change; + int GetSelectedIndex(); + virtual uint GetIndexAtPosition(int x, int y); protected: void MouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); @@ -86,11 +88,10 @@ int GetItemsPerRow(); void SizeReallocate(); void PositionPreview(); - uint GetIndexAtPosition(int x, int y); uint mouse_over_index_; int active_index_; - int selected_index_; + nux::Property selected_index_; uint preview_row_; std::string focused_uri_; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ShortcutController.cpp +++ unity-5.12/plugins/unityshell/src/ShortcutController.cpp @@ -157,6 +157,7 @@ void Controller::ConstructView() { view_ = View::Ptr(new View()); + AddChild(view_.GetPointer()); view_->SetModel(model_); view_->background_color = bg_color_; only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/BamfLauncherIcon.cpp +++ unity-5.12/plugins/unityshell/src/BamfLauncherIcon.cpp @@ -54,6 +54,8 @@ , _fill_supported_types_id(0) , _window_moved_id(0) { + g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), + GUINT_TO_POINTER(1)); auto bamf_view = glib::object_cast(_bamf_app); glib::String icon(bamf_view_get_icon(bamf_view)); @@ -99,10 +101,17 @@ sig = new glib::Signal(bamf_view, "running-changed", [&] (BamfView*, gboolean running) { SetQuirk(QUIRK_RUNNING, running); + if (running) { EnsureWindowState(); UpdateIconGeometries(GetCenters()); + + if (_remove_timeout_id) + { + g_source_remove(_remove_timeout_id); + _remove_timeout_id = 0; + } } }); _gsignals.Add(sig); @@ -117,7 +126,23 @@ sig = new glib::Signal(bamf_view, "closed", [&] (BamfView*) { if (!IsSticky()) - Remove(); + { + /* Use a timeout to remove the icon, this avoids + * that we remove an application that is going + * to be reopened soon. So applications that + * have a splash screen won't be removed from + * the launcher while the splash is closed and + * a new window is opened. */ + if (_remove_timeout_id) + g_source_remove(_remove_timeout_id); + + _remove_timeout_id = g_timeout_add_seconds(1, [] (gpointer data) -> gboolean { + auto self = static_cast(data); + self->Remove(); + self->_remove_timeout_id = 0; + return false; + }, this); + } }); _gsignals.Add(sig); @@ -143,8 +168,10 @@ BamfLauncherIcon::~BamfLauncherIcon() { g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()), - g_quark_from_static_string("unity-seen"), - GUINT_TO_POINTER(0)); + g_quark_from_static_string("unity-seen"), nullptr); + + if (_remove_timeout_id != 0) + g_source_remove(_remove_timeout_id); if (_fill_supported_types_id != 0) g_source_remove(_fill_supported_types_id); @@ -159,6 +186,18 @@ g_source_remove(_dnd_hover_timer); } +void BamfLauncherIcon::Remove() +{ + /* Removing the unity-seen flag to the wrapped bamf application, on remove + * request we make sure that if the bamf application is re-opened while + * the removal process is still ongoing, the application will be shown + * on the launcher. */ + g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()), + g_quark_from_static_string("unity-seen"), nullptr); + + SimpleLauncherIcon::Remove(); +} + bool BamfLauncherIcon::IsSticky() const { return bamf_view_is_sticky(BAMF_VIEW(_bamf_app.RawPtr())); only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/unityshell.cpp +++ unity-5.12/plugins/unityshell/src/unityshell.cpp @@ -1449,8 +1449,11 @@ ShowdesktopHandler::InhibitLeaveShowdesktopMode (event->xmaprequest.window); break; case PropertyNotify: - if (event->xproperty.window == GDK_ROOT_WINDOW()) + if (event->xproperty.window == GDK_ROOT_WINDOW() && + event->xproperty.atom == gdk_x11_get_xatom_by_name("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS")) + { _bghash.RefreshColor(); + } break; default: if (screen->shapeEvent () + ShapeNotify == event->type) only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/ShortcutView.h +++ unity-5.12/plugins/unityshell/src/ShortcutView.h @@ -58,6 +58,9 @@ void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry clip); nux::Geometry GetBackgroundGeometry(); + // Introspectable methods + std::string GetName() const; + private: // Private methods nux::LinearLayout* CreateSectionLayout(const char* section_name); only in patch2: unchanged: --- unity-5.12.orig/plugins/unityshell/src/SwitcherView.h +++ unity-5.12/plugins/unityshell/src/SwitcherView.h @@ -27,8 +27,6 @@ #include "BackgroundEffectHelper.h" #include "UnityWindowView.h" -#include "Introspectable.h" - #include #include @@ -48,7 +46,7 @@ namespace switcher { -class SwitcherView : public debug::Introspectable, public ui::UnityWindowView +class SwitcherView : public ui::UnityWindowView { NUX_DECLARE_OBJECT_TYPE(SwitcherView, ui::UnityWindowView); public: