summaryrefslogtreecommitdiff
diff options
-rw-r--r--UnityCore/GnomeSessionManager.cpp32
-rw-r--r--UnityCore/GnomeSessionManagerImpl.h4
-rw-r--r--UnityCore/SessionManager.h4
-rw-r--r--dash/DashController.cpp57
-rw-r--r--dash/DashController.h8
-rw-r--r--dash/DashView.cpp4
-rw-r--r--dash/ResultRendererTile.cpp2
-rw-r--r--debian/changelog56
-rw-r--r--debian/control2
-rwxr-xr-xdebian/rules14
-rw-r--r--hud/HudController.cpp1
-rw-r--r--launcher/AbstractLauncherIcon.h5
-rw-r--r--launcher/ApplicationLauncherIcon.cpp29
-rw-r--r--launcher/ApplicationLauncherIcon.h1
-rw-r--r--launcher/Launcher.cpp34
-rw-r--r--launcher/LauncherController.cpp12
-rw-r--r--launcher/TrashLauncherIcon.cpp1
-rw-r--r--launcher/VolumeLauncherIcon.cpp1
-rw-r--r--lockscreen/CMakeLists.txt2
-rw-r--r--lockscreen/LockScreenAbstractShield.h7
-rw-r--r--lockscreen/LockScreenAcceleratorController.cpp146
-rw-r--r--lockscreen/LockScreenAcceleratorController.h46
-rw-r--r--lockscreen/LockScreenAccelerators.cpp528
-rw-r--r--lockscreen/LockScreenAccelerators.h94
-rw-r--r--lockscreen/LockScreenController.cpp16
-rw-r--r--lockscreen/LockScreenController.h5
-rw-r--r--lockscreen/LockScreenPanel.cpp239
-rw-r--r--lockscreen/LockScreenPanel.h52
-rw-r--r--lockscreen/LockScreenShield.cpp35
-rw-r--r--lockscreen/LockScreenShield.h4
-rw-r--r--lockscreen/LockScreenShieldFactory.cpp4
-rw-r--r--lockscreen/LockScreenShieldFactory.h4
-rw-r--r--lockscreen/UserPromptView.cpp108
-rw-r--r--lockscreen/UserPromptView.h14
-rw-r--r--plugins/unityshell/src/unityshell.cpp148
-rw-r--r--plugins/unityshell/src/unityshell.h3
-rw-r--r--po/POTFILES.in1
-rw-r--r--resources/launcher_icon_glow_62.pngbin0 -> 650 bytes
-rw-r--r--resources/launcher_icon_glow_62.svg.save (renamed from resources/launcher_icon_glow_62.svg)0
-rw-r--r--shutdown/SessionView.cpp32
-rw-r--r--tests/data/external.gschema.xml21
-rw-r--r--tests/test_lockscreen_controller.cpp6
-rw-r--r--tests/test_unity_window_view.cpp18
-rw-r--r--unity-shared/DebugDBusInterface.cpp28
-rw-r--r--unity-shared/PluginAdapter.cpp48
-rw-r--r--unity-shared/TextInput.cpp182
-rw-r--r--unity-shared/TextInput.h23
-rw-r--r--unity-shared/UnityWindowStyle.cpp66
-rw-r--r--unity-shared/UnityWindowStyle.h9
-rw-r--r--unity-shared/UnityWindowView.cpp36
-rw-r--r--unity-shared/UnityWindowView.h2
51 files changed, 1561 insertions, 633 deletions
diff --git a/UnityCore/GnomeSessionManager.cpp b/UnityCore/GnomeSessionManager.cpp
index 466a61125..a4ba1b284 100644
--- a/UnityCore/GnomeSessionManager.cpp
+++ b/UnityCore/GnomeSessionManager.cpp
@@ -85,6 +85,7 @@ GnomeManager::Impl::Impl(GnomeManager* manager, bool test_mode)
, can_hibernate_(false)
, pending_action_(shell::Action::NONE)
, shell_server_(test_mode_ ? testing::DBUS_NAME : shell::DBUS_NAME)
+ , open_sessions_(0)
{
shell_server_.AddObjects(shell::INTROSPECTION_XML, shell::DBUS_OBJECT_PATH);
shell_object_ = shell_server_.GetObject(shell::DBUS_INTERFACE);
@@ -126,6 +127,22 @@ GnomeManager::Impl::Impl(GnomeManager* manager, bool test_mode)
});
}
+ {
+ dm_proxy_ = std::make_shared<glib::DBusProxy>("org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager",
+ "org.freedesktop.DisplayManager",
+ G_BUS_TYPE_SYSTEM);
+
+ dm_proxy_->Connect("SessionAdded", sigc::hide(sigc::mem_fun(this, &Impl::UpdateHaveOtherOpenSessions)));
+ dm_proxy_->Connect("SessionRemoved", sigc::hide(sigc::mem_fun(this, &Impl::UpdateHaveOtherOpenSessions)));
+
+ UpdateHaveOtherOpenSessions();
+
+ manager_->have_other_open_sessions.SetGetterFunction([this]() {
+ return open_sessions_ > 1;
+ });
+ }
+
CallLogindMethod("CanHibernate", nullptr, [this] (GVariant* variant, glib::Error const& err) {
if (err)
{
@@ -422,6 +439,21 @@ void GnomeManager::Impl::LockScreen(bool prompt)
prompt ? manager_->prompt_lock_requested.emit() : manager_->lock_requested.emit();
}
+void GnomeManager::Impl::UpdateHaveOtherOpenSessions()
+{
+ dm_proxy_->GetProperty("Sessions", [this](GVariant* variant) {
+ GVariantIter *sessions;
+ g_variant_get(variant, "ao", &sessions);
+ int open_sessions = g_variant_iter_n_children(sessions);
+
+ if (open_sessions_ != open_sessions)
+ {
+ open_sessions_ = open_sessions;
+ manager_->have_other_open_sessions.changed.emit(open_sessions_);
+ }
+ });
+}
+
// Public implementation
GnomeManager::GnomeManager()
diff --git a/UnityCore/GnomeSessionManagerImpl.h b/UnityCore/GnomeSessionManagerImpl.h
index 1045b78db..1730748c5 100644
--- a/UnityCore/GnomeSessionManagerImpl.h
+++ b/UnityCore/GnomeSessionManagerImpl.h
@@ -61,6 +61,7 @@ struct GnomeManager::Impl
void CallLogindMethod(std::string const& method, GVariant* parameters = nullptr, glib::DBusProxy::CallFinishedCallback const& cb = nullptr);
void CallConsoleKitMethod(std::string const& method, GVariant* parameters = nullptr);
bool InteractiveMode();
+ void UpdateHaveOtherOpenSessions();
GnomeManager* manager_;
bool test_mode_;
@@ -73,6 +74,9 @@ struct GnomeManager::Impl
glib::DBusObject::Ptr shell_object_;
glib::DBusProxy::Ptr login_proxy_;
glib::DBusProxy::Ptr presence_proxy_;
+ glib::DBusProxy::Ptr dm_proxy_;
+
+ int open_sessions_;
};
} // namespace session
diff --git a/UnityCore/SessionManager.h b/UnityCore/SessionManager.h
index fb45e5253..2ef619909 100644
--- a/UnityCore/SessionManager.h
+++ b/UnityCore/SessionManager.h
@@ -23,6 +23,8 @@
#include <sigc++/sigc++.h>
#include <memory>
+#include <NuxCore/Property.h>
+
namespace unity
{
namespace session
@@ -36,6 +38,8 @@ public:
Manager() = default;
virtual ~Manager() = default;
+ nux::ROProperty<bool> have_other_open_sessions;
+
virtual std::string RealName() const = 0;
virtual std::string UserName() const = 0;
virtual std::string HostName() const = 0;
diff --git a/dash/DashController.cpp b/dash/DashController.cpp
index 0e693c53f..6ecd146cc 100644
--- a/dash/DashController.cpp
+++ b/dash/DashController.cpp
@@ -66,7 +66,6 @@ Controller::Controller(Controller::WindowCreator const& create_window)
, create_window_(create_window)
, monitor_(0)
, visible_(false)
- , need_show_(false)
, dbus_server_(dbus::BUS_NAME)
, ensure_timeout_(PRELOAD_TIMEOUT_LENGTH)
, timeline_animator_(90)
@@ -105,7 +104,9 @@ Controller::Controller(Controller::WindowCreator const& create_window)
}
});
- WindowManager::Default().initiate_spread.connect(sigc::mem_fun(this, &Controller::HideDash));
+ auto& wm = WindowManager::Default();
+ wm.initiate_spread.connect(sigc::mem_fun(this, &Controller::HideDash));
+ wm.screen_viewport_switch_started.connect(sigc::mem_fun(this, &Controller::HideDash));
dbus_server_.AddObjects(dbus::INTROSPECTION, dbus::PATH);
dbus_server_.GetObjects().front()->SetMethodsCallsHandler([this] (std::string const& method, GVariant*) {
@@ -262,20 +263,14 @@ void Controller::OnMouseDownOutsideWindow(int x, int y,
HideDash();
}
-void Controller::OnScreenUngrabbed()
-{
- LOG_DEBUG(logger) << "On Screen Ungrabbed called";
- if (need_show_)
- {
- EnsureDash();
- ShowDash();
- }
-}
-
void Controller::OnExternalShowDash(GVariant* variant)
{
EnsureDash();
- visible_ ? HideDash() : ShowDash();
+
+ if (!visible_)
+ ShowDash();
+ else
+ HideDash();
}
void Controller::OnExternalHideDash(GVariant* variant)
@@ -283,31 +278,44 @@ void Controller::OnExternalHideDash(GVariant* variant)
HideDash();
}
-void Controller::ShowDash()
+bool Controller::ShowDash()
{
- EnsureDash();
- WindowManager& wm = WindowManager::Default();
// Don't want to show at the wrong time
- if (visible_ || wm.IsExpoActive() || wm.IsScaleActive())
- return;
+ if (visible_)
+ return false;
+
+ WindowManager& wm = WindowManager::Default();
+
+ if (wm.IsExpoActive())
+ wm.TerminateExpo();
// We often need to wait for the mouse/keyboard to be available while a plugin
// is finishing it's animations/cleaning up. In these cases, we patiently wait
// for the screen to be available again before honouring the request.
if (wm.IsScreenGrabbed())
{
- screen_ungrabbed_slot_ = wm.screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
- need_show_ = true;
- return;
+ screen_ungrabbed_slot_ = wm.screen_ungrabbed.connect([this] {
+ grab_wait_.reset();
+ ShowDash();
+ });
+
+ // Let's wait ungrab event for maximum a couple of seconds...
+ grab_wait_.reset(new glib::TimeoutSeconds(2, [this] {
+ screen_ungrabbed_slot_->disconnect();
+ return false;
+ }));
+
+ return false;
}
+ EnsureDash();
monitor_ = GetIdealMonitor();
+ screen_ungrabbed_slot_->disconnect();
int launcher_width = unity::Settings::Instance().LauncherWidth(monitor_);
view_->SetMonitorOffset(launcher_width, panel::Style::Instance().PanelHeight(monitor_));
view_->AboutToShow(monitor_);
FocusWindow();
- need_show_ = false;
visible_ = true;
StartShowHideTimeline();
@@ -316,6 +324,7 @@ void Controller::ShowDash()
GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_, view_content_geo.width, view_content_geo.height);
ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);
+ return true;
}
void Controller::FocusWindow()
@@ -347,8 +356,6 @@ void Controller::HideDash()
if (!visible_)
return;
- screen_ungrabbed_slot_->disconnect();
-
EnsureDash();
view_->AboutToHide();
@@ -394,7 +401,7 @@ void Controller::OnActivateRequest(GVariant* variant)
view_->OnActivateRequest(variant);
}
-gboolean Controller::CheckShortcutActivation(const char* key_string)
+bool Controller::CheckShortcutActivation(const char* key_string)
{
if (!key_string)
return false;
diff --git a/dash/DashController.h b/dash/DashController.h
index e3256913c..ac5c12d93 100644
--- a/dash/DashController.h
+++ b/dash/DashController.h
@@ -51,7 +51,7 @@ public:
nux::BaseWindow* window() const;
- gboolean CheckShortcutActivation(const char* key_string);
+ bool CheckShortcutActivation(const char* key_string);
std::vector<char> GetAllShortcuts();
nux::Property<bool> use_primary;
@@ -60,7 +60,7 @@ public:
void HideDash();
void QuicklyHideDash();
- void ShowDash();
+ bool ShowDash();
void ReFocusKeyInput();
@@ -86,7 +86,6 @@ private:
void Relayout(bool check_monitor =false);
void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
- void OnScreenUngrabbed();
void OnExternalShowDash(GVariant* variant);
void OnExternalHideDash(GVariant* variant);
void OnActivateRequest(GVariant* variant);
@@ -103,14 +102,13 @@ private:
nux::ObjectPtr<ResizingBaseWindow> window_;
nux::ObjectPtr<DashView> view_;
int monitor_;
-
bool visible_;
- bool need_show_;
connection::Wrapper screen_ungrabbed_slot_;
connection::Wrapper form_factor_changed_;
glib::DBusServer dbus_server_;
glib::TimeoutSeconds ensure_timeout_;
+ glib::Source::UniquePtr grab_wait_;
nux::animation::AnimateValue<double> timeline_animator_;
UBusManager ubus_manager_;
};
diff --git a/dash/DashView.cpp b/dash/DashView.cpp
index a2cc68696..b9e73439a 100644
--- a/dash/DashView.cpp
+++ b/dash/DashView.cpp
@@ -1457,8 +1457,8 @@ std::vector<char> DashView::GetAllShortcuts()
{
for (Scope::Ptr scope: scopes_->GetScopes())
{
- std::string shortcut = scope->shortcut;
- if(shortcut.size() > 0)
+ std::string const& shortcut = scope->shortcut;
+ if (!shortcut.empty())
result.push_back(shortcut.at(0));
}
}
diff --git a/dash/ResultRendererTile.cpp b/dash/ResultRendererTile.cpp
index f20a298d0..9b677409e 100644
--- a/dash/ResultRendererTile.cpp
+++ b/dash/ResultRendererTile.cpp
@@ -424,7 +424,7 @@ void ResultRendererTile::IconLoaded(std::string const& texid,
bool IsBlacklistedChar(gunichar uni_c)
{
if ((uni_c >= 0x1000 && uni_c <= 0x109F) ||
- (uni_c >= 0xAA60 && uni_c >= 0xAA7B))
+ (uni_c >= 0xAA60 && uni_c <= 0xAA7B))
{
return true;
}
diff --git a/debian/changelog b/debian/changelog
index 27977c2b6..50538cac3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,59 @@
+unity (7.2.0+14.10.20140512.4-0ubuntu1) utopic; urgency=low
+
+ [ Stephen M. Webb ]
+ * lockscreen/LockScreenAccelerators.h: added required header for
+ std:vector definition
+ * disabled precompiled headers on arm64 Ubuntu package builds (LP:
+ #1317276)
+
+ [ Brandon Schaefer ]
+ * Set the max width, so our static text wraps. So we don't end up
+ rendering text out of the view area. (LP: #1312749)
+
+ [ Marco Trevisan (Treviño) ]
+ * UnityScreen: toggle activation of all the unity compiz actions when
+ locking the screen Also, make sure that the lockscreen views are
+ treated as "always-on-front" windows by nux (and this applies to
+ both visibility and events).
+ * PanelService: emit an invalid EntryActivated signal if the menu
+ hasn't actually been shown In addition, if the menu is not visible
+ after the first popup call, try to show a menu without keyboard
+ focus. This will make possible to see menus also when there's a key-
+ grab (although they will be without keyboard support). Finally,
+ reset the menu state, if that failed.
+ * UnityScreen: always paint the lockscreen above, just add menu and
+ onboard as exceptions Some code cleanup, factorizing similar code.
+ (LP: #1313280)
+ * UnityScreen: don't try to show Dash/Hud if the screen is grabbed
+ Also move the dash opening out from LauncherController, and get rid
+ of UBus as first initialization source, as it can only slow things
+ down here. (LP: #741869)
+ * PluginAdapter: make sure we don't try to call an invalid
+ initiate/terminate callback function (LP: #1221673)
+ * DebugDBusInterface: match properties if they are in the AP array
+ form [<type>, <value>] (LP: #1307748)
+
+ [ William Hua ]
+ * Add proper support for modifier-only shortcuts on the lock screen.
+ (LP: #1291461)
+
+ [ Jinkyu Yi ]
+ * Dash: Fix problem at checking blacklisted unicode range (LP:
+ #1251193)
+
+ [ Andrea Azzarone ]
+ * Add a warning in the session dialog if other sessions are still
+ open. (LP: #1281058)
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 12 May 2014 22:03:27 +0000
+
+unity (7.2.0+14.04.20140423-0ubuntu2) utopic; urgency=medium
+
+ * debian/control: depends on autopilot-desktop-legacy rather than
+ autopilot-desktop.
+
+ -- Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com> Thu, 01 May 2014 00:32:05 -0400
+
unity (7.2.0+14.04.20140423-0ubuntu1.2) trusty-security; urgency=medium
* SECURITY UPDATE: more lock screen bypass issues, and regression with
diff --git a/debian/control b/debian/control
index 0609086f2..214cc81dd 100644
--- a/debian/control
+++ b/debian/control
@@ -165,7 +165,7 @@ Section: python
Architecture: all
Depends: ${misc:Depends},
${python:Depends},
- autopilot-desktop,
+ autopilot-desktop-legacy,
python-windowmocker,
gir1.2-appindicator3-0.1,
gir1.2-dee-1.0,
diff --git a/debian/rules b/debian/rules
index 1e862b9df..d6ef3b2f6 100755
--- a/debian/rules
+++ b/debian/rules
@@ -23,14 +23,18 @@ LIBUNITY_PRIVATE := $(shell pkg-config --libs-only-L unity-protocol-private | se
SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
-
-override_dh_auto_configure:
+cmake_base_options := -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), $(gles2_architectures)))
- dh_auto_configure -- -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CFLAGS=ON
-else
- dh_auto_configure -- -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
+ cmake_gl_options := -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CFLAGS=ON
+endif
+ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), arm64))
+ cmake_pch_options := -Duse_pch=OFF
endif
+
+override_dh_auto_configure:
+ dh_auto_configure -- $(cmake_base_options) $(cmake_gl_options) $(cmake_pch_options)
+
override_dh_install:
# install autopilot tests
cd tests/autopilot; \
diff --git a/hud/HudController.cpp b/hud/HudController.cpp
index 58134d4a6..aefe40f63 100644
--- a/hud/HudController.cpp
+++ b/hud/HudController.cpp
@@ -102,6 +102,7 @@ Controller::Controller(Controller::ViewCreator const& create_view,
WindowManager& wm = WindowManager::Default();
wm.screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
wm.initiate_spread.connect(sigc::mem_fun(this, &Controller::HideHud));
+ wm.screen_viewport_switch_started.connect(sigc::mem_fun(this, &Controller::HideHud));
hud_service_.queries_updated.connect(sigc::mem_fun(this, &Controller::OnQueriesFinished));
timeline_animator_.updated.connect(sigc::mem_fun(this, &Controller::OnViewShowHideFrame));
diff --git a/launcher/AbstractLauncherIcon.h b/launcher/AbstractLauncherIcon.h
index fe2600062..5cacbe96d 100644
--- a/launcher/AbstractLauncherIcon.h
+++ b/launcher/AbstractLauncherIcon.h
@@ -110,10 +110,11 @@ public:
UNFOLDED,
STARTING,
SHIMMER,
- CENTER_SAVED,
- PROGRESS,
DESAT,
+ GLOW,
+ PROGRESS,
PULSE_ONCE,
+ CENTER_SAVED,
LAST
};
diff --git a/launcher/ApplicationLauncherIcon.cpp b/launcher/ApplicationLauncherIcon.cpp
index d88fe3e1f..4d079f1fd 100644
--- a/launcher/ApplicationLauncherIcon.cpp
+++ b/launcher/ApplicationLauncherIcon.cpp
@@ -49,9 +49,10 @@ namespace
// We use the "bamf-" prefix since the manager is protected, to avoid name clash
const std::string WINDOW_MOVE_TIMEOUT = "bamf-window-move";
const std::string ICON_REMOVE_TIMEOUT = "bamf-icon-remove";
-//const std::string ICON_DND_OVER_TIMEOUT = "bamf-icon-dnd-over";
+const std::string ICON_DND_OVER_TIMEOUT = "bamf-icon-dnd-over";
const std::string DEFAULT_ICON = "application-default-icon";
const int MAXIMUM_QUICKLIST_WIDTH = 300;
+const int COMPIZ_SCALE_DND_SPREAD = 1 << 7;
enum MenuItemType
{
@@ -1157,28 +1158,28 @@ std::string ApplicationLauncherIcon::GetRemoteUri() const
return _remote_uri;
}
-void ApplicationLauncherIcon::OnDndHovered()
-{
- // for now, let's not do this, it turns out to be quite buggy
- //if (IsRunning())
- // Spread(CompAction::StateInitEdgeDnd, true);
-}
-
void ApplicationLauncherIcon::OnDndEnter()
{
- /* Disabled, since the DND code is currently disabled as well.
- _source_manager.AddTimeout(1000, [this] {
- OnDndHovered();
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
+
+ _source_manager.AddTimeout(1000, [this, timestamp] {
+ WindowManager::Default().TerminateScale();
+
+ if (!IsRunning())
+ return false;
+
+ Focus(ActionArg(ActionArg::Source::LAUNCHER, 1, timestamp));
+
+ if (GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() > 1)
+ Spread(true, COMPIZ_SCALE_DND_SPREAD, false);
+
return false;
}, ICON_DND_OVER_TIMEOUT);
- */
}
void ApplicationLauncherIcon::OnDndLeave()
{
- /* Disabled, since the DND code is currently disabled as well.
_source_manager.Remove(ICON_DND_OVER_TIMEOUT);
- */
}
bool ApplicationLauncherIcon::IsFileManager()
diff --git a/launcher/ApplicationLauncherIcon.h b/launcher/ApplicationLauncherIcon.h
index e7a26fed7..b92ad5e1f 100644
--- a/launcher/ApplicationLauncherIcon.h
+++ b/launcher/ApplicationLauncherIcon.h
@@ -83,7 +83,6 @@ protected:
void AddProperties(debug::IntrospectionData&);
void OnAcceptDrop(DndData const& dnd_data);
void OnDndEnter();
- void OnDndHovered();
void OnDndLeave();
void OpenInstanceLauncherIcon(Time timestamp) override;
void ToggleSticky();
diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp
index 4b67ddc30..088e2b168 100644
--- a/launcher/Launcher.cpp
+++ b/launcher/Launcher.cpp
@@ -157,6 +157,7 @@ Launcher::Launcher(MockableBaseWindow* parent,
hide_machine_.should_hide_changed.connect(sigc::mem_fun(this, &Launcher::SetHidden));
hide_machine_.reveal_progress.changed.connect(redraw_cb);
hover_machine_.should_hover_changed.connect(sigc::mem_fun(this, &Launcher::SetHover));
+ bg_effect_helper_.enabled.changed.connect(redraw_cb);
mouse_down.connect(sigc::mem_fun(this, &Launcher::RecvMouseDown));
mouse_up.connect(sigc::mem_fun(this, &Launcher::RecvMouseUp));
@@ -599,7 +600,7 @@ void Launcher::SetupRenderArg(AbstractLauncherIcon::Ptr const& icon, RenderArg&
else
urgent_progress = CLAMP(urgent_progress * 3.0f - 2.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle
- arg.glow_intensity = urgent_progress;
+ arg.glow_intensity = icon->GetQuirkProgress(AbstractLauncherIcon::Quirk::GLOW, monitor()) + urgent_progress;
if (options()->urgent_animation() == URGENT_ANIMATION_WIGGLE)
{
@@ -809,13 +810,11 @@ void Launcher::RenderArgs(std::list<RenderArg> &launcher_args,
}
}
- float drag_hide_progress = dnd_hide_animation_.GetCurrentValue();
- if (options()->hide_mode != LAUNCHER_HIDE_NEVER && drag_hide_progress > 0.0f)
+ if (options()->hide_mode != LAUNCHER_HIDE_NEVER)
{
+ float drag_hide_progress = dnd_hide_animation_.GetCurrentValue();
autohide_offset -= geo.width * 0.25f * drag_hide_progress;
-
- if (drag_hide_progress >= 1.0f)
- hide_machine_.SetQuirk(LauncherHideMachine::DND_PUSHED_OFF, true);
+ hide_machine_.SetQuirk(LauncherHideMachine::DND_PUSHED_OFF, (drag_hide_progress >= 1.0f));
}
// Inform the painter where to paint the box
@@ -1171,6 +1170,9 @@ void Launcher::OnSpreadChanged()
hide_machine_.SetQuirk(LauncherHideMachine::SCALE_ACTIVE, active);
bg_effect_helper_.enabled = active;
+ if (hide_machine_.GetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE))
+ return;
+
if (active && icon_under_mouse_)
icon_under_mouse_->HideTooltip();
@@ -1592,6 +1594,7 @@ void Launcher::SetupIconAnimations(AbstractLauncherIcon::Ptr const& icon)
icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::CENTER_SAVED, ANIM_DURATION, monitor());
icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::PROGRESS, ANIM_DURATION, monitor());
icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::DESAT, ANIM_DURATION_SHORT_SHORT, monitor());
+ icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::GLOW, ANIM_DURATION_SHORT, monitor());
if (options()->urgent_animation() == URGENT_ANIMATION_WIGGLE)
icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::URGENT, (ANIM_DURATION_SHORT * WIGGLE_CYCLES), monitor());
@@ -2523,7 +2526,10 @@ void Launcher::DndHoveredIconReset()
}
if (!steal_drag_ && dnd_hovered_icon_)
+ {
dnd_hovered_icon_->SendDndLeave();
+ dnd_hovered_icon_->SetQuirk(AbstractLauncherIcon::Quirk::GLOW, false, monitor());
+ }
steal_drag_ = false;
drag_edge_touching_ = false;
@@ -2535,7 +2541,6 @@ void Launcher::ProcessDndLeave()
{
#ifdef USE_X11
SetStateMouseOverLauncher(false);
-
DndHoveredIconReset();
#endif
}
@@ -2581,7 +2586,10 @@ void Launcher::ProcessDndMove(int x, int y, std::list<char*> mimes)
mouse_position_.y <= (parent_->GetGeometry().height - icon_size_.CP(cv_) - 2 * SPACE_BETWEEN_ICONS.CP(cv_)))
{
if (dnd_hovered_icon_)
- dnd_hovered_icon_->SendDndLeave();
+ {
+ dnd_hovered_icon_->SendDndLeave();
+ dnd_hovered_icon_->SetQuirk(AbstractLauncherIcon::Quirk::GLOW, false, monitor());
+ }
animation::StartOrReverse(dnd_hide_animation_, animation::Direction::FORWARD);
drag_edge_touching_ = true;
@@ -2640,6 +2648,9 @@ void Launcher::ProcessDndMove(int x, int y, std::list<char*> mimes)
{
hovered_icon->SendDndEnter();
drag_action_ = hovered_icon->QueryAcceptDrop(dnd_data_);
+
+ if (drag_action_ != nux::DNDACTION_NONE)
+ hovered_icon->SetQuirk(AbstractLauncherIcon::Quirk::GLOW, true, monitor());
}
else
{
@@ -2647,7 +2658,10 @@ void Launcher::ProcessDndMove(int x, int y, std::list<char*> mimes)
}
if (dnd_hovered_icon_)
+ {
dnd_hovered_icon_->SendDndLeave();
+ dnd_hovered_icon_->SetQuirk(AbstractLauncherIcon::Quirk::GLOW, false, monitor());
+ }
dnd_hovered_icon_ = hovered_icon;
}
@@ -2790,8 +2804,10 @@ void Launcher::UnsetDndQuirk()
}
}
+
+ hide_machine_.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, drag_out_delta_x_ >= DRAG_OUT_PIXELS - 90.0f);
hide_machine_.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, false);
- hide_machine_.SetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE, false);
+ animation::SetValue(dnd_hide_animation_, animation::Direction::BACKWARD);
#endif
}
diff --git a/launcher/LauncherController.cpp b/launcher/LauncherController.cpp
index 86d8ba20c..39b54d807 100644
--- a/launcher/LauncherController.cpp
+++ b/launcher/LauncherController.cpp
@@ -1199,18 +1199,6 @@ bool Controller::AboutToShowDash(int was_tap, int when) const
void Controller::HandleLauncherKeyRelease(bool was_tap, int when)
{
int tap_duration = when - pimpl->launcher_key_press_time_;
- WindowManager& wm = WindowManager::Default();
-
- if (tap_duration < options()->super_tap_duration && was_tap &&
- !wm.IsTopWindowFullscreenOnMonitorWithMouse())
- {
- LOG_DEBUG(logger) << "Quick tap, sending activation request.";
- pimpl->SendHomeActivationRequest();
- }
- else
- {
- LOG_DEBUG(logger) << "Tap too long: " << tap_duration;
- }
pimpl->sources_.Remove(local::LABELS_TIMEOUT);
pimpl->sources_.Remove(local::KEYPRESS_TIMEOUT);
diff --git a/launcher/TrashLauncherIcon.cpp b/launcher/TrashLauncherIcon.cpp
index 8c254e6de..fdc540e43 100644
--- a/launcher/TrashLauncherIcon.cpp
+++ b/launcher/TrashLauncherIcon.cpp
@@ -173,6 +173,7 @@ void TrashLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
}
SetQuirk(LauncherIcon::Quirk::PULSE_ONCE, true);
+ FullyAnimateQuirkDelayed(100, LauncherIcon::Quirk::SHIMMER);
}
std::string TrashLauncherIcon::GetName() const
diff --git a/launcher/VolumeLauncherIcon.cpp b/launcher/VolumeLauncherIcon.cpp
index 0818cf7c1..0cec6afeb 100644
--- a/launcher/VolumeLauncherIcon.cpp
+++ b/launcher/VolumeLauncherIcon.cpp
@@ -410,6 +410,7 @@ void VolumeLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
pimpl_->CopyFilesToVolume(dnd_data.Uris(), timestamp);
SetQuirk(Quirk::PULSE_ONCE, true);
+ FullyAnimateQuirkDelayed(100, LauncherIcon::Quirk::SHIMMER);
}
//
diff --git a/lockscreen/CMakeLists.txt b/lockscreen/CMakeLists.txt
index b32421f8f..47c1c54ed 100644
--- a/lockscreen/CMakeLists.txt
+++ b/lockscreen/CMakeLists.txt
@@ -24,6 +24,8 @@ set (LOCKSCREEN_SOURCES
LockScreenShield.cpp
LockScreenShieldFactory.cpp
LockScreenPanel.cpp
+ LockScreenAcceleratorController.cpp
+ LockScreenAccelerators.cpp
ScreenSaverDBusManager.cpp
UserAuthenticatorPam.cpp
UserPromptView.cpp
diff --git a/lockscreen/LockScreenAbstractShield.h b/lockscreen/LockScreenAbstractShield.h
index 52f063e84..d974f1f5c 100644
--- a/lockscreen/LockScreenAbstractShield.h
+++ b/lockscreen/LockScreenAbstractShield.h
@@ -25,6 +25,7 @@
#include <UnityCore/Indicators.h>
#include "unity-shared/MockableBaseWindow.h"
+#include "LockScreenAccelerators.h"
namespace unity
{
@@ -34,12 +35,13 @@ namespace lockscreen
class AbstractShield : public MockableBaseWindow
{
public:
- AbstractShield(session::Manager::Ptr const& session, indicator::Indicators::Ptr const& indicators, int monitor_num, bool is_primary)
+ AbstractShield(session::Manager::Ptr const& session, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor_num, bool is_primary)
: MockableBaseWindow("Unity Lockscreen")
, primary(is_primary)
, monitor(monitor_num)
, session_manager_(session)
, indicators_(indicators)
+ , accelerators_(accelerators)
{}
nux::Property<bool> primary;
@@ -47,7 +49,7 @@ public:
using MockableBaseWindow::RemoveLayout;
virtual bool IsIndicatorOpen() const = 0;
- virtual void CheckCapsLockPrompt() = 0;
+ virtual void ActivatePanel() = 0;
sigc::signal<void, int, int> grab_motion;
sigc::signal<void, unsigned long, unsigned long> grab_key;
@@ -55,6 +57,7 @@ public:
protected:
session::Manager::Ptr session_manager_;
indicator::Indicators::Ptr indicators_;
+ Accelerators::Ptr accelerators_;
};
} // lockscreen
diff --git a/lockscreen/LockScreenAcceleratorController.cpp b/lockscreen/LockScreenAcceleratorController.cpp
new file mode 100644
index 000000000..298d8def9
--- /dev/null
+++ b/lockscreen/LockScreenAcceleratorController.cpp
@@ -0,0 +1,146 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 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: William Hua <william.hua@canonical.com>
+ */
+
+#include "LockScreenAcceleratorController.h"
+
+#include <UnityCore/GLibDBusProxy.h>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+namespace
+{
+const char* const MEDIA_KEYS_SCHEMA = "org.gnome.settings-daemon.plugins.media-keys";
+const char* const MEDIA_KEYS_KEY_VOLUME_MUTE = "volume-mute";
+const char* const MEDIA_KEYS_KEY_VOLUME_DOWN = "volume-down";
+const char* const MEDIA_KEYS_KEY_VOLUME_UP = "volume-up";
+const char* const INPUT_SWITCH_SCHEMA = "org.gnome.desktop.wm.keybindings";
+const char* const INPUT_SWITCH_KEY_PREVIOUS_SOURCE = "switch-input-source-backward";
+const char* const INPUT_SWITCH_KEY_NEXT_SOURCE = "switch-input-source";
+
+const char* const INDICATOR_INTERFACE_ACTIONS = "org.gtk.Actions";
+const char* const INDICATOR_METHOD_ACTIVATE = "Activate";
+const char* const INDICATOR_SOUND_BUS_NAME = "com.canonical.indicator.sound";
+const char* const INDICATOR_SOUND_OBJECT_PATH = "/com/canonical/indicator/sound";
+const char* const INDICATOR_SOUND_ACTION_MUTE = "mute";
+const char* const INDICATOR_SOUND_ACTION_SCROLL = "scroll";
+const char* const INDICATOR_KEYBOARD_BUS_NAME = "com.canonical.indicator.keyboard";
+const char* const INDICATOR_KEYBOARD_OBJECT_PATH = "/com/canonical/indicator/keyboard";
+const char* const INDICATOR_KEYBOARD_ACTION_SCROLL = "locked_scroll";
+
+void ActivateIndicator(std::string const& bus_name,
+ std::string const& object_path,
+ std::string const& action_name,
+ glib::Variant const& parameters = glib::Variant())
+{
+ GVariantBuilder builder;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("(sava{sv})"));
+ g_variant_builder_add(&builder, "s", action_name.c_str());
+
+ if (parameters)
+ g_variant_builder_add_parsed(&builder, "[%v]", static_cast<GVariant*>(parameters));
+ else
+ g_variant_builder_add_parsed(&builder, "@av []");
+
+ g_variant_builder_add_parsed(&builder, "@a{sv} []");
+
+ auto proxy = std::make_shared<glib::DBusProxy>(bus_name, object_path, INDICATOR_INTERFACE_ACTIONS);
+ proxy->CallBegin(INDICATOR_METHOD_ACTIVATE, g_variant_builder_end(&builder), [proxy] (GVariant*, glib::Error const&) {});
+}
+
+void MuteIndicatorSound()
+{
+ ActivateIndicator(INDICATOR_SOUND_BUS_NAME,
+ INDICATOR_SOUND_OBJECT_PATH,
+ INDICATOR_SOUND_ACTION_MUTE);
+}
+
+void ScrollIndicatorSound(int offset)
+{
+ ActivateIndicator(INDICATOR_SOUND_BUS_NAME,
+ INDICATOR_SOUND_OBJECT_PATH,
+ INDICATOR_SOUND_ACTION_SCROLL,
+ g_variant_new_int32(offset));
+}
+
+void ScrollIndicatorKeyboard(int offset)
+{
+ ActivateIndicator(INDICATOR_KEYBOARD_BUS_NAME,
+ INDICATOR_KEYBOARD_OBJECT_PATH,
+ INDICATOR_KEYBOARD_ACTION_SCROLL,
+ g_variant_new_int32(-offset));
+}
+} // namespace
+
+AcceleratorController::AcceleratorController()
+ : accelerators_(new Accelerators)
+{
+ auto settings = glib::Object<GSettings>(g_settings_new(MEDIA_KEYS_SCHEMA));
+
+ auto accelerator = std::make_shared<Accelerator>(glib::String(g_settings_get_string(settings, MEDIA_KEYS_KEY_VOLUME_MUTE)));
+ accelerator->activated.connect(std::function<void ()>(MuteIndicatorSound));
+ accelerators_->Add(accelerator);
+
+ accelerator = std::make_shared<Accelerator>(glib::String(g_settings_get_string(settings, MEDIA_KEYS_KEY_VOLUME_DOWN)));
+ accelerator->activated.connect(std::bind(ScrollIndicatorSound, -1));
+ accelerators_->Add(accelerator);
+
+ accelerator = std::make_shared<Accelerator>(glib::String(g_settings_get_string(settings, MEDIA_KEYS_KEY_VOLUME_UP)));
+ accelerator->activated.connect(std::bind(ScrollIndicatorSound, +1));
+ accelerators_->Add(accelerator);
+
+ settings = glib::Object<GSettings>(g_settings_new(INPUT_SWITCH_SCHEMA));
+
+ auto variant = glib::Variant(g_settings_get_value(settings, INPUT_SWITCH_KEY_PREVIOUS_SOURCE), glib::StealRef());
+
+ if (g_variant_n_children(variant) > 0)
+ {
+ const gchar* string;
+
+ g_variant_get_child(variant, 0, "&s", &string);
+
+ accelerator = std::make_shared<Accelerator>(string);
+ accelerator->activated.connect(std::bind(ScrollIndicatorKeyboard, -1));
+ accelerators_->Add(accelerator);
+ }
+
+ variant = glib::Variant(g_settings_get_value(settings, INPUT_SWITCH_KEY_NEXT_SOURCE), glib::StealRef());
+
+ if (g_variant_n_children(variant) > 0)
+ {
+ const gchar* string;
+
+ g_variant_get_child(variant, 0, "&s", &string);
+
+ accelerator = std::make_shared<Accelerator>(string);
+ accelerator->activated.connect(std::bind(ScrollIndicatorKeyboard, +1));
+ accelerators_->Add(accelerator);
+ }
+}
+
+Accelerators::Ptr const& AcceleratorController::GetAccelerators() const
+{
+ return accelerators_;
+}
+
+} // lockscreen namespace
+} // unity namespace
diff --git a/lockscreen/LockScreenAcceleratorController.h b/lockscreen/LockScreenAcceleratorController.h
new file mode 100644
index 000000000..a69b245eb
--- /dev/null
+++ b/lockscreen/LockScreenAcceleratorController.h
@@ -0,0 +1,46 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 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: William Hua <william.hua@canonical.com>
+ */
+
+#ifndef UNITY_LOCKSCREEN_ACCELERATOR_CONTROLLER
+#define UNITY_LOCKSCREEN_ACCELERATOR_CONTROLLER
+
+#include "LockScreenAccelerators.h"
+
+namespace unity
+{
+namespace lockscreen
+{
+
+class AcceleratorController
+{
+public:
+ typedef std::shared_ptr<AcceleratorController> Ptr;
+
+ AcceleratorController();
+
+ Accelerators::Ptr const& GetAccelerators() const;
+
+private:
+ Accelerators::Ptr accelerators_;
+};
+
+} // lockscreen namespace
+} // unity namespace
+
+#endif // UNITY_LOCKSCREEN_ACCELERATOR_CONTROLLER
diff --git a/lockscreen/LockScreenAccelerators.cpp b/lockscreen/LockScreenAccelerators.cpp
new file mode 100644
index 000000000..f3f4a4bc7
--- /dev/null
+++ b/lockscreen/LockScreenAccelerators.cpp
@@ -0,0 +1,528 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 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: William Hua <william.hua@canonical.com>
+ */
+
+#include "LockScreenAccelerators.h"
+
+#include <NuxGraphics/Events.h>
+#include <gtk/gtk.h>
+
+namespace unity
+{
+namespace lockscreen
+{
+
+enum class PressedState : unsigned int
+{
+ NothingPressed = 0x00,
+ LeftShiftPressed = 0x01,
+ LeftControlPressed = 0x02,
+ LeftAltPressed = 0x04,
+ LeftSuperPressed = 0x08,
+ RightShiftPressed = 0x10,
+ RightControlPressed = 0x20,
+ RightAltPressed = 0x40,
+ RightSuperPressed = 0x80
+};
+
+PressedState operator~(PressedState const& first)
+{
+ return static_cast<PressedState>(~static_cast<unsigned int>(first));
+}
+
+PressedState operator&(PressedState const& first, PressedState const& second)
+{
+ return static_cast<PressedState>(static_cast<unsigned int>(first) & static_cast<unsigned int>(second));
+}
+
+PressedState operator|(PressedState const& first, PressedState const& second)
+{
+ return static_cast<PressedState>(static_cast<unsigned int>(first) | static_cast<unsigned int>(second));
+}
+
+PressedState& operator&=(PressedState& first, PressedState const& second)
+{
+ return first = first & second;
+}
+
+PressedState& operator|=(PressedState& first, PressedState const& second)
+{
+ return first = first | second;
+}
+
+namespace
+{
+unsigned int KeysymToModifier(unsigned int keysym)
+{
+ switch (keysym)
+ {
+ case GDK_KEY_Shift_L:
+ case GDK_KEY_Shift_R:
+ return nux::KEY_MODIFIER_SHIFT;
+ case GDK_KEY_Control_L:
+ case GDK_KEY_Control_R:
+ return nux::KEY_MODIFIER_CTRL;
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Alt_L:
+ case GDK_KEY_Alt_R:
+ return nux::KEY_MODIFIER_ALT;
+ case GDK_KEY_Super_L:
+ case GDK_KEY_Super_R:
+ return nux::KEY_MODIFIER_SUPER;
+ }
+
+ return 0;
+}
+
+PressedState KeysymToPressedState(unsigned int keysym)
+{
+ switch (keysym)
+ {
+ case GDK_KEY_Shift_L:
+ return PressedState::LeftShiftPressed;
+ case GDK_KEY_Shift_R:
+ return PressedState::RightShiftPressed;
+ case GDK_KEY_Control_L:
+ return PressedState::LeftControlPressed;
+ case GDK_KEY_Control_R:
+ return PressedState::RightControlPressed;
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Alt_L:
+ return PressedState::LeftAltPressed;
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Alt_R:
+ return PressedState::RightAltPressed;
+ case GDK_KEY_Super_L:
+ return PressedState::LeftSuperPressed;
+ case GDK_KEY_Super_R:
+ return PressedState::RightSuperPressed;
+ }
+
+ return PressedState::NothingPressed;
+}
+
+unsigned int KeysymToMirrorKeysym(unsigned int keysym)
+{
+ switch (keysym)
+ {
+ case GDK_KEY_Shift_L:
+ return GDK_KEY_Shift_R;
+ case GDK_KEY_Shift_R:
+ return GDK_KEY_Shift_L;
+ case GDK_KEY_Control_L:
+ return GDK_KEY_Control_R;
+ case GDK_KEY_Control_R:
+ return GDK_KEY_Control_L;
+ case GDK_KEY_Meta_L:
+ return GDK_KEY_Meta_R;
+ case GDK_KEY_Meta_R:
+ return GDK_KEY_Meta_L;
+ case GDK_KEY_Alt_L:
+ return GDK_KEY_Alt_R;
+ case GDK_KEY_Alt_R:
+ return GDK_KEY_Alt_L;
+ case GDK_KEY_Super_L:
+ return GDK_KEY_Super_R;
+ case GDK_KEY_Super_R:
+ return GDK_KEY_Super_L;
+ }
+
+ return 0;
+}
+} // namespace
+
+Accelerator::Accelerator(unsigned int keysym,
+ unsigned int keycode,
+ unsigned int modifiers)
+ : keysym_(keysym)
+ , keycode_(keycode)
+ , modifiers_(modifiers)
+ , active_(true)
+ , activated_(false)
+{
+}
+
+Accelerator::Accelerator(std::string const& string)
+ : keysym_(0)
+ , keycode_(0)
+ , modifiers_(0)
+ , active_(true)
+ , activated_(false)
+{
+ guint keysym;
+ guint* keycodes;
+ GdkModifierType modifiers;
+
+ gtk_accelerator_parse_with_keycode(string.c_str(), &keysym, &keycodes, &modifiers);
+
+ /* gtk_accelerator_parse_with_keycode() might fail if the key is not in the
+ * default key map. gtk_accelerator_parse() might succeed in this case. */
+ if (keysym == 0 && keycodes == NULL && modifiers == 0)
+ gtk_accelerator_parse(string.c_str(), &keysym, &modifiers);
+
+ keysym_ = keysym;
+
+ if (keycodes != NULL)
+ {
+ keycode_ = keycodes[0];
+ g_free(keycodes);
+ }
+
+ if (modifiers & GDK_SHIFT_MASK)
+ modifiers_ |= nux::KEY_MODIFIER_SHIFT;
+ if (modifiers & GDK_CONTROL_MASK)
+ modifiers_ |= nux::KEY_MODIFIER_CTRL;
+ if ((modifiers & GDK_MOD1_MASK) || (modifiers & GDK_META_MASK))
+ modifiers_ |= nux::KEY_MODIFIER_ALT;
+ if (modifiers & GDK_SUPER_MASK)
+ modifiers_ |= nux::KEY_MODIFIER_SUPER;
+}
+
+bool Accelerator::operator==(Accelerator const& accelerator) const
+{
+ return keysym_ == accelerator.keysym_
+ && keycode_ == accelerator.keycode_
+ && modifiers_ == accelerator.modifiers_;
+}
+
+bool Accelerator::KeyPressActivate()
+{
+ activated.emit();
+ activated_ = true;
+
+ return true;
+}
+
+bool Accelerator::KeyReleaseActivate()
+{
+ activated.emit();
+ activated_ = false;
+
+ return true;
+}
+
+bool Accelerator::HandleKeyPress(unsigned int keysym,
+ unsigned int modifiers,
+ PressedState pressed_state)
+{
+ auto is_modifier_only = keysym_ == 0 && keycode_ == 0 && modifiers_ != 0;
+ auto is_modifier_keysym = KeysymToModifier(keysym_);
+ auto modifier = KeysymToModifier(keysym);
+
+ if (modifiers == 0)
+ {
+ /* We're pressing a key when no other key is pressed. We can reset this
+ * accelerator back to its original enabled state. */
+ active_ = true;
+ activated_ = false;
+ }
+
+ if (!active_)
+ return false;
+
+ /* We need to cancel modifier-only accelerators in some cases. For example,
+ * we should cancel a Ctrl+Alt accelerator if Ctrl+Alt+T is pressed. */
+ if (is_modifier_only || is_modifier_keysym)
+ {
+ if (!modifier)
+ {
+ /* We pressed a non-modifier key for a modifier-only accelerator. */
+ active_ = false;
+ return false;
+ }
+ else if (keysym != keysym_ && (modifiers_ & modifier) == 0)
+ {
+ /* We pressed a modifier key that isn't the keysym and isn't one of the
+ * modifiers. */
+ active_ = false;
+ return false;
+ }
+ }
+ else if (!modifier)
+ {
+ /* We expect a non-modifier key to activate and one was pressed. */
+ if (modifiers == modifiers_)
+ {
+ /* The modifiers match. Check if the keysyms match. */
+ if (keysym == keysym_)
+ return KeyPressActivate();
+ else
+ {
+ /* Otherwise, check if the keycodes match. Maybe the accelerator
+ * specifies a particular key code, or the keyboard layout changed. For
+ * example, if the accelerator is Ctrl+A and the user switches from a
+ * QWERTY to an AZERTY layout, we should accept Ctrl+Q so the user can
+ * cycle through the entire list of keyboard layouts. */
+
+ GdkKeymapKey* key;
+ gint keys;
+
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keysym, &key, &keys))
+ {
+ for (auto i = 0; i < keys; i++)
+ {
+ if (key[i].keycode == keycode_)
+ {
+ g_free(key);
+
+ return KeyPressActivate();
+ }
+ }
+
+ g_free(key);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool Accelerator::HandleKeyRelease(unsigned int keysym,
+ unsigned int modifiers,
+ PressedState pressed_state)
+{
+ auto is_modifier_only = keysym_ == 0 && keycode_ == 0 && modifiers_ != 0;
+ auto is_modifier_keysym = KeysymToModifier(keysym_);
+ auto modifier = KeysymToModifier(keysym);
+
+ /* Don't activate on key release if we were activated on a key press. */
+ if (!active_ || activated_)
+ return false;
+
+ /* Check if the keysyms match. */
+ if (keysym == keysym_)
+ {
+ if (KeysymToModifier(keysym) == 0)
+ {
+ /* We released a non-modifier key. */
+ if (modifiers == modifiers_)
+ return KeyReleaseActivate();
+ }
+ else
+ {
+ /* We released a modifier key. */
+ auto mirror_keysym = KeysymToMirrorKeysym(keysym);
+ auto is_mirror_pressed = (pressed_state & KeysymToPressedState(mirror_keysym)) != PressedState::NothingPressed;
+
+ /* Ctrl+Shift_R is different from Ctrl+Shift+Shift_R, so we must detect
+ * if the mirror key was pressed or not. */
+ if (is_mirror_pressed)
+ {
+ /* The mirrored modifier is pressed. */
+ if (modifiers == modifiers_)
+ return KeyReleaseActivate();
+ }
+ else
+ {
+ /* The mirrored modifier wasn't pressed. Compare modifiers without it. */
+ if ((modifiers & ~KeysymToModifier(mirror_keysym)) == modifiers_)
+ return KeyReleaseActivate();
+ }
+ }
+ }
+
+ if (is_modifier_only || is_modifier_keysym)
+ {
+ if (modifier)
+ {
+ /* We released a modifier key for a modifier-only accelerator. */
+
+ if (is_modifier_only)
+ {
+ /* The accelerator has no keysym or keycode. */
+
+ /* TODO: Normally we would activate here, but compiz is intercepting
+ * this case and handling it. This is bad because now we can't do
+ * anything here. Otherwise we'll do the same action twice. */
+ if (modifiers == modifiers_)
+ return false;
+ }
+ else
+ {
+ /* The accelerator has a modifier keysym. */
+ auto is_keysym_pressed = (pressed_state & KeysymToPressedState(keysym_)) != PressedState::NothingPressed;
+
+ if (is_keysym_pressed)
+ {
+ auto mirror_keysym = KeysymToMirrorKeysym(keysym_);
+ auto is_mirror_pressed = (pressed_state & KeysymToPressedState(mirror_keysym)) != PressedState::NothingPressed;
+
+ /* Ctrl+Shift_R is different from Ctrl+Shift+Shift_R, so we must detect
+ * if the mirror key was pressed or not. */
+ if (is_mirror_pressed)
+ {
+ /* The mirrored modifier is pressed. */
+ if (modifiers == modifiers_)
+ return KeyReleaseActivate();
+ }
+ else
+ {
+ /* The mirrored modifier wasn't pressed. Compare modifiers without it. */
+ if ((modifiers & ~KeysymToModifier(mirror_keysym)) == modifiers_)
+ return KeyReleaseActivate();
+ }
+ }
+ }
+ }
+ }
+ else if (keycode_ != 0 && modifiers == modifiers_)
+ {
+ /* Otherwise, check if the keycodes match. Maybe the accelerator
+ * specifies a particular key code, or the keyboard layout changed. For
+ * example, if the accelerator is Ctrl+A and the user switches from a
+ * QWERTY to an AZERTY layout, we should accept Ctrl+Q so the user can
+ * cycle through the entire list of keyboard layouts. */
+
+ GdkKeymapKey* key;
+ gint keys;
+
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keysym, &key, &keys))
+ {
+ for (auto i = 0; i < keys; i++)
+ {
+ if (key[i].keycode == keycode_)
+ {
+ g_free(key);
+
+ return KeyReleaseActivate();
+ }
+ }
+
+ g_free(key);
+ }
+ }
+
+ return false;
+}
+
+Accelerators::Accelerators()
+ : pressed_state_(PressedState::NothingPressed)
+{
+}
+
+void Accelerators::Clear()
+{
+ accelerators_.clear();
+}
+
+void Accelerators::Add(Accelerator::Ptr const& accelerator)
+{
+ accelerators_.push_back(accelerator);
+}
+
+void Accelerators::Remove(Accelerator::Ptr const& accelerator)
+{
+ accelerators_.erase(std::remove(accelerators_.begin(), accelerators_.end(), accelerator), accelerators_.end());
+}
+
+bool Accelerators::HandleKeyPress(unsigned int keysym,
+ unsigned int modifiers)
+{
+ modifiers &= nux::KEY_MODIFIER_SHIFT
+ | nux::KEY_MODIFIER_CTRL
+ | nux::KEY_MODIFIER_ALT
+ | nux::KEY_MODIFIER_SUPER;
+
+ switch (keysym)
+ {
+ case GDK_KEY_Shift_L:
+ pressed_state_ |= PressedState::LeftShiftPressed;
+ break;
+ case GDK_KEY_Shift_R:
+ pressed_state_ |= PressedState::RightShiftPressed;
+ break;
+ case GDK_KEY_Control_L:
+ pressed_state_ |= PressedState::LeftControlPressed;
+ break;
+ case GDK_KEY_Control_R:
+ pressed_state_ |= PressedState::RightControlPressed;
+ break;
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Alt_L:
+ pressed_state_ |= PressedState::LeftAltPressed;
+ break;
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Alt_R:
+ pressed_state_ |= PressedState::RightAltPressed;
+ break;
+ case GDK_KEY_Super_L:
+ pressed_state_ |= PressedState::LeftSuperPressed;
+ break;
+ case GDK_KEY_Super_R:
+ pressed_state_ |= PressedState::RightSuperPressed;
+ break;
+ }
+
+ auto handled = false;
+
+ for (auto& accelerator : accelerators_)
+ handled = accelerator->HandleKeyPress(keysym, modifiers, pressed_state_) || handled;
+
+ return handled;
+}
+
+bool Accelerators::HandleKeyRelease(unsigned int keysym,
+ unsigned int modifiers)
+{
+ modifiers &= nux::KEY_MODIFIER_SHIFT
+ | nux::KEY_MODIFIER_CTRL
+ | nux::KEY_MODIFIER_ALT
+ | nux::KEY_MODIFIER_SUPER;
+
+ auto handled = false;
+
+ for (auto& accelerator : accelerators_)
+ handled = accelerator->HandleKeyRelease(keysym, modifiers, pressed_state_) || handled;
+
+ switch (keysym)
+ {
+ case GDK_KEY_Shift_L:
+ pressed_state_ &= ~PressedState::LeftShiftPressed;
+ break;
+ case GDK_KEY_Shift_R:
+ pressed_state_ &= ~PressedState::RightShiftPressed;
+ break;
+ case GDK_KEY_Control_L:
+ pressed_state_ &= ~PressedState::LeftControlPressed;
+ break;
+ case GDK_KEY_Control_R:
+ pressed_state_ &= ~PressedState::RightControlPressed;
+ break;
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Alt_L:
+ pressed_state_ &= ~PressedState::LeftAltPressed;
+ break;
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Alt_R:
+ pressed_state_ &= ~PressedState::RightAltPressed;
+ break;
+ case GDK_KEY_Super_L:
+ pressed_state_ &= ~PressedState::LeftSuperPressed;
+ break;
+ case GDK_KEY_Super_R:
+ pressed_state_ &= ~PressedState::RightSuperPressed;
+ break;
+ }
+
+ return handled;
+}
+
+} // lockscreen namespace
+} // unity namespace
diff --git a/lockscreen/LockScreenAccelerators.h b/lockscreen/LockScreenAccelerators.h
new file mode 100644
index 000000000..7e8408252
--- /dev/null
+++ b/lockscreen/LockScreenAccelerators.h
@@ -0,0 +1,94 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2014 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: William Hua <william.hua@canonical.com>
+ */
+
+#ifndef UNITY_LOCKSCREEN_ACCELERATORS
+#define UNITY_LOCKSCREEN_ACCELERATORS
+
+#include <memory>
+#include <sigc++/signal.h>
+#include <vector>
+
+
+namespace unity
+{
+namespace lockscreen
+{
+
+enum class PressedState : unsigned int;
+
+class Accelerator
+{
+public:
+ typedef std::shared_ptr<Accelerator> Ptr;
+
+ Accelerator(unsigned int keysym, unsigned int keycode, unsigned int modifiers);
+ explicit Accelerator(std::string const& string);
+
+ bool operator==(Accelerator const& accelerator) const;
+
+ sigc::signal<void> activated;
+
+private:
+ bool KeyPressActivate();
+ bool KeyReleaseActivate();
+
+ bool HandleKeyPress(unsigned int keysym,
+ unsigned int modifiers,
+ PressedState pressed_state);
+ bool HandleKeyRelease(unsigned int keysym,
+ unsigned int modifiers,
+ PressedState pressed_state);
+
+ unsigned int keysym_;
+ unsigned int keycode_;
+ unsigned int modifiers_;
+
+ bool active_;
+ bool activated_;
+
+ friend class Accelerators;
+};
+
+class Accelerators
+{
+public:
+ typedef std::shared_ptr<Accelerators> Ptr;
+
+ Accelerators();
+
+ void Clear();
+
+ void Add(Accelerator::Ptr const& accelerator);
+ void Remove(Accelerator::Ptr const& accelerator);
+
+ bool HandleKeyPress(unsigned int keysym,
+ unsigned int modifiers);
+ bool HandleKeyRelease(unsigned int keysym,
+ unsigned int modifiers);
+
+private:
+ std::vector<Accelerator::Ptr> accelerators_;
+
+ PressedState pressed_state_;
+};
+
+} // lockscreen namespace
+} // unity namespace
+
+#endif // UNITY_LOCKSCREEN_ACCELERATORS
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 0314cf6fd..34fddaead 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -113,6 +113,7 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
shields_.clear();
upstart_wrapper_->Emit("desktop-unlock");
+ accelerator_controller_.reset();
indicators_.reset();
}
else if (!prompt_activation_)
@@ -147,6 +148,12 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
});
}
+void Controller::ActivatePanel()
+{
+ if (primary_shield_.IsValid())
+ primary_shield_->ActivatePanel();
+}
+
void Controller::ResetPostLockScreenSaver()
{
screensaver_post_lock_timeout_.reset();
@@ -164,7 +171,6 @@ void Controller::OnPrimaryShieldMotion(int x, int y)
primary_shield_->primary = false;
primary_shield_ = shield;
- primary_shield_->CheckCapsLockPrompt();
shield->primary = true;
nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
@@ -193,7 +199,7 @@ void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
if (i >= shields_size)
{
- shield = shield_factory_->CreateShield(session_manager_, indicators_, i, i == primary);
+ shield = shield_factory_->CreateShield(session_manager_, indicators_, accelerator_controller_->GetAccelerators(), i, i == primary);
is_new = true;
}
@@ -397,6 +403,12 @@ void Controller::LockScreen()
indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
upstart_wrapper_->Emit("desktop-lock");
+ accelerator_controller_ = std::make_shared<AcceleratorController>();
+ auto activate_key = WindowManager::Default().activate_indicators_key();
+ auto accelerator = std::make_shared<Accelerator>(activate_key.second, 0, activate_key.first);
+ accelerator->activated.connect(std::bind(std::mem_fn(&Controller::ActivatePanel), this));
+ accelerator_controller_->GetAccelerators()->Add(accelerator);
+
ShowShields();
}
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
index 1c43fa49a..8e53269b7 100644
--- a/lockscreen/LockScreenController.h
+++ b/lockscreen/LockScreenController.h
@@ -25,6 +25,7 @@
#include <UnityCore/GLibSource.h>
#include "LockScreenShieldFactory.h"
+#include "LockScreenAcceleratorController.h"
#include "ScreenSaverDBusManager.h"
#include "unity-shared/BackgroundEffectHelper.h"
#include "unity-shared/UpstartWrapper.h"
@@ -60,6 +61,7 @@ private:
void BlankWindowGrabEnable(bool grab);
void SimulateActivity();
void ResetPostLockScreenSaver();
+ void ActivatePanel();
void OnLockRequested(bool prompt);
void OnUnlockRequested();
@@ -74,6 +76,7 @@ private:
DBusManager::Ptr dbus_manager_;
session::Manager::Ptr session_manager_;
indicator::Indicators::Ptr indicators_;
+ AcceleratorController::Ptr accelerator_controller_;
UpstartWrapper::Ptr upstart_wrapper_;
ShieldFactoryInterface::Ptr shield_factory_;
@@ -99,4 +102,4 @@ private:
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/lockscreen/LockScreenPanel.cpp b/lockscreen/LockScreenPanel.cpp
index c3b5a934d..71dc3397e 100644
--- a/lockscreen/LockScreenPanel.cpp
+++ b/lockscreen/LockScreenPanel.cpp
@@ -21,7 +21,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <Nux/HLayout.h>
-#include <UnityCore/Variant.h>
#include "LockScreenSettings.h"
#include "panel/PanelIndicatorsView.h"
@@ -39,30 +38,6 @@ namespace lockscreen
namespace
{
const RawPixel PADDING = 5_em;
-
-const std::string MEDIA_KEYS_SCHEMA = "org.gnome.settings-daemon.plugins.media-keys";
-const std::string MEDIA_KEYS_VOLUME_MUTE = "volume-mute";
-const std::string MEDIA_KEYS_VOLUME_DOWN = "volume-down";
-const std::string MEDIA_KEYS_VOLUME_UP = "volume-up";
-const std::string INPUT_SWITCH_SCHEMA = "org.gnome.desktop.wm.keybindings";
-const std::string INPUT_SWITCH_PREVIOUS = "switch-input-source-backward";
-const std::string INPUT_SWITCH_NEXT = "switch-input-source";
-
-const std::string INDICATOR_KEYBOARD_BUS_NAME = "com.canonical.indicator.keyboard";
-const std::string INDICATOR_KEYBOARD_OBJECT_PATH = "/com/canonical/indicator/keyboard";
-const std::string INDICATOR_SOUND_BUS_NAME = "com.canonical.indicator.sound";
-const std::string INDICATOR_SOUND_OBJECT_PATH = "/com/canonical/indicator/sound";
-const std::string INDICATOR_ACTION_INTERFACE = "org.gtk.Actions";
-
-const std::string INDICATOR_KEYBOARD_ACTION_SCROLL = "locked_scroll";
-const std::string INDICATOR_SOUND_ACTION_SCROLL = "scroll";
-const std::string INDICATOR_SOUND_ACTION_MUTE = "mute";
-
-const unsigned int MODIFIERS = nux::KEY_MODIFIER_SHIFT |
- nux::KEY_MODIFIER_CAPS_LOCK |
- nux::KEY_MODIFIER_CTRL |
- nux::KEY_MODIFIER_ALT |
- nux::KEY_MODIFIER_SUPER;
}
using namespace indicator;
@@ -74,8 +49,6 @@ Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::
, monitor(monitor_)
, indicators_(indicators)
, needs_geo_sync_(true)
- , media_key_settings_(g_settings_new(MEDIA_KEYS_SCHEMA.c_str()))
- , input_switch_settings_(g_settings_new(INPUT_SWITCH_SCHEMA.c_str()))
{
double scale = unity::Settings::Instance().em(monitor)->DPIScale();
auto* layout = new nux::HLayout();
@@ -114,11 +87,6 @@ Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::
BuildTexture();
QueueRelayout();
});
-
- ParseAccelerators();
-
- key_down.connect(sigc::mem_fun(this, &Panel::OnKeyDown));
- key_up.connect(sigc::mem_fun(this, &Panel::OnKeyUp));
}
void Panel::BuildTexture()
@@ -180,12 +148,6 @@ void Panel::OnEntryActivateRequest(std::string const& entry_id)
indicators_view_->ActivateEntry(entry_id, 0);
}
-void Panel::ActivateFirst()
-{
- if (GetInputEventSensitivity())
- indicators_view_->ActivateIfSensitive();
-}
-
void Panel::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&)
{
if (!GetInputEventSensitivity() || (!panel.empty() && panel != GetPanelName()))
@@ -254,210 +216,15 @@ void Panel::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
}
}
-Panel::Accelerator Panel::ParseAcceleratorString(std::string const& string) const
-{
- guint gtk_key;
- GdkModifierType gtk_modifiers;
- gtk_accelerator_parse(string.c_str(), &gtk_key, &gtk_modifiers);
-
- unsigned int nux_key = gtk_key;
- unsigned int nux_modifiers = 0;
-
- if (gtk_modifiers & GDK_SHIFT_MASK)
- nux_modifiers |= nux::KEY_MODIFIER_SHIFT;
- if (gtk_modifiers & GDK_LOCK_MASK)
- nux_modifiers |= nux::KEY_MODIFIER_CAPS_LOCK;
- if (gtk_modifiers & GDK_CONTROL_MASK)
- nux_modifiers |= nux::KEY_MODIFIER_CTRL;
- if (gtk_modifiers & GDK_MOD1_MASK)
- nux_modifiers |= nux::KEY_MODIFIER_ALT;
- if (gtk_modifiers & GDK_SUPER_MASK)
- nux_modifiers |= nux::KEY_MODIFIER_SUPER;
-
- return std::make_pair(nux_modifiers, nux_key);
-}
-
-void Panel::ParseAccelerators()
-{
- activate_indicator_ = WindowManager::Default().activate_indicators_key();
- volume_mute_ = ParseAcceleratorString(glib::String(g_settings_get_string(media_key_settings_, MEDIA_KEYS_VOLUME_MUTE.c_str())));
- volume_down_ = ParseAcceleratorString(glib::String(g_settings_get_string(media_key_settings_, MEDIA_KEYS_VOLUME_DOWN.c_str())));
- volume_up_ = ParseAcceleratorString(glib::String(g_settings_get_string(media_key_settings_, MEDIA_KEYS_VOLUME_UP.c_str())));
-
- auto variant = glib::Variant(g_settings_get_value(input_switch_settings_, INPUT_SWITCH_PREVIOUS.c_str()), glib::StealRef());
-
- if (g_variant_n_children(variant) > 0)
- {
- const gchar *accelerator;
- g_variant_get_child(variant, 0, "&s", &accelerator);
- previous_source_ = ParseAcceleratorString(accelerator);
- }
- else
- previous_source_ = std::make_pair(0, 0);
-
- variant = glib::Variant(g_settings_get_value(input_switch_settings_, INPUT_SWITCH_NEXT.c_str()), glib::StealRef());
-
- if (g_variant_n_children(variant) > 0)
- {
- const gchar *accelerator;
- g_variant_get_child(variant, 0, "&s", &accelerator);
- next_source_ = ParseAcceleratorString(accelerator);
- }
- else
- next_source_ = std::make_pair(0, 0);
-}
-
-bool Panel::WillHandleKeyEvent(unsigned int event_type, unsigned long key_sym, unsigned long modifiers)
-{
- auto is_press = event_type == nux::EVENT_KEY_DOWN;
-
- /* If we're just pressing a key, and no modifiers are pressed, then
- * we can start accepting new actions again. */
- if (is_press && (modifiers & MODIFIERS) == 0)
- last_action_ = std::make_pair(0, 0);
-
- return IsMatch(is_press, key_sym, modifiers, activate_indicator_) ||
- IsMatch(is_press, key_sym, modifiers, volume_mute_) ||
- IsMatch(is_press, key_sym, modifiers, volume_down_) ||
- IsMatch(is_press, key_sym, modifiers, volume_up_) ||
- IsMatch(is_press, key_sym, modifiers, previous_source_) ||
- IsMatch(is_press, key_sym, modifiers, next_source_);
-}
-
bool Panel::InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char*)
{
return true;
}
-bool Panel::IsMatch(bool is_press,
- unsigned int key_sym,
- unsigned int state,
- Accelerator const& accelerator) const
+void Panel::ActivatePanel()
{
- /* Do the easy check, just compare key codes and modifiers.
- * TODO: Check permutations of modifier-only shortcuts. */
- return key_sym == accelerator.second && (state & MODIFIERS) == accelerator.first;
-}
-
-void Panel::OnKeyDown(unsigned long event,
- unsigned long key_sym,
- unsigned long state,
- const char* text,
- unsigned short repeat)
-{
- if (IsMatch(true, key_sym, state, activate_indicator_))
- {
- ActivateFirst();
- last_action_ = activate_indicator_;
- }
- else if (IsMatch(true, key_sym, state, volume_mute_))
- {
- ActivateSoundAction(INDICATOR_SOUND_ACTION_MUTE);
- last_action_ = volume_mute_;
- }
- else if (IsMatch(true, key_sym, state, volume_down_))
- {
- ActivateSoundAction(INDICATOR_SOUND_ACTION_SCROLL, g_variant_new_int32(-1));
- last_action_ = volume_down_;
- }
- else if (IsMatch(true, key_sym, state, volume_up_))
- {
- ActivateSoundAction(INDICATOR_SOUND_ACTION_SCROLL, g_variant_new_int32(+1));
- last_action_ = volume_up_;
- }
- else if (IsMatch(true, key_sym, state, previous_source_))
- {
- ActivateKeyboardAction(INDICATOR_KEYBOARD_ACTION_SCROLL, g_variant_new_int32(-1));
- last_action_ = previous_source_;
- }
- else if (IsMatch(true, key_sym, state, next_source_))
- {
- ActivateKeyboardAction(INDICATOR_KEYBOARD_ACTION_SCROLL, g_variant_new_int32(+1));
- last_action_ = next_source_;
- }
-}
-
-void Panel::OnKeyUp(unsigned int key_sym,
- unsigned long key_code,
- unsigned long state)
-{
- /* We only want to act if we didn't activate the action on key
- * down. Once we see the key up, we can start accepting actions
- * again. */
-
- if (IsMatch(false, key_sym, state, activate_indicator_))
- {
- if (last_action_ != activate_indicator_)
- ActivateFirst();
-
- last_action_ = std::make_pair(0, 0);
- }
- else if (IsMatch(false, key_sym, state, volume_mute_))
- {
- if (last_action_ != volume_mute_)
- ActivateSoundAction(INDICATOR_SOUND_ACTION_MUTE);
-
- last_action_ = std::make_pair(0, 0);
- }
- else if (IsMatch(false, key_sym, state, volume_down_))
- {
- if (last_action_ != volume_down_)
- ActivateSoundAction(INDICATOR_SOUND_ACTION_SCROLL, g_variant_new_int32(-1));
-
- last_action_ = std::make_pair(0, 0);
- }
- else if (IsMatch(false, key_sym, state, volume_up_))
- {
- if (last_action_ != volume_up_)
- ActivateSoundAction(INDICATOR_SOUND_ACTION_SCROLL, g_variant_new_int32(+1));
-
- last_action_ = std::make_pair(0, 0);
- }
- else if (IsMatch(false, key_sym, state, previous_source_))
- {
- if (last_action_ != previous_source_)
- ActivateKeyboardAction(INDICATOR_KEYBOARD_ACTION_SCROLL, g_variant_new_int32(-1));
-
- last_action_ = std::make_pair(0, 0);
- }
- else if (IsMatch(false, key_sym, state, next_source_))
- {
- if (last_action_ != next_source_)
- ActivateKeyboardAction(INDICATOR_KEYBOARD_ACTION_SCROLL, g_variant_new_int32(+1));
-
- last_action_ = std::make_pair(0, 0);
- }
-}
-
-void Panel::ActivateIndicatorAction(std::string const& bus_name,
- std::string const& object_path,
- std::string const& action,
- glib::Variant const& parameter) const
-{
- GVariantBuilder builder;
-
- g_variant_builder_init(&builder, G_VARIANT_TYPE("(sava{sv})"));
- g_variant_builder_add(&builder, "s", action.c_str());
-
- if (parameter)
- g_variant_builder_add_parsed(&builder, "[%v]", (GVariant*) parameter);
- else
- g_variant_builder_add_parsed(&builder, "@av []");
-
- g_variant_builder_add_parsed(&builder, "@a{sv} []");
-
- auto proxy = std::make_shared<glib::DBusProxy>(bus_name, object_path, INDICATOR_ACTION_INTERFACE, G_BUS_TYPE_SESSION);
- proxy->CallBegin("Activate", g_variant_builder_end(&builder), [proxy] (GVariant*, glib::Error const&) {});
-}
-
-void Panel::ActivateKeyboardAction(std::string const& action, glib::Variant const& parameter) const
-{
- ActivateIndicatorAction(INDICATOR_KEYBOARD_BUS_NAME, INDICATOR_KEYBOARD_OBJECT_PATH, action, parameter);
-}
-
-void Panel::ActivateSoundAction(std::string const& action, glib::Variant const& parameter) const
-{
- ActivateIndicatorAction(INDICATOR_SOUND_BUS_NAME, INDICATOR_SOUND_OBJECT_PATH, action, parameter);
+ if (GetInputEventSensitivity())
+ indicators_view_->ActivateIfSensitive();
}
}
diff --git a/lockscreen/LockScreenPanel.h b/lockscreen/LockScreenPanel.h
index 8c31108a5..c5397b617 100644
--- a/lockscreen/LockScreenPanel.h
+++ b/lockscreen/LockScreenPanel.h
@@ -22,10 +22,8 @@
#include <Nux/Nux.h>
#include <Nux/View.h>
-#include <UnityCore/GLibDBusProxy.h>
-#include <UnityCore/GLibSource.h>
-#include <UnityCore/GLibWrapper.h>
#include <UnityCore/Indicators.h>
+#include <UnityCore/GLibSource.h>
#include <UnityCore/SessionManager.h>
namespace unity
@@ -46,7 +44,7 @@ public:
nux::Property<bool> active;
nux::Property<int> monitor;
- bool WillHandleKeyEvent(unsigned int event_type, unsigned long key_sym, unsigned long modifiers);
+ void ActivatePanel();
protected:
void Draw(nux::GraphicsEngine& GfxContext, bool force_draw) override;
@@ -71,52 +69,6 @@ private:
bool needs_geo_sync_;
nux::Point tracked_pointer_pos_;
glib::Source::UniquePtr track_menu_pointer_timeout_;
-
- glib::Object<GSettings> media_key_settings_;
- glib::Object<GSettings> input_switch_settings_;
-
- typedef std::pair<unsigned int, unsigned int> Accelerator;
- Accelerator ParseAcceleratorString(std::string const& string) const;
-
- void ParseAccelerators();
-
- Accelerator activate_indicator_;
- Accelerator volume_mute_;
- Accelerator volume_down_;
- Accelerator volume_up_;
- Accelerator previous_source_;
- Accelerator next_source_;
-
- /* We only want to activate the indicator on key press OR key
- * release, never both, so we'll need to keep track of the last
- * action that occurred. However, holding the keys down should
- * allow multiple activations, for example, when the volume
- * down button is held down. */
- Accelerator last_action_;
-
- bool IsMatch(bool is_press,
- unsigned int key_sym,
- unsigned int modifiers,
- Accelerator const& accelerator) const;
-
- void OnKeyDown(unsigned long event,
- unsigned long key_sym,
- unsigned long state,
- const char* text,
- unsigned short repeat);
-
- void OnKeyUp(unsigned int key_sym,
- unsigned long key_code,
- unsigned long state);
-
- /* This is just for telling an indicator to do something. */
- void ActivateIndicatorAction(std::string const& bus_name,
- std::string const& object_path,
- std::string const& action,
- glib::Variant const& parameter = glib::Variant()) const;
-
- void ActivateKeyboardAction(std::string const& action, glib::Variant const& parameter = glib::Variant()) const;
- void ActivateSoundAction(std::string const& action, glib::Variant const& parameter = glib::Variant()) const;
};
} // lockscreen namespace
diff --git a/lockscreen/LockScreenShield.cpp b/lockscreen/LockScreenShield.cpp
index 861beb176..50dd1e42e 100644
--- a/lockscreen/LockScreenShield.cpp
+++ b/lockscreen/LockScreenShield.cpp
@@ -36,8 +36,8 @@ namespace unity
namespace lockscreen
{
-Shield::Shield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, int monitor_num, bool is_primary)
- : AbstractShield(session_manager, indicators, monitor_num, is_primary)
+Shield::Shield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor_num, bool is_primary)
+ : AbstractShield(session_manager, indicators, accelerators, monitor_num, is_primary)
, bg_settings_(std::make_shared<BackgroundSettings>())
, prompt_view_(nullptr)
, panel_view_(nullptr)
@@ -86,12 +86,6 @@ void Shield::UpdateBackgroundTexture()
}
}
-void Shield::CheckCapsLockPrompt()
-{
- if (prompt_view_)
- prompt_view_->CheckIfCapsLockOn();
-}
-
void Shield::ShowPrimaryView()
{
GrabPointer();
@@ -189,14 +183,25 @@ UserPromptView* Shield::CreatePromptView()
return prompt_view;
}
-nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long key_sym, unsigned long modifiers)
+nux::Area* Shield::FindKeyFocusArea(unsigned etype, unsigned long keysym, unsigned long modifiers)
{
if (primary)
{
- grab_key.emit(modifiers, key_sym);
+ grab_key.emit(modifiers, keysym);
- if (panel_view_ && panel_view_->WillHandleKeyEvent(etype, key_sym, modifiers))
- return panel_view_;
+ if (accelerators_)
+ {
+ if (etype == nux::EVENT_KEY_DOWN)
+ {
+ if (accelerators_->HandleKeyPress(keysym, modifiers))
+ return panel_view_;
+ }
+ else if (etype == nux::EVENT_KEY_UP)
+ {
+ if (accelerators_->HandleKeyRelease(keysym, modifiers))
+ return panel_view_;
+ }
+ }
if (prompt_view_)
{
@@ -230,5 +235,11 @@ bool Shield::IsIndicatorOpen() const
return panel_view_ ? panel_view_->active() : false;
}
+void Shield::ActivatePanel()
+{
+ if (panel_view_)
+ panel_view_->ActivatePanel();
+}
+
}
}
diff --git a/lockscreen/LockScreenShield.h b/lockscreen/LockScreenShield.h
index c95633385..25846334d 100644
--- a/lockscreen/LockScreenShield.h
+++ b/lockscreen/LockScreenShield.h
@@ -36,10 +36,10 @@ class Panel;
class Shield : public AbstractShield
{
public:
- Shield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary);
+ Shield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary);
bool IsIndicatorOpen() const override;
- void CheckCapsLockPrompt() override;
+ void ActivatePanel() override;
protected:
bool AcceptKeyNavFocus() override;
diff --git a/lockscreen/LockScreenShieldFactory.cpp b/lockscreen/LockScreenShieldFactory.cpp
index 4932ca5c4..6bed3db27 100644
--- a/lockscreen/LockScreenShieldFactory.cpp
+++ b/lockscreen/LockScreenShieldFactory.cpp
@@ -25,9 +25,9 @@ namespace unity
namespace lockscreen
{
-nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, int monitor, bool is_primary)
+nux::ObjectPtr<AbstractShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, indicator::Indicators::Ptr const& indicators, Accelerators::Ptr const& accelerators, int monitor, bool is_primary)
{
- return nux::ObjectPtr<Shield>(new Shield(session_manager, indicators, monitor, is_primary));
+ return nux::ObjectPtr<Shield>(new Shield(session_manager, indicators, accelerators, monitor, is_primary));
}
}
diff --git a/lockscreen/LockScreenShieldFactory.h b/lockscreen/LockScreenShieldFactory.h
index 19b3894fa..581feba9f 100644
--- a/lockscreen/LockScreenShieldFactory.h
+++ b/lockscreen/LockScreenShieldFactory.h
@@ -37,12 +37,12 @@ struct ShieldFactoryInterface
virtual ~ShieldFactoryInterface() = default;
- virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary) = 0;
+ virtual nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary) = 0;
};
struct ShieldFactory : ShieldFactoryInterface
{
- nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int monitor, bool is_primary) override;
+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int monitor, bool is_primary) override;
};
}
diff --git a/lockscreen/UserPromptView.cpp b/lockscreen/UserPromptView.cpp
index 2e852ceff..5c99fefe9 100644
--- a/lockscreen/UserPromptView.cpp
+++ b/lockscreen/UserPromptView.cpp
@@ -21,12 +21,10 @@
#include <boost/algorithm/string/trim.hpp>
#include <Nux/VLayout.h>
-#include <X11/XKBlib.h>
#include "LockScreenSettings.h"
#include "unity-shared/CairoTexture.h"
#include "unity-shared/DashStyle.h"
-#include "unity-shared/PreviewStyle.h"
#include "unity-shared/TextInput.h"
#include "unity-shared/StaticCairoText.h"
#include "unity-shared/RawPixel.h"
@@ -40,9 +38,9 @@ namespace
const RawPixel PADDING = 10_em;
const RawPixel LAYOUT_MARGIN = 10_em;
const RawPixel MSG_LAYOUT_MARGIN = 15_em;
-const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
+const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
-const int PROMPT_FONT_SIZE = 13;
+const int PROMPT_FONT_SIZE = 13;
nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
{
@@ -78,28 +76,6 @@ nux::AbstractPaintLayer* CrateBackgroundLayer(int width, int height)
rop));
}
-nux::AbstractPaintLayer* CreateWarningLayer(nux::BaseTexture* texture)
-{
- // Create the texture layer
- nux::TexCoordXForm texxform;
-
- texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
- texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
- texxform.min_filter = nux::TEXFILTER_LINEAR;
- texxform.mag_filter = nux::TEXFILTER_LINEAR;
-
- nux::ROPConfig rop;
- rop.Blend = true;
- rop.SrcBlend = GL_ONE;
- rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
-
- return (new nux::TextureLayer(texture->GetDeviceTexture(),
- texxform,
- nux::color::White,
- true,
- rop));
-}
-
std::string SanitizeMessage(std::string const& message)
{
std::string msg = boost::algorithm::trim_copy(message);
@@ -124,7 +100,6 @@ std::string SanitizeMessage(std::string const& message)
UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
: nux::View(NUX_TRACKER_LOCATION)
, session_manager_(session_manager)
- , caps_lock_on_(false)
{
user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
AddPrompt(message, /* visible */ true, promise);
@@ -146,32 +121,10 @@ UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
ResetLayout();
});
- dash::previews::Style& preview_style = dash::previews::Style::Instance();
-
- warning_ = preview_style.GetWarningIcon();
ResetLayout();
user_authenticator_.AuthenticateStart(session_manager_->UserName(),
sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
-
- // When we get to HiDPI changes here, we will need to update this width
- dash::Style& style = dash::Style::Instance();
- spin_icon_width_ = style.GetSearchSpinIcon()->GetWidth();
-
- CheckIfCapsLockOn();
-}
-
-void UserPromptView::CheckIfCapsLockOn()
-{
- Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
- unsigned int state = 0;
- XkbGetIndicatorState(dpy, XkbUseCoreKbd, &state);
-
- // Caps is on 0x1, couldn't find any #define in /usr/include/X11
- if ((state & 0x1) == 1)
- caps_lock_on_ = true;
- else
- caps_lock_on_ = false;
}
bool UserPromptView::InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character)
@@ -179,7 +132,7 @@ bool UserPromptView::InspectKeyEvent(unsigned int eventType, unsigned int key_sy
if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ESCAPE))
{
if (!focus_queue_.empty())
- focus_queue_.front()->SetText("");
+ focus_queue_.front()->text_entry()->SetText("");
return true;
}
@@ -260,15 +213,6 @@ void UserPromptView::DrawContent(nux::GraphicsEngine& graphics_engine, bool forc
nux::GetPainter().PushLayer(graphics_engine, geo, bg_layer_.get());
}
- if (caps_lock_on_)
- {
- for (auto const& text_entry : focus_queue_)
- PaintWarningIcon(graphics_engine, text_entry->GetGeometry());
-
- if (focus_queue_.empty())
- PaintWarningIcon(graphics_engine, cached_focused_geo_);
- }
-
if (GetLayout())
GetLayout()->ProcessDraw(graphics_engine, force_draw);
@@ -278,49 +222,16 @@ void UserPromptView::DrawContent(nux::GraphicsEngine& graphics_engine, bool forc
graphics_engine.PopClippingRectangle();
}
-void UserPromptView::PaintWarningIcon(nux::GraphicsEngine& graphics_engine, nux::Geometry const& geo)
-{
- nux::Geometry warning_geo = {geo.x + geo.width - GetWarningIconOffset(),
- geo.y, warning_->GetWidth(), warning_->GetHeight()};
-
- nux::GetPainter().PushLayer(graphics_engine, warning_geo, CreateWarningLayer(warning_));
-}
-
-int UserPromptView::GetWarningIconOffset()
-{
- return warning_->GetWidth() + spin_icon_width_;
-}
-
nux::View* UserPromptView::focus_view()
{
if (focus_queue_.empty())
return nullptr;
for (auto* view : focus_queue_)
- if (view->HasKeyboardFocus())
+ if (view->text_entry()->HasKeyboardFocus())
return view;
- return focus_queue_.front();
-}
-
-void UserPromptView::ToggleCapsLockBool()
-{
- caps_lock_on_ = !caps_lock_on_;
- QueueDraw();
-}
-
-void UserPromptView::RecvKeyUp(unsigned keysym,
- unsigned long keycode,
- unsigned long state)
-{
- if (!caps_lock_on_ && keysym == NUX_VK_CAPITAL)
- {
- ToggleCapsLockBool();
- }
- else if (caps_lock_on_ && keysym == NUX_VK_CAPITAL)
- {
- ToggleCapsLockBool();
- }
+ return focus_queue_.front()->text_entry();
}
void UserPromptView::AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const& promise)
@@ -330,18 +241,15 @@ void UserPromptView::AddPrompt(std::string const& message, bool visible, Promise
text_input->input_hint = SanitizeMessage(message);
text_input->hint_font_size = PROMPT_FONT_SIZE;
+ text_input->show_caps_lock = true;
text_entry->SetPasswordMode(!visible);
text_entry->SetPasswordChar("•");
text_entry->SetToggleCursorVisibilityOnKeyFocus(true);
- text_entry->key_up.connect(sigc::mem_fun(this, &UserPromptView::RecvKeyUp));
-
text_input->SetMinimumHeight(Settings::GRID_SIZE);
text_input->SetMaximumHeight(Settings::GRID_SIZE);
prompt_layout_->AddView(text_input, 1);
- focus_queue_.push_back(text_entry);
-
- CheckIfCapsLockOn();
+ focus_queue_.push_back(text_input);
// Don't remove it, it helps with a11y.
if (focus_queue_.size() == 1)
@@ -378,10 +286,12 @@ void UserPromptView::AddPrompt(std::string const& message, bool visible, Promise
void UserPromptView::AddMessage(std::string const& message, nux::Color const& color)
{
+ nux::Geometry const& geo = GetGeometry();
auto* view = new unity::StaticCairoText("");
view->SetFont(Settings::Instance().font_name());
view->SetTextColor(color);
view->SetText(message);
+ view->SetMaximumWidth(geo.width);
msg_layout_->AddView(view);
diff --git a/lockscreen/UserPromptView.h b/lockscreen/UserPromptView.h
index 7e98dc0af..4b3061565 100644
--- a/lockscreen/UserPromptView.h
+++ b/lockscreen/UserPromptView.h
@@ -56,8 +56,6 @@ public:
void AddMessage(std::string const& message, nux::Color const& color);
void AuthenticationCb(bool authenticated);
- void CheckIfCapsLockOn();
-
protected:
void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
@@ -66,12 +64,6 @@ private:
void ResetLayout();
bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
- void RecvKeyUp(unsigned int, unsigned long, unsigned long);
-
- void PaintWarningIcon(nux::GraphicsEngine& graphics_engine, nux::Geometry const& geo);
- void ToggleCapsLockBool();
-
- int GetWarningIconOffset();
session::Manager::Ptr session_manager_;
UserAuthenticatorPam user_authenticator_;
@@ -81,13 +73,9 @@ private:
StaticCairoText* message_;
StaticCairoText* error_;
StaticCairoText* invalid_login_;
- std::deque<IMTextEntry*> focus_queue_;
+ std::deque<TextInput*> focus_queue_;
- nux::BaseTexture* warning_;
nux::Geometry cached_focused_geo_;
-
- bool caps_lock_on_;
- int spin_icon_width_;
};
}
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index dfc4a70ac..170e2bd1b 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -101,7 +101,7 @@ using util::Timer;
DECLARE_LOGGER(logger, "unity.shell.compiz");
namespace
{
-UnityScreen* uScreen = 0;
+UnityScreen* uScreen = nullptr;
void reset_glib_logging();
void configure_logging();
@@ -143,6 +143,7 @@ const int FRAMES_TO_REDRAW_ON_RESUME = 10;
const RawPixel SCALE_PADDING = 40_em;
const RawPixel SCALE_SPACING = 20_em;
const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
+const std::string HUD_UNGRAB_WAIT = "hud-ungrab-wait";
const std::string FIRST_RUN_STAMP = "first_run.stamp";
const std::string LOCKED_STAMP = "locked.stamp";
} // namespace local
@@ -167,6 +168,8 @@ UnityScreen::UnityScreen(CompScreen* screen)
, _key_nav_mode_requested(false)
, _last_output(nullptr)
, force_draw_countdown_(0)
+ , firstWindowAboveShell(nullptr)
+ , onboard_(nullptr)
, grab_index_(0)
, painting_tray_ (false)
, last_scroll_event_(0)
@@ -521,6 +524,7 @@ void UnityScreen::initAltTabNextWindow()
void UnityScreen::OnInitiateSpread()
{
+ scale_just_activated_ = super_keypressed_;
spread_filter_ = std::make_shared<spread::Filter>();
spread_filter_->text.changed.connect([this] (std::string const& filter) {
if (filter.empty())
@@ -939,7 +943,8 @@ void UnityScreen::DrawPanelUnderDash()
bool UnityScreen::forcePaintOnTop()
{
- return !allowWindowPaint ||
+ return !allowWindowPaint ||
+ lockscreen_controller_->IsLocked() ||
((switcher_controller_->Visible() ||
WindowManager::Default().IsExpoActive())
&& !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
@@ -1184,6 +1189,20 @@ bool UnityWindow::IsMinimized ()
return window->minimized ();
}
+bool UnityWindow::CanBypassLockScreen() const
+{
+ if (window->type() == CompWindowTypePopupMenuMask &&
+ uScreen->lockscreen_controller_->HasOpenMenu())
+ {
+ return true;
+ }
+
+ if (window == uScreen->onboard_)
+ return true;
+
+ return false;
+}
+
void UnityWindow::DoOverrideFrameRegion(CompRegion &region)
{
unsigned int oldUpdateFrameRegionIndex = window->updateFrameRegionGetCurrentIndex();
@@ -1703,6 +1722,8 @@ void UnityScreen::handleEvent(XEvent* event)
wm.OnScreenGrabbed();
else if (event->xfocus.mode == NotifyUngrab)
wm.OnScreenUngrabbed();
+ else if (!screen->grabbed() && event->xfocus.mode == NotifyWhileGrabbed)
+ wm.OnScreenGrabbed();
if (_key_nav_mode_requested)
{
@@ -1981,19 +2002,7 @@ void UnityScreen::handleCompizEvent(const char* plugin,
{
PluginAdapter& adapter = PluginAdapter::Default();
adapter.NotifyCompizEvent(plugin, event, option);
- compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>::handleCompizEvent (plugin, event, option);
-
- if (launcher_controller_->IsOverlayOpen() && g_strcmp0(event, "start_viewport_switch") == 0)
- {
- ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
- }
-
- if (super_keypressed_ && g_strcmp0(plugin, "scale") == 0 &&
- g_strcmp0(event, "activate") == 0)
- {
- scale_just_activated_ = CompOption::getBoolOptionNamed(option, "active");
- }
-
+ compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>::handleCompizEvent(plugin, event, option);
screen->handleCompizEvent(plugin, event, option);
}
@@ -2062,6 +2071,7 @@ bool UnityScreen::showLauncherKeyTerminate(CompAction* action,
return false;
bool was_tap = state & CompAction::StateTermTapped;
+ bool tap_handled = false;
LOG_DEBUG(logger) << "Super released: " << (was_tap ? "tapped" : "released");
int when = options[7].value().i(); // XEvent time in millisec
@@ -2090,6 +2100,24 @@ bool UnityScreen::showLauncherKeyTerminate(CompAction* action,
{
QuicklistManager::Default()->Current()->Hide();
}
+
+ if (!dash_controller_->IsVisible())
+ {
+ if (!adapter.IsTopWindowFullscreenOnMonitorWithMouse())
+ {
+ if (dash_controller_->ShowDash())
+ {
+ tap_handled = true;
+ ubus_manager_.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
+ g_variant_new("(sus)", "home.scope", dash::GOTO_DASH_URI, ""));
+ }
+ }
+ }
+ else
+ {
+ dash_controller_->HideDash();
+ tap_handled = true;
+ }
}
super_keypressed_ = false;
@@ -2103,7 +2131,7 @@ bool UnityScreen::showLauncherKeyTerminate(CompAction* action,
EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, false);
action->setState (action->state() & (unsigned)~(CompAction::StateTermKey));
- return true;
+ return (was_tap && tap_handled) || !was_tap;
}
bool UnityScreen::showPanelFirstMenuKeyInitiate(CompAction* action,
@@ -2471,32 +2499,45 @@ bool UnityScreen::ShowHud()
{
if (switcher_controller_->Visible())
{
- LOG_ERROR(logger) << "this should never happen";
+ LOG_ERROR(logger) << "Switcher is visible when showing HUD: this should never happen";
return false; // early exit if the switcher is open
}
- if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse())
- {
- return false;
- }
-
if (hud_controller_->IsVisible())
{
- ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST);
+ hud_controller_->HideHud();
}
else
{
+ auto& wm = WindowManager::Default();
+
+ if (wm.IsTopWindowFullscreenOnMonitorWithMouse())
+ return false;
+
+ if (wm.IsScreenGrabbed())
+ {
+ hud_ungrab_slot_ = wm.screen_ungrabbed.connect([this] { ShowHud(); });
+
+ // Let's wait ungrab event for maximum a couple of seconds...
+ sources_.AddTimeoutSeconds(2, [this] {
+ hud_ungrab_slot_->disconnect();
+ return false;
+ }, local::HUD_UNGRAB_WAIT);
+
+ return false;
+ }
+
// Handles closing KeyNav (Alt+F1) if the hud is about to show
if (launcher_controller_->KeyNavIsActive())
launcher_controller_->KeyNavTerminate(false);
- // If an overlay is open, it must be the dash! Close it!
- if (launcher_controller_->IsOverlayOpen())
+ if (dash_controller_->IsVisible())
dash_controller_->HideDash();
if (QuicklistManager::Default()->Current())
QuicklistManager::Default()->Current()->Hide();
+ hud_ungrab_slot_->disconnect();
hud_controller_->ShowHud();
}
@@ -2799,9 +2840,7 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
* fully covers the shell on its output. It does not include regular windows
* stacked above the shell like DnD icons or Onboard etc.
*/
- if (G_UNLIKELY(is_nux_window_) &&
- (!uScreen->lockscreen_controller_->IsLocked() ||
- uScreen->lockscreen_controller_->opacity() != 1.0f))
+ if (G_UNLIKELY(is_nux_window_))
{
if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
{
@@ -2858,9 +2897,7 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
if (uScreen->lockscreen_controller_->IsLocked())
{
- if ((window->type() != CompWindowTypePopupMenuMask ||
- !uScreen->lockscreen_controller_->HasOpenMenu()) &&
- !window->minimized() && window->resName() != "onboard")
+ if (!window->minimized() && !CanBypassLockScreen())
{
// For some reasons PAINT_WINDOW_NO_CORE_INSTANCE_MASK doesn't work here
// (well, it works too much, as it applies to menus too), so we need
@@ -2933,6 +2970,7 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
{
auto window_state = window->state();
auto window_type = window->type();
+ bool locked = uScreen->lockscreen_controller_->IsLocked();
if (uScreen->doShellRepaint && !uScreen->paint_panel_under_dash_ && window_type == CompWindowTypeNormalMask)
{
@@ -2949,12 +2987,16 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
}
if (uScreen->doShellRepaint &&
- !uScreen->forcePaintOnTop () &&
window == uScreen->firstWindowAboveShell &&
+ !uScreen->forcePaintOnTop() &&
!uScreen->fullscreenRegion.contains(window->geometry()))
{
uScreen->paintDisplay();
}
+ else if (locked && CanBypassLockScreen())
+ {
+ uScreen->paintDisplay();
+ }
enum class DrawPanelShadow
{
@@ -3017,7 +3059,7 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
}
}
- if (uScreen->lockscreen_controller_->IsLocked())
+ if (locked)
draw_panel_shadow = DrawPanelShadow::NO;
if (draw_panel_shadow == DrawPanelShadow::BELOW_WINDOW)
@@ -3819,14 +3861,14 @@ void UnityScreen::SaveLockStamp(bool save)
void UnityScreen::RaiseOSK()
{
- /* stack any windows named "onboard" above us */
- for (CompWindow *w : screen->windows ())
+ /* stack the onboard window above us */
+ if (onboard_)
{
- if (w->resName() == "onboard")
+ if (nux::BaseWindow* dash = dash_controller_->window())
{
- Window xid = dash_controller_->window()->GetInputWindowId();
- XSetTransientForHint (screen->dpy(), w->id(), xid);
- w->raise ();
+ Window xid = dash->GetInputWindowId();
+ XSetTransientForHint(screen->dpy(), onboard_->id(), xid);
+ onboard_->raise();
}
}
}
@@ -3911,8 +3953,10 @@ void UnityScreen::initLauncher()
CompOption::Value v(launcher_width);
screen->setOptionForPlugin("expo", "x_offset", v);
- if (launcher_controller_->options()->hide_mode != LAUNCHER_HIDE_NEVER)
- screen->setOptionForPlugin("scale", "x_offset", v);
+ if (launcher_controller_->options()->hide_mode == LAUNCHER_HIDE_NEVER)
+ v.set(0);
+
+ screen->setOptionForPlugin("scale", "x_offset", v);
};
for (auto const& launcher : launcher_controller_->launchers())
@@ -4073,23 +4117,10 @@ UnityWindow::UnityWindow(CompWindow* window)
if (window->state() & CompWindowStateFullscreenMask)
uScreen->fullscreen_windows_.push_back(window);
- /* We might be starting up so make sure that
- * we don't deref the dashcontroller that doesnt
- * exist */
- dash::Controller::Ptr dp = uScreen->dash_controller_;
-
- if (dp)
+ if (window->type() == CompWindowTypeUtilMask && window->resName() == "onboard")
{
- nux::BaseWindow* w = dp->window ();
-
- if (w)
- {
- if (window->resName() == "onboard")
- {
- Window xid = dp->window()->GetInputWindowId();
- XSetTransientForHint (screen->dpy(), window->id(), xid);
- }
- }
+ uScreen->onboard_ = window;
+ uScreen->RaiseOSK();
}
}
@@ -4470,6 +4501,9 @@ UnityWindow::~UnityWindow()
if (window->state () & CompWindowStateFullscreenMask)
uScreen->fullscreen_windows_.remove(window);
+ if (window == uScreen->onboard_)
+ uScreen->onboard_ = nullptr;
+
uScreen->fake_decorated_windows_.erase(this);
PluginAdapter::Default().OnWindowClosed(window);
}
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 7a5cb5271..36af0514a 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -393,6 +393,7 @@ private:
CompRegion nuxRegion;
CompRegion fullscreenRegion;
CompWindow* firstWindowAboveShell;
+ CompWindow* onboard_;
::GLFramebufferObject *oldFbo;
@@ -421,6 +422,7 @@ private:
UBusManager ubus_manager_;
glib::SourceManager sources_;
+ connection::Wrapper hud_ungrab_slot_;
CompRegion buffered_compiz_damage_this_frame_;
CompRegion buffered_compiz_damage_last_frame_;
@@ -519,6 +521,7 @@ private:
bool IsInShowdesktopMode ();
bool IsShaded ();
bool IsMinimized ();
+ bool CanBypassLockScreen() const;
void DoOverrideFrameRegion (CompRegion &r);
void DoHide ();
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5f2c0845e..97fe6601b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -48,5 +48,6 @@ unity-shared/CoverArt.cpp
unity-shared/DashStyle.cpp
unity-shared/PreviewStyle.cpp
unity-shared/SearchBar.cpp
+unity-shared/TextInput.cpp
unity-shared/UScreen.cpp
gnome/50-unity-launchers.xml.in
diff --git a/resources/launcher_icon_glow_62.png b/resources/launcher_icon_glow_62.png
new file mode 100644
index 000000000..9e21628f5
--- /dev/null
+++ b/resources/launcher_icon_glow_62.png
Binary files differ
diff --git a/resources/launcher_icon_glow_62.svg b/resources/launcher_icon_glow_62.svg.save
index 7eb994de3..7eb994de3 100644
--- a/resources/launcher_icon_glow_62.svg
+++ b/resources/launcher_icon_glow_62.svg.save
diff --git a/shutdown/SessionView.cpp b/shutdown/SessionView.cpp
index 0a20f1162..8fe60d859 100644
--- a/shutdown/SessionView.cpp
+++ b/shutdown/SessionView.cpp
@@ -76,6 +76,7 @@ View::View(Manager::Ptr const& manager)
GetBoundingArea()->mouse_click.connect([this] (int, int, unsigned long, unsigned long) { request_close.emit(); });
have_inhibitors.changed.connect(sigc::hide(sigc::mem_fun(this, &View::UpdateText)));
+ manager_->have_other_open_sessions.changed.connect(sigc::hide(sigc::mem_fun(this, &View::UpdateText)));
mode.SetSetterFunction([this] (Mode& target, Mode new_mode) {
if (new_mode == Mode::SHUTDOWN && !manager_->CanShutdown())
@@ -124,24 +125,32 @@ void View::UpdateViewSize()
void View::UpdateText()
{
- const char* message = nullptr;
+ std::string message;
+ std::string other_users_msg;
auto const& real_name = manager_->RealName();
auto const& name = (real_name.empty() ? manager_->UserName() : real_name);
+ other_users_msg = _("Other users are logged in. Restarting or shutting down will close their open applications and may cause them to lose work.\n\n");
+
if (mode() == Mode::SHUTDOWN)
{
title_->SetText(_("Shut Down"));
title_->SetVisible(true);
+ if (manager_->have_other_open_sessions())
+ {
+ message += other_users_msg;
+ }
+
if (have_inhibitors())
{
- message = _("Hi %s, you have open files that you might want to save " \
- "before shutting down. Are you sure you want to continue?");
+ message += _("Hi %s, you have open files that you might want to save " \
+ "before shutting down. Are you sure you want to continue?");
}
else
{
- message = _("Goodbye, %s. Are you sure you want to close all programs " \
- "and shut down the computer?");
+ message += _("Goodbye, %s. Are you sure you want to close all programs " \
+ "and shut down the computer?");
}
}
else if (mode() == Mode::LOGOUT)
@@ -164,27 +173,32 @@ void View::UpdateText()
{
title_->SetVisible(false);
+ if (manager_->have_other_open_sessions())
+ {
+ message += other_users_msg;
+ }
+
if (have_inhibitors())
{
if (buttons_layout_->GetChildren().size() > 3)
{
// We have enough buttons to show the message without a new line.
- message = _("Hi %s, you have open files you might want to save. " \
+ message += _("Hi %s, you have open files you might want to save. " \
"Would you like to…");
}
else
{
- message = _("Hi %s, you have open files you might want to save.\n" \
+ message += _("Hi %s, you have open files you might want to save.\n" \
"Would you like to…");
}
}
else
{
- message = _("Goodbye, %s. Would you like to…");
+ message += _("Goodbye, %s. Would you like to…");
}
}
- subtitle_->SetText(glib::String(g_strdup_printf(message, name.c_str())).Str());
+ subtitle_->SetText(glib::String(g_strdup_printf(message.c_str(), name.c_str())).Str());
}
void View::Populate()
diff --git a/tests/data/external.gschema.xml b/tests/data/external.gschema.xml
index bdc418567..160db0572 100644
--- a/tests/data/external.gschema.xml
+++ b/tests/data/external.gschema.xml
@@ -121,4 +121,25 @@
<default>false</default>
</key>
</schema>
+
+ <schema id="org.gnome.settings-daemon.plugins.media-keys" path="/org/gnome/settings-daemon/plugins/media-keys/">
+ <key type="s" name="volume-mute">
+ <default>'XF86AudioMute'</default>
+ </key>
+ <key type="s" name="volume-down">
+ <default>'XF86AudioLowerVolume'</default>
+ </key>
+ <key type="s" name="volume-up">
+ <default>'XF86AudioRaiseVolume'</default>
+ </key>
+ </schema>
+
+ <schema id="org.gnome.desktop.wm.keybindings" path="/org/gnome/desktop/wm/keybindings/">
+ <key type="as" name="switch-input-source-backward">
+ <default>["&lt;Shift&gt;&lt;Super&gt;space"]</default>
+ </key>
+ <key type="as" name="switch-input-source">
+ <default>["&lt;Super&gt;space"]</default>
+ </key>
+ </schema>
</schemalist>
diff --git a/tests/test_lockscreen_controller.cpp b/tests/test_lockscreen_controller.cpp
index 55add06bc..520f00963 100644
--- a/tests/test_lockscreen_controller.cpp
+++ b/tests/test_lockscreen_controller.cpp
@@ -52,16 +52,16 @@ const unsigned TICK_DURATION = 10 * 1000;
struct MockShield : AbstractShield
{
MockShield()
- : AbstractShield(nullptr, nullptr, 0, false)
+ : AbstractShield(nullptr, nullptr, nullptr, 0, false)
{}
MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
- MOCK_METHOD0(CheckCapsLockPrompt, void());
+ MOCK_METHOD0(ActivatePanel, void());
};
struct ShieldFactoryMock : ShieldFactoryInterface
{
- nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, int, bool) override
+ nux::ObjectPtr<AbstractShield> CreateShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, Accelerators::Ptr const&, int, bool) override
{
return nux::ObjectPtr<AbstractShield>(new MockShield());
}
diff --git a/tests/test_unity_window_view.cpp b/tests/test_unity_window_view.cpp
index f9ac699ef..1eb0d2562 100644
--- a/tests/test_unity_window_view.cpp
+++ b/tests/test_unity_window_view.cpp
@@ -82,10 +82,10 @@ TEST_F(TestUnityWindowView, Closable)
view.closable = true;
ASSERT_NE(view.close_button_, nullptr);
- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
EXPECT_EQ(view.close_button_->GetParentObject(), &view);
- int padding = view.style()->GetCloseButtonPadding();
+ int padding = view.style()->GetCloseButtonPadding(view.scale);
EXPECT_EQ(view.close_button_->GetBaseX(), padding);
EXPECT_EQ(view.close_button_->GetBaseY(), padding);
}
@@ -96,16 +96,16 @@ TEST_F(TestUnityWindowView, CloseButtonStates)
ASSERT_NE(view.close_button_, nullptr);
view.close_button_->mouse_enter.emit(0, 0, 0, 0);
- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIconHighligted());
+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
view.close_button_->mouse_leave.emit(0, 0, 0, 0);
- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
view.close_button_->mouse_down.emit(0, 0, 0, 0);
- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIconPressed());
+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON_PRESSED));
view.close_button_->mouse_up.emit(0, 0, 0, 0);
- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
}
TEST_F(TestUnityWindowView, CloseButtonClicksRequestsClose)
@@ -185,7 +185,7 @@ TEST_F(TestUnityWindowView, SetLayoutWrapsOriginalLayout)
view.SetLayout(layout);
view.ComputeContentSize();
- int offset = view.style()->GetInternalOffset();
+ int offset = view.style()->GetInternalOffset(view.scale);
EXPECT_EQ(layout->GetBaseX(), offset);
EXPECT_EQ(layout->GetBaseY(), offset);
}
@@ -199,7 +199,7 @@ TEST_F(TestUnityWindowView, GetLayout)
TEST_F(TestUnityWindowView, GetInternalBackground)
{
- int offset = view.style()->GetInternalOffset();
+ int offset = view.style()->GetInternalOffset(view.scale);
view.background_geo_.Set(g_random_int(), g_random_int(), g_random_int(), g_random_int());
EXPECT_EQ(view.GetInternalBackground(), view.background_geo_.GetExpand(-offset, -offset));
}
@@ -240,4 +240,4 @@ TEST_F(TestUnityWindowView, FindAreaUnderMouse)
}
} // ui
-} // unity \ No newline at end of file
+} // unity
diff --git a/unity-shared/DebugDBusInterface.cpp b/unity-shared/DebugDBusInterface.cpp
index 4177e3fb3..59a93cc18 100644
--- a/unity-shared/DebugDBusInterface.cpp
+++ b/unity-shared/DebugDBusInterface.cpp
@@ -84,7 +84,8 @@ namespace local
{
if (!g_variant_is_of_type(prop_value, G_VARIANT_TYPE_STRING))
{
- LOG_WARNING(logger) << "Unable to match '"<< name << "', it's not a string property.";
+ LOG_WARNING(logger) << "Unable to match '"<< name << "', '" <<
+ prop_value << "' is not a string property.";
return false;
}
@@ -102,7 +103,8 @@ namespace local
{
if (!g_variant_is_of_type(prop_value, G_VARIANT_TYPE_BOOLEAN))
{
- LOG_WARNING(logger) << "Unable to match '"<< name << "', it's not a boolean property.";
+ LOG_WARNING(logger) << "Unable to match '"<< name << "', '" <<
+ prop_value << "' is not a boolean property.";
return false;
}
@@ -138,7 +140,8 @@ namespace local
case G_VARIANT_CLASS_UINT64:
return static_cast<uint64_t>(value) == prop_value.GetUInt64();
default:
- LOG_WARNING(logger) << "Unable to match '"<< name << "' against property of unknown integer type.";
+ LOG_WARNING(logger) << "Unable to match '"<< name << "', '" <<
+ prop_value << "' is not a known integer property.";
};
}
@@ -152,7 +155,24 @@ namespace local
IntrospectionData introspection;
node_->AddProperties(introspection);
- return g_variant_lookup_value(glib::Variant(introspection.Get()), name.c_str(), nullptr);
+
+ glib::Variant value(g_variant_lookup_value(glib::Variant(introspection.Get()), name.c_str(), nullptr), glib::StealRef());
+
+ if (!value)
+ return nullptr;
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_ARRAY) || g_variant_n_children(value) != 2)
+ {
+ LOG_ERROR(logger) << "Property value for '"<< name << "' should be a 2-sized array, got instead '" << value << "'";
+ return nullptr;
+ }
+
+ glib::Variant child(g_variant_get_child_value(value, 1), glib::StealRef());
+
+ if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT))
+ return child.GetVariant();
+
+ return child;
}
std::vector<xpathselect::Node::Ptr> Children() const
diff --git a/unity-shared/PluginAdapter.cpp b/unity-shared/PluginAdapter.cpp
index ddca3f118..0fffe0074 100644
--- a/unity-shared/PluginAdapter.cpp
+++ b/unity-shared/PluginAdapter.cpp
@@ -190,15 +190,34 @@ void PluginAdapter::NotifyCompizEvent(const char* plugin,
_vp_switch_started = false;
screen_viewport_switch_ended.emit();
}
- else if (IsScaleActive() && g_strcmp0(plugin, "scale") == 0 &&
- g_strcmp0(event, "activate") == 0)
+ else if (g_strcmp0(plugin, "scale") == 0 && g_strcmp0(event, "activate") == 0)
{
- // If the scale plugin is activated again while is already grabbing the screen
- // it means that is switching the view (i.e. switching from a spread application
- // to another), so we need to notify our clients that it has really terminated
- // and initiated again.
- terminate_spread.emit();
- initiate_spread.emit();
+ bool new_state = CompOption::getBoolOptionNamed(option, "active");
+
+ if (_spread_state != new_state)
+ {
+ _spread_state = new_state;
+ _spread_state ? initiate_spread.emit() : terminate_spread.emit();
+
+ if (!_spread_state)
+ _spread_windows_state = false;
+ }
+ else if (_spread_state && new_state)
+ {
+ // If the scale plugin is activated again while is already grabbing the screen
+ // it means that is switching the view (i.e. switching from a spread application
+ // to another), so we need to notify our clients that it has really terminated
+ // and initiated again.
+
+ bool old_windows_state = _spread_windows_state;
+ _spread_state = false;
+ _spread_windows_state = false;
+ terminate_spread.emit();
+
+ _spread_state = true;
+ _spread_windows_state = old_windows_state;
+ initiate_spread.emit();
+ }
}
}
@@ -248,7 +267,8 @@ void MultiActionList::Initiate(std::string const& name, CompOption::Vector const
argument.push_back(arg);
/* Initiate the selected action with the arguments */
- action->initiate()(action, state, argument);
+ if (CompAction::CallBack const& initiate_cb = primary_action_->initiate())
+ initiate_cb(action, 0, argument);
}
void MultiActionList::InitiateAll(CompOption::Vector const& extra_args, int state) const
@@ -291,8 +311,11 @@ void MultiActionList::TerminateAll(CompOption::Vector const& extra_args) const
if (primary_action_)
{
- primary_action_->terminate()(primary_action_, CompAction::StateCancel, argument);
- return;
+ if (CompAction::CallBack const& terminate_cb = primary_action_->terminate())
+ {
+ terminate_cb(primary_action_, CompAction::StateCancel, argument);
+ return;
+ }
}
for (auto const& it : actions_)
@@ -304,7 +327,8 @@ void MultiActionList::TerminateAll(CompOption::Vector const& extra_args) const
CompAction::StateTermEdge |
CompAction::StateTermEdgeDnd))
{
- action->terminate()(action, 0, argument);
+ if (CompAction::CallBack const& terminate_cb = primary_action_->terminate())
+ terminate_cb(action, 0, argument);
}
}
}
diff --git a/unity-shared/TextInput.cpp b/unity-shared/TextInput.cpp
index 2dfb72769..23a4e3196 100644
--- a/unity-shared/TextInput.cpp
+++ b/unity-shared/TextInput.cpp
@@ -18,6 +18,15 @@
*/
#include "TextInput.h"
+#include "unity-shared/IconTexture.h"
+#include "unity-shared/DashStyle.h"
+#include "unity-shared/RawPixel.h"
+#include "unity-shared/PreviewStyle.h"
+
+#include <X11/XKBlib.h>
+
+namespace unity
+{
namespace
{
@@ -29,6 +38,14 @@ const int TEXT_INPUT_RIGHT_BORDER = 10;
const int HIGHLIGHT_HEIGHT = 24;
+const RawPixel TOOLTIP_Y_OFFSET = 3_em;
+const RawPixel TOOLTIP_OFFSET = 10_em;
+const RawPixel DEFAULT_ICON_SIZE = 22_em;
+
+// Caps is on 0x1, couldn't find any #define in /usr/include/X11
+const int CAPS_STATE_ON = 0x1;
+
+std::string WARNING_ICON = "dialog-warning-symbolic";
// Fonts
const std::string HINT_LABEL_DEFAULT_FONT_NAME = "Ubuntu";
const int HINT_LABEL_FONT_SIZE = 11;
@@ -38,21 +55,44 @@ const int PANGO_ENTRY_FONT_SIZE = 14;
}
-namespace unity
-{
-
nux::logging::Logger logger("unity.textinput");
NUX_IMPLEMENT_OBJECT_TYPE(TextInput);
+nux::AbstractPaintLayer* CreateWarningLayer(nux::BaseTexture* texture)
+{
+ // Create the texture layer
+ nux::TexCoordXForm texxform;
+
+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
+ texxform.min_filter = nux::TEXFILTER_LINEAR;
+ texxform.mag_filter = nux::TEXFILTER_LINEAR;
+
+ nux::ROPConfig rop;
+ rop.Blend = true;
+
+ rop.SrcBlend = GL_ONE;
+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
+
+ return (new nux::TextureLayer(texture->GetDeviceTexture(),
+ texxform,
+ nux::color::White,
+ true,
+ rop));
+}
+
TextInput::TextInput(NUX_FILE_LINE_DECL)
: View(NUX_FILE_LINE_PARAM)
, input_hint("")
, hint_font_name(HINT_LABEL_DEFAULT_FONT_NAME)
, hint_font_size(HINT_LABEL_FONT_SIZE)
+ , show_caps_lock(false)
, bg_layer_(new nux::ColorLayer(nux::Color(0xff595853), true))
+ , caps_lock_on(false)
, last_width_(-1)
, last_height_(-1)
+ , mouse_over_warning_icon_(false)
{
layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, TEXT_INPUT_RIGHT_BORDER);
@@ -74,6 +114,7 @@ TextInput::TextInput(NUX_FILE_LINE_DECL)
pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
pango_entry_->cursor_moved.connect([this](int i) { QueueDraw(); });
pango_entry_->mouse_down.connect(sigc::mem_fun(this, &TextInput::OnMouseButtonDown));
+ pango_entry_->key_up.connect(sigc::mem_fun(this, &TextInput::OnKeyUp));
pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &TextInput::OnEndKeyFocus));
pango_entry_->text_changed.connect([this](nux::TextEntry*) {
hint_->SetVisible(input_string().empty());
@@ -86,6 +127,25 @@ TextInput::TextInput(NUX_FILE_LINE_DECL)
layered_layout_->SetActiveLayerN(1);
layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
+ warning_ = new IconTexture(LoadWarningIcon(DEFAULT_ICON_SIZE));
+ warning_->SetVisible(caps_lock_on());
+ layout_->AddView(warning_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
+ caps_lock_on.changed.connect([this] (bool on) {
+ if (show_caps_lock)
+ {
+ warning_->SetVisible(on);
+ QueueRelayout();
+ QueueDraw();
+ }
+ });
+
+ show_caps_lock.changed.connect([this] (bool changed) {
+ if (!warning_tooltip_.IsValid())
+ LoadWarningTooltip();
+
+ CheckIfCapsLockOn();
+ });
+
spinner_ = new SearchBarSpinner();
spinner_->SetVisible(false);
spinner_->SetMinMaxSize(22, 22);
@@ -101,6 +161,27 @@ TextInput::TextInput(NUX_FILE_LINE_DECL)
im_preedit.SetGetterFunction(sigc::mem_fun(this, &TextInput::get_im_preedit));
input_hint.changed.connect([this](std::string const& s) { OnInputHintChanged(); });
+ warning_->mouse_enter.connect([this] (int x, int y, int button, int key_flags) {
+ mouse_over_warning_icon_ = true;
+ QueueDraw();
+ });
+
+ warning_->mouse_leave.connect([this] (int x, int y, int button, int key_flags) {
+ mouse_over_warning_icon_ = false;
+ QueueDraw();
+ });
+}
+
+void TextInput::CheckIfCapsLockOn()
+{
+ Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
+ unsigned int state = 0;
+ XkbGetIndicatorState(dpy, XkbUseCoreKbd, &state);
+
+ if ((state & CAPS_STATE_ON) == 1)
+ caps_lock_on = true;
+ else
+ caps_lock_on = false;
}
void TextInput::SetSpinnerVisible(bool visible)
@@ -118,6 +199,75 @@ void TextInput::UpdateHintFont()
hint_->SetFont((hint_font_name() + " " + std::to_string(hint_font_size())).c_str());
}
+nux::ObjectPtr<nux::BaseTexture> TextInput::LoadWarningIcon(int icon_size)
+{
+ auto* theme = gtk_icon_theme_get_default();
+ GtkIconLookupFlags flags = GTK_ICON_LOOKUP_FORCE_SIZE;
+ glib::Error error;
+ glib::Object<GdkPixbuf> pixbuf(gtk_icon_theme_load_icon(theme, WARNING_ICON.c_str(), icon_size, flags, &error));
+
+ if (pixbuf != nullptr)
+ {
+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+ cairo_t* cr = cg.GetInternalContext();
+
+ cairo_push_group(cr);
+ gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
+ cairo_paint_with_alpha(cr, 1.0);
+ std::shared_ptr<cairo_pattern_t> pat(cairo_pop_group(cr), cairo_pattern_destroy);
+
+ cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
+ cairo_rectangle(cr, 0, 0, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+ cairo_mask(cr, pat.get());
+
+ return texture_ptr_from_cairo_graphics(cg);
+ }
+ // Use fallback icon (this one is a png, and does not scale!)
+ else
+ {
+ dash::previews::Style& preview_style = dash::previews::Style::Instance();
+ return nux::ObjectPtr<nux::BaseTexture>(preview_style.GetWarningIcon());
+ }
+}
+
+void TextInput::LoadWarningTooltip()
+{
+ glib::String font_name;
+ g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL);
+
+ glib::Object<GtkStyleContext> style_context(gtk_style_context_new());
+ std::shared_ptr<GtkWidgetPath> widget_path(gtk_widget_path_new(), gtk_widget_path_free);
+ gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_TOOLTIP);
+
+ gtk_style_context_set_path(style_context, widget_path.get());
+ gtk_style_context_add_class(style_context, "tooltip");
+
+ glib::Object<PangoLayout> layout;
+ glib::Object<PangoContext> context(gdk_pango_context_get_for_screen(gdk_screen_get_default()));
+ layout = pango_layout_new(context);
+
+ std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), pango_font_description_free);
+ pango_context_set_font_description(context, desc.get());
+ pango_context_set_language(context, gtk_get_default_language());
+
+ pango_layout_set_height(layout, -1); //avoid wrap lines
+ pango_layout_set_text(layout, _("Caps lock is on"), -1);
+
+ nux::Size extents;
+ pango_layout_get_pixel_size(layout, &extents.width, &extents.height);
+ extents.width += TOOLTIP_OFFSET;
+ extents.height += TOOLTIP_OFFSET;
+
+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, extents.width, extents.height);
+ cairo_t* cr = cg.GetInternalContext();
+
+ gtk_render_background(style_context, cr, 0, 0, extents.width, extents.height);
+ gtk_render_frame(style_context, cr, 0, 0, extents.width, extents.height);
+ gtk_render_layout(style_context, cr, TOOLTIP_OFFSET/2, TOOLTIP_OFFSET/2, layout);
+
+ warning_tooltip_ = texture_ptr_from_cairo_graphics(cg);
+}
+
void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
{
glib::String font_name;
@@ -175,7 +325,6 @@ void TextInput::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
nux::GetPainter().PushLayer(GfxContext, highlight_layer_->GetGeometry(), highlight_layer_.get());
}
-
if (!IsFullRedraw())
{
gPainter.PushLayer(GfxContext, bg_layer_->GetGeometry(), bg_layer_.get());
@@ -187,6 +336,9 @@ void TextInput::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
layout_->ProcessDraw(GfxContext, force_draw);
+ if (caps_lock_on && mouse_over_warning_icon_)
+ PaintWarningTooltip(GfxContext);
+
if (!IsFullRedraw())
{
gPainter.PopBackground();
@@ -199,6 +351,18 @@ void TextInput::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
GfxContext.PopClippingRectangle();
}
+void TextInput::PaintWarningTooltip(nux::GraphicsEngine& graphics_engine)
+{
+ nux::Geometry warning_geo = warning_->GetGeometry();
+
+ nux::Geometry tooltip_geo = {warning_geo.x - (warning_tooltip_->GetWidth() + TOOLTIP_OFFSET / 2),
+ warning_geo.y - TOOLTIP_Y_OFFSET,
+ warning_tooltip_->GetWidth(),
+ warning_tooltip_->GetHeight()};
+
+ nux::GetPainter().PushDrawLayer(graphics_engine, tooltip_geo, CreateWarningLayer(warning_tooltip_.GetPointer()));
+}
+
void TextInput::UpdateBackground(bool force)
{
int RADIUS = 5;
@@ -254,6 +418,16 @@ void TextInput::UpdateBackground(bool force)
texture2D->UnReference();
}
+void TextInput::OnKeyUp(unsigned keysym,
+ unsigned long keycode,
+ unsigned long state)
+{
+ if (!caps_lock_on && keysym == NUX_VK_CAPITAL)
+ caps_lock_on = true;
+ else if (caps_lock_on && keysym == NUX_VK_CAPITAL)
+ caps_lock_on = false;
+}
+
void TextInput::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
{
hint_->SetVisible(false);
diff --git a/unity-shared/TextInput.h b/unity-shared/TextInput.h
index 462474d6e..1e708511e 100644
--- a/unity-shared/TextInput.h
+++ b/unity-shared/TextInput.h
@@ -62,6 +62,8 @@ public:
void SetSpinnerVisible(bool visible);
void SetSpinnerState(SpinnerState spinner_state);
+ void EnableCapsLockWarning() const;
+
IMTextEntry* text_entry() const;
nux::RWProperty<std::string> input_string;
@@ -70,6 +72,7 @@ public:
nux::Property<int> hint_font_size;
nux::ROProperty<bool> im_active;
nux::ROProperty<bool> im_preedit;
+ nux::Property<bool> show_caps_lock;
private:
void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
@@ -83,9 +86,20 @@ private:
void AddProperties(debug::IntrospectionData&);
bool AcceptKeyNavFocus();
+ bool ShouldBeHighlighted();
+
+ nux::Geometry GetWaringIconGeometry() const;
+ void CheckIfCapsLockOn();
+
+ nux::ObjectPtr<nux::BaseTexture> LoadWarningIcon(int icon_size);
+ void LoadWarningTooltip();
+
+ void PaintWarningTooltip(nux::GraphicsEngine& graphics_engine);
+
protected:
void OnInputHintChanged();
void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
+ void OnKeyUp(unsigned keysym, unsigned long keycode, unsigned long state);
void OnEndKeyFocus();
// getters & setters
@@ -100,20 +114,21 @@ protected:
IMTextEntry* pango_entry_;
private:
-
- bool ShouldBeHighlighted();
-
std::unique_ptr<nux::AbstractPaintLayer> bg_layer_;
std::unique_ptr<nux::AbstractPaintLayer> highlight_layer_;
nux::HLayout* layout_;
nux::LayeredLayout* layered_layout_;
SearchBarSpinner* spinner_;
+ nux::Property<bool> caps_lock_on;
int last_width_;
int last_height_;
+ bool mouse_over_warning_icon_;
- glib::SignalManager sig_manager_;
+ IconTexture* warning_;
+ nux::ObjectPtr<nux::BaseTexture> warning_tooltip_;
+ glib::SignalManager sig_manager_;
};
}
diff --git a/unity-shared/UnityWindowStyle.cpp b/unity-shared/UnityWindowStyle.cpp
index 9fbccbe75..598380a2c 100644
--- a/unity-shared/UnityWindowStyle.cpp
+++ b/unity-shared/UnityWindowStyle.cpp
@@ -21,9 +21,13 @@
#include <NuxCore/Logger.h>
+#include "UnitySettings.h"
#include "UnityWindowStyle.h"
+#include "UScreen.h"
#include "config.h"
+#include <unordered_set>
+
namespace unity
{
namespace ui
@@ -38,14 +42,31 @@ namespace
const char* const DIALOG_HIGHLIGHT = PKGDATADIR"/dialog_close_highlight.png";
const char* const DIALOG_PRESS = PKGDATADIR"/dialog_close_press.png";
- double const DEFAULT_SCALE = 1.0;
+
+ RawPixel const INTERNAL_OFFSET = 20_em;
+ RawPixel const BORDER_SIZE = 30_em;
+ RawPixel const CLOSE_PADDING = 3_em;
}
DECLARE_LOGGER(logger, "unity.ui.unity.window.style");
+
UnityWindowStyle::UnityWindowStyle()
{
- LoadAllTextureInScale(DEFAULT_SCALE);
+ unsigned monitors = UScreen::GetDefault()->GetPluggedMonitorsNumber();
+ auto& settings = Settings::Instance();
+
+ // Pre-load scale values per monitor
+ for (unsigned i = 0; i < monitors; ++i)
+ {
+ double scale = settings.Instance().em(i)->DPIScale();
+
+ if (unity_window_textures_.find(scale) == unity_window_textures_.end())
+ LoadAllTextureInScale(scale);
+ }
+
+ settings.Instance().dpi_changed.connect(sigc::mem_fun(this, &UnityWindowStyle::CleanUpUnusedTextures));
+ UScreen::GetDefault()->changed.connect(sigc::mem_fun(this, &UnityWindowStyle::OnMonitorChanged));
}
void UnityWindowStyle::LoadAllTextureInScale(double scale)
@@ -76,6 +97,35 @@ RawPixel UnityWindowStyle::GetDefaultMaxTextureSize(const char* const texture_na
return max_size;
}
+void UnityWindowStyle::OnMonitorChanged(int primary, std::vector<nux::Geometry> const& monitors)
+{
+ CleanUpUnusedTextures();
+}
+
+// Get current in use scale values, if a scaled value is allocated, but
+// not in use clean up the scaled textures in unity_window_textures
+void UnityWindowStyle::CleanUpUnusedTextures()
+{
+ unsigned monitors = UScreen::GetDefault()->GetPluggedMonitorsNumber();
+ auto& settings = Settings::Instance();
+ std::unordered_set<double> used_scales;
+
+ for (unsigned i = 0; i < monitors; ++i)
+ used_scales.insert(settings.em(i)->DPIScale());
+
+ for (auto it = unity_window_textures_.begin(); it != unity_window_textures_.end();)
+ {
+ if (used_scales.find(it->first) == used_scales.end())
+ {
+ it = unity_window_textures_.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
UnityWindowStyle::Ptr const& UnityWindowStyle::Get()
{
// This is set only the first time;
@@ -83,19 +133,19 @@ UnityWindowStyle::Ptr const& UnityWindowStyle::Get()
return instance;
}
-int UnityWindowStyle::GetBorderSize() const
+int UnityWindowStyle::GetBorderSize(double scale) const
{
- return 30; // as measured from textures
+ return BORDER_SIZE.CP(scale); // as measured from textures
}
-int UnityWindowStyle::GetInternalOffset() const
+int UnityWindowStyle::GetInternalOffset(double scale) const
{
- return 20;
+ return INTERNAL_OFFSET.CP(scale);
}
-int UnityWindowStyle::GetCloseButtonPadding() const
+int UnityWindowStyle::GetCloseButtonPadding(double scale) const
{
- return 3;
+ return CLOSE_PADDING.CP(scale);
}
UnityWindowStyle::BaseTexturePtr UnityWindowStyle::GetTexture(double scale, WindowTextureType const& type)
diff --git a/unity-shared/UnityWindowStyle.h b/unity-shared/UnityWindowStyle.h
index cc04f7d5e..99080a735 100644
--- a/unity-shared/UnityWindowStyle.h
+++ b/unity-shared/UnityWindowStyle.h
@@ -52,9 +52,9 @@ public:
static UnityWindowStyle::Ptr const& Get();
BaseTexturePtr GetTexture(double scale, WindowTextureType const& type);
- int GetCloseButtonPadding() const;
- int GetBorderSize() const;
- int GetInternalOffset() const;
+ int GetCloseButtonPadding(double scale) const;
+ int GetBorderSize(double scale) const;
+ int GetInternalOffset(double scale) const;
private:
UnityWindowStyle();
@@ -63,6 +63,9 @@ private:
void LoadAllTextureInScale(double scale);
nux::BaseTexture* LoadTexture(double scale, const char* const texture_name) const;
RawPixel GetDefaultMaxTextureSize(const char* const texture_name) const;
+
+ void OnMonitorChanged(int primary, std::vector<nux::Geometry> const& monitors);
+ void CleanUpUnusedTextures();
typedef std::array<BaseTexturePtr, size_t(WindowTextureType::Size)> UnityWindowTextures;
std::unordered_map<double, UnityWindowTextures> unity_window_textures_;
diff --git a/unity-shared/UnityWindowView.cpp b/unity-shared/UnityWindowView.cpp
index b88a180ae..f751386f7 100644
--- a/unity-shared/UnityWindowView.cpp
+++ b/unity-shared/UnityWindowView.cpp
@@ -33,8 +33,7 @@ UnityWindowView::UnityWindowView(NUX_FILE_LINE_DECL)
, style(UnityWindowStyle::Get())
, closable(false)
, monitor(0)
- , scale(1.0)
- , cv_(Settings::Instance().em())
+ , scale(Settings::Instance().em()->DPIScale())
, internal_layout_(nullptr)
, bg_helper_(this)
{
@@ -49,7 +48,6 @@ UnityWindowView::UnityWindowView(NUX_FILE_LINE_DECL)
});
live_background = false;
- scale = cv_->DPIScale();
monitor.changed.connect(sigc::hide(sigc::mem_fun(this, &UnityWindowView::OnDPIChanged)));
Settings::Instance().dpi_changed.connect(sigc::mem_fun(this, &UnityWindowView::OnDPIChanged));
@@ -68,12 +66,11 @@ UnityWindowView::~UnityWindowView()
void UnityWindowView::OnDPIChanged()
{
- cv_ = Settings::Instance().em(monitor());
- scale = cv_->DPIScale();
+ scale = Settings::Instance().em(monitor())->DPIScale();
if (internal_layout_)
{
- int offset = cv_->CP(style()->GetInternalOffset());
+ int offset = style()->GetInternalOffset(scale);
view_layout_->SetPadding(offset, offset);
}
}
@@ -140,9 +137,8 @@ void UnityWindowView::OnClosableChanged(bool closable)
return;
}
- auto const& texture = style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON);
- int padding_raw = style()->GetCloseButtonPadding();
- int padding = cv_->CP(padding_raw);
+ auto const& texture = style()->GetTexture(scale, WindowTextureType::CLOSE_ICON);
+ int padding = style()->GetCloseButtonPadding(scale);
close_button_ = new IconTexture(texture);
close_button_->SetBaseXY(padding, padding);
@@ -150,29 +146,29 @@ void UnityWindowView::OnClosableChanged(bool closable)
close_button_->mouse_enter.connect([this](int, int, unsigned long, unsigned long) {
if (close_button_->IsMouseOwner())
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON_PRESSED));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON_PRESSED));
else
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
});
close_button_->mouse_leave.connect([this](int, int, unsigned long, unsigned long) {
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON));
});
close_button_->mouse_down.connect([this](int, int, unsigned long, unsigned long) {
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON_PRESSED));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON_PRESSED));
});
close_button_->mouse_up.connect([this](int, int, unsigned long, unsigned long) {
bool inside = close_button_->IsMouseInside();
if (inside)
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
else
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON));
});
close_button_->mouse_click.connect([this](int, int, unsigned long, unsigned long) {
- close_button_->SetTexture(style()->GetTexture(cv_->DPIScale(), WindowTextureType::CLOSE_ICON));
+ close_button_->SetTexture(style()->GetTexture(scale, WindowTextureType::CLOSE_ICON));
request_close.emit();
});
@@ -183,7 +179,7 @@ bool UnityWindowView::SetLayout(nux::Layout* layout)
{
if (layout && layout->IsLayout())
{
- int offset = cv_->CP(style()->GetInternalOffset());
+ int offset = style()->GetInternalOffset(scale);
// We wrap the internal layout adding some padding, so that inherited classes
// can ignore the offsets we define here.
@@ -208,7 +204,8 @@ nux::Layout* UnityWindowView::GetLayout()
nux::Geometry UnityWindowView::GetInternalBackground()
{
- int offset = cv_->CP(style()->GetInternalOffset());
+ int offset = style()->GetInternalOffset(scale);
+
return GetBackgroundGeometry().GetExpand(-offset, -offset);
}
@@ -358,8 +355,7 @@ void UnityWindowView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
void UnityWindowView::DrawBackground(nux::GraphicsEngine& GfxContext, nux::Geometry const& geo)
{
- int border = cv_->CP(style()->GetBorderSize());
- float scale = cv_->DPIScale();
+ int border = style()->GetBorderSize(scale);
auto background_corner_textrue = style()->GetTexture(scale, WindowTextureType::BACKGROUND_CORNER)->GetDeviceTexture();
diff --git a/unity-shared/UnityWindowView.h b/unity-shared/UnityWindowView.h
index 00df54147..880390811 100644
--- a/unity-shared/UnityWindowView.h
+++ b/unity-shared/UnityWindowView.h
@@ -23,7 +23,6 @@
#include "unity-shared/BackgroundEffectHelper.h"
#include "unity-shared/IconTexture.h"
-#include "unity-shared/EMConverter.h"
#include "Introspectable.h"
#include "UnityWindowStyle.h"
@@ -81,7 +80,6 @@ private:
void OnClosableChanged(bool closable);
void DrawBackground(nux::GraphicsEngine& GfxContext, nux::Geometry const& geo);
- EMConverter::Ptr cv_;
nux::Layout *internal_layout_;
BackgroundEffectHelper bg_helper_;
nux::ObjectPtr<nux::InputArea> bounding_area_;