summaryrefslogtreecommitdiff
diff options
-rw-r--r--CMakeLists.txt2
-rw-r--r--dash/ApplicationStarter.h2
-rw-r--r--dash/ApplicationStarterImp.cpp2
-rw-r--r--dash/DashView.cpp8
-rw-r--r--dash/DashView.h2
-rw-r--r--dash/ResultViewGrid.cpp4
-rw-r--r--hud/HudController.cpp4
-rw-r--r--hud/HudView.cpp31
-rw-r--r--launcher/AbstractLauncherIcon.h18
-rw-r--r--launcher/ApplicationLauncherIcon.cpp210
-rw-r--r--launcher/Launcher.cpp5
-rw-r--r--launcher/LauncherController.cpp12
-rw-r--r--launcher/LauncherIcon.cpp34
-rw-r--r--launcher/LauncherIcon.h7
-rw-r--r--launcher/MockLauncherIcon.h1
-rw-r--r--launcher/StandaloneLauncher.cpp7
-rw-r--r--launcher/SwitcherController.cpp4
-rw-r--r--launcher/TooltipManager.cpp104
-rw-r--r--launcher/TooltipManager.h23
-rw-r--r--plugins/unityshell/src/unity-launcher-icon-accessible.cpp2
-rw-r--r--plugins/unityshell/src/unityshell.cpp1
-rw-r--r--po/POTFILES.in1
-rw-r--r--resources/launcher_icon_back_170.pngbin6990 -> 0 bytes
-rw-r--r--resources/launcher_icon_edge_150.pngbin1152 -> 4983 bytes
-rw-r--r--resources/launcher_icon_edge_170.pngbin4909 -> 0 bytes
-rw-r--r--resources/launcher_icon_edge_54.pngbin437 -> 2709 bytes
-rw-r--r--resources/launcher_icon_selected_back_170.pngbin3788 -> 0 bytes
-rw-r--r--resources/launcher_icon_selected_edge_170.pngbin4642 -> 0 bytes
-rw-r--r--resources/launcher_icon_shine_170.pngbin11408 -> 0 bytes
-rw-r--r--resources/launcher_pip_large_ltr.pngbin0 -> 266 bytes
-rw-r--r--resources/launcher_pip_large_rtl.pngbin0 -> 266 bytes
-rw-r--r--shutdown/SessionButton.cpp38
-rw-r--r--shutdown/SessionButton.h14
-rw-r--r--shutdown/SessionView.cpp20
-rw-r--r--tests/CMakeLists.txt27
-rw-r--r--tests/autopilot/unity/emulators/launcher.py2
-rw-r--r--tests/autopilot/unity/tests/launcher/test_icon_behavior.py2
-rw-r--r--tests/autopilot/unity/tests/test_dash.py6
-rw-r--r--tests/autopilot/unity/tests/test_hud.py11
-rw-r--r--tests/test_application_launcher_icon.cpp68
-rw-r--r--tests/test_im_text_entry.cpp65
-rw-r--r--tests/test_im_text_entry.h47
-rw-r--r--tests/test_im_text_entry_class.cpp41
-rw-r--r--tests/test_im_text_entry_slow.cpp46
-rw-r--r--tests/test_session_button.cpp49
-rw-r--r--tests/test_session_view.cpp64
-rw-r--r--tests/test_tooltip_manager.cpp79
-rw-r--r--unity-shared/CoverArt.cpp7
-rw-r--r--unity-shared/IconRenderer.cpp485
-rw-r--r--unity-shared/IconRenderer.h7
-rw-r--r--unity-shared/SearchBar.cpp2
-rw-r--r--unity-shared/SearchBar.h1
-rw-r--r--unity-shared/StaticCairoText.cpp118
-rw-r--r--unity-shared/Timer.h1
54 files changed, 985 insertions, 699 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1839bde69..70b66c195 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -153,7 +153,7 @@ find_package (Gettext REQUIRED)
set (COMPIZ_I18N_DIR ${CMAKE_SOURCE_DIR}/po)
add_custom_command (OUTPUT ${CMAKE_SOURCE_DIR}/po/unity.pot
- COMMAND xgettext -c --files-from ${CMAKE_SOURCE_DIR}/po/POTFILES.in --keyword=_ -o ${CMAKE_SOURCE_DIR}/po/unity.pot --copyright-holder="Canonical Ltd" --msgid-bugs-address="ayatana-dev@lists.launchpad.net" --no-wrap --no-location
+ COMMAND xgettext -c --from-code=UTF-8 --files-from ${CMAKE_SOURCE_DIR}/po/POTFILES.in --keyword=_ -o ${CMAKE_SOURCE_DIR}/po/unity.pot --copyright-holder="Canonical Ltd" --msgid-bugs-address="ayatana-dev@lists.launchpad.net" --no-wrap --no-location
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
diff --git a/dash/ApplicationStarter.h b/dash/ApplicationStarter.h
index 817a5466d..d74f302fe 100644
--- a/dash/ApplicationStarter.h
+++ b/dash/ApplicationStarter.h
@@ -32,6 +32,8 @@ class ApplicationStarter : boost::noncopyable
public:
typedef std::shared_ptr<ApplicationStarter> Ptr;
+ virtual ~ApplicationStarter() {}
+
virtual bool Launch(std::string const& application_name, Time timestamp) = 0;
};
diff --git a/dash/ApplicationStarterImp.cpp b/dash/ApplicationStarterImp.cpp
index bdc75aab4..021649109 100644
--- a/dash/ApplicationStarterImp.cpp
+++ b/dash/ApplicationStarterImp.cpp
@@ -37,7 +37,7 @@ bool ApplicationStarterImp::Launch(std::string const& application_name, Time tim
GdkDisplay* display = gdk_display_get_default();
glib::Object<GdkAppLaunchContext> app_launch_context(gdk_display_get_app_launch_context(display));
- if (timestamp >= 0)
+ if (timestamp > 0)
gdk_app_launch_context_set_timestamp(app_launch_context, timestamp);
while (true)
diff --git a/dash/DashView.cpp b/dash/DashView.cpp
index 17af8d43e..d0d30ae85 100644
--- a/dash/DashView.cpp
+++ b/dash/DashView.cpp
@@ -200,7 +200,7 @@ void DashView::OnUriActivated(ResultView::ActivateType type, std::string const&
int row_height = 0;
int results_to_the_left = 0;
int results_to_the_right = 0;
- g_variant_get(data, "(iiiiiii)", &last_activated_timestamp_, &column_x, &row_y, &column_width, &row_height, &results_to_the_left, &results_to_the_right);
+ g_variant_get(data, "(tiiiiii)", &last_activated_timestamp_, &column_x, &row_y, &column_width, &row_height, &results_to_the_left, &results_to_the_right);
preview_state_machine_.SetSplitPosition(SplitPosition::CONTENT_AREA, row_y);
preview_state_machine_.left_results = results_to_the_left;
@@ -703,7 +703,11 @@ void DashView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw
renderer_.DrawInner(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo);
nux::Geometry const& geo_layout(layout_->GetGeometry());
- graphics_engine.PushClippingRectangle(geo_layout);
+
+ // See lp bug: 1125346 (The sharp white line between dash and launcher is missing)
+ nux::Geometry clip_geo = geo_layout;
+ clip_geo.x += 1;
+ graphics_engine.PushClippingRectangle(clip_geo);
if (IsFullRedraw())
{
diff --git a/dash/DashView.h b/dash/DashView.h
index 37c06bfed..eb929f706 100644
--- a/dash/DashView.h
+++ b/dash/DashView.h
@@ -162,7 +162,7 @@ private:
OverlayRenderer renderer_;
std::string last_activated_uri_;
- Time last_activated_timestamp_;
+ guint64 last_activated_timestamp_;
bool search_in_progress_;
bool activate_on_finish_;
diff --git a/dash/ResultViewGrid.cpp b/dash/ResultViewGrid.cpp
index 4f52952d5..d81341474 100644
--- a/dash/ResultViewGrid.cpp
+++ b/dash/ResultViewGrid.cpp
@@ -208,8 +208,8 @@ void ResultViewGrid::Activate(std::string const& uri, int index, ResultView::Act
}
active_index_ = index;
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
- glib::Variant data(g_variant_new("(iiiiiii)", timestamp, column_x, row_y, column_width, row_height, left_results, right_results));
+ guint64 timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
+ glib::Variant data(g_variant_new("(tiiiiii)", timestamp, column_x, row_y, column_width, row_height, left_results, right_results));
UriActivated.emit(uri, type, data);
}
diff --git a/hud/HudController.cpp b/hud/HudController.cpp
index 2c57aea12..71895a679 100644
--- a/hud/HudController.cpp
+++ b/hud/HudController.cpp
@@ -484,7 +484,7 @@ void Controller::OnSearchChanged(std::string search_string)
void Controller::OnSearchActivated(std::string search_string)
{
- unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ unsigned int timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
hud_service_.ExecuteQueryBySearch(search_string, timestamp);
ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
}
@@ -492,7 +492,7 @@ void Controller::OnSearchActivated(std::string search_string)
void Controller::OnQueryActivated(Query::Ptr query)
{
LOG_DEBUG(logger) << "Activating query, " << query->formatted_text;
- unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ unsigned int timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
hud_service_.ExecuteQuery(query, timestamp);
ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
}
diff --git a/hud/HudView.cpp b/hud/HudView.cpp
index ebea81ae4..e32190218 100644
--- a/hud/HudView.cpp
+++ b/hud/HudView.cpp
@@ -114,6 +114,11 @@ View::View()
}
});
+ mouse_move.connect([this] (int x, int y, int dx, int dy, unsigned long mouse_button, unsigned long special_key) {
+ for (auto button : buttons_)
+ button->SetInputEventSensitivity(true);
+ });
+
mouse_down.connect(sigc::mem_fun(this, &View::OnMouseButtonDown));
QueueDraw();
@@ -133,7 +138,6 @@ void View::ProcessGrowShrink()
{
float diff = g_get_monotonic_time() - start_time_;
int target_height = content_layout_->GetGeometry().height;
-
// only animate if we are after our defined pause time
if (diff > pause_before_grow_length)
{
@@ -151,12 +155,18 @@ void View::ProcessGrowShrink()
//shrink
new_height = last_height - ((last_height - target_height) * progress);
}
+
LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")"
<< "View height: " << GetGeometry().height;
current_height_ = new_height;
}
+ for (auto button : buttons_)
+ {
+ button->SetSkipDraw((button->GetAbsoluteY() + button->GetBaseHeight()) > (GetAbsoluteY() + current_height_));
+ }
+
if (diff > grow_anim_length + pause_before_grow_length)
{
// ensure we are at our final location and update last known height
@@ -175,13 +185,8 @@ void View::ProcessGrowShrink()
return false;
}));
}
-
- // Do this after we check if we are finished, it will skip drawing buttons otherwise
- for (auto button : buttons_)
- button->SetSkipDraw((button->GetAbsoluteY() + button->GetBaseHeight()) > (GetAbsoluteY() + current_height_));
}
-
void View::ResetToDefault()
{
SetQueries(Hud::Queries());
@@ -227,6 +232,7 @@ void View::SetQueries(Hud::Queries queries)
HudButton::Ptr button(new HudButton());
buttons_.push_front(button);
+ button->SetInputEventSensitivity(false);
button->SetMinimumWidth(content_width);
button->SetMaximumWidth(content_width);
button->SetQuery(query);
@@ -237,7 +243,7 @@ void View::SetQueries(Hud::Queries queries)
query_activated.emit(dynamic_cast<HudButton*>(view)->GetQuery());
});
- button->mouse_move.connect([&](int x, int y, int dx, int dy, unsigned long mouse_button, unsigned long special_key) {
+ button->mouse_move.connect([this](int x, int y, int dx, int dy, unsigned long mouse_button, unsigned long special_key) {
if (keyboard_stole_focus_)
{
MouseStealsHudButtonFocus();
@@ -245,19 +251,19 @@ void View::SetQueries(Hud::Queries queries)
}
});
- button->mouse_enter.connect([&](int x, int y, unsigned long mouse_button, unsigned long special_key) {
+ button->mouse_enter.connect([this](int x, int y, unsigned long mouse_button, unsigned long special_key) {
MouseStealsHudButtonFocus();
});
- button->mouse_leave.connect([&](int x, int y, unsigned long mouse_button, unsigned long special_key) {
+ button->mouse_leave.connect([this](int x, int y, unsigned long mouse_button, unsigned long special_key) {
SelectLastFocusedButton();
});
- button->key_nav_focus_activate.connect([&](nux::Area* area) {
+ button->key_nav_focus_activate.connect([this](nux::Area* area) {
query_activated.emit(dynamic_cast<HudButton*>(area)->GetQuery());
});
- button->key_nav_focus_change.connect([&](nux::Area* area, bool recieving, nux::KeyNavDirection direction){
+ button->key_nav_focus_change.connect([this](nux::Area* area, bool recieving, nux::KeyNavDirection direction){
if (recieving)
query_selected.emit(dynamic_cast<HudButton*>(area)->GetQuery());
});
@@ -346,7 +352,6 @@ void View::AboutToHide()
visible_ = false;
overlay_window_buttons_->Hide();
renderer_.AboutToHide();
- ResetToDefault();
}
void View::SetupViews()
@@ -419,9 +424,7 @@ void View::OnSearchChanged(std::string const& search_string)
search_changed.emit(search_string);
for(auto button : buttons_)
- {
button->fake_focused = false;
- }
if (!buttons_.empty())
buttons_.back()->fake_focused = true;
diff --git a/launcher/AbstractLauncherIcon.h b/launcher/AbstractLauncherIcon.h
index 7bf6e1ee5..859ab56ba 100644
--- a/launcher/AbstractLauncherIcon.h
+++ b/launcher/AbstractLauncherIcon.h
@@ -41,10 +41,9 @@ namespace unity
namespace launcher
{
-class ActionArg
+struct ActionArg
{
-public:
- enum Source
+ enum class Source
{
LAUNCHER,
SWITCHER,
@@ -52,25 +51,24 @@ public:
};
ActionArg()
- : source(OTHER)
+ : source(Source::OTHER)
, button(0)
+ , timestamp(0)
, target(0)
, monitor(-1)
- {
- }
+ {}
- ActionArg(Source source, int button, Time timestamp = -1, Window target = 0, int monitor = -1)
+ ActionArg(Source source, int button, unsigned long timestamp = 0, Window target = 0, int monitor = -1)
: source(source)
, button(button)
, timestamp(timestamp)
, target(target)
, monitor(monitor)
- {
- }
+ {}
Source source;
int button;
- Time timestamp;
+ unsigned long timestamp;
Window target;
int monitor;
};
diff --git a/launcher/ApplicationLauncherIcon.cpp b/launcher/ApplicationLauncherIcon.cpp
index cf1697613..2e0e70691 100644
--- a/launcher/ApplicationLauncherIcon.cpp
+++ b/launcher/ApplicationLauncherIcon.cpp
@@ -90,68 +90,68 @@ ApplicationLauncherIcon::ApplicationLauncherIcon(ApplicationPtr const& app)
// Lambda functions should be fine here because when the application the icon
// is only ever removed when the application is closed.
app->window_opened.connect([this](ApplicationWindow const&) {
- EnsureWindowState();
- UpdateMenus();
- UpdateIconGeometries(GetCenters());
- });
- app->window_closed.connect([this]() { EnsureWindowState(); });
- app->window_moved.connect([this](ApplicationWindow const&) { EnsureWindowState(); });
+ EnsureWindowState();
+ UpdateMenus();
+ UpdateIconGeometries(GetCenters());
+ });
+ app->window_closed.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
+ app->window_moved.connect(sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState)));
app->urgent.changed.connect([this](bool const& urgent) {
- LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");
- SetQuirk(Quirk::URGENT, urgent);
- });
+ LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");
+ SetQuirk(Quirk::URGENT, urgent);
+ });
app->active.changed.connect([this](bool const& active) {
- LOG_DEBUG(logger) << tooltip_text() << " active now " << (active ? "true" : "false");
- SetQuirk(Quirk::ACTIVE, active);
- });
+ LOG_DEBUG(logger) << tooltip_text() << " active now " << (active ? "true" : "false");
+ SetQuirk(Quirk::ACTIVE, active);
+ });
app->running.changed.connect([this](bool const& running) {
- LOG_DEBUG(logger) << tooltip_text() << " running now " << (running ? "true" : "false");
- SetQuirk(Quirk::RUNNING, running);
-
- if (running)
- {
- _source_manager.Remove(ICON_REMOVE_TIMEOUT);
-
- /* It can happen that these values are not set
- * during initialization if the view is closed
- * very early, so we need to make sure that they
- * are updated as soon as the view is re-opened. */
- if (tooltip_text().empty())
- tooltip_text = app_->title();
-
- if (icon_name == DEFAULT_ICON)
- {
- std::string icon = app_->icon();
- icon_name = (icon.empty() ? DEFAULT_ICON : icon);
- }
-
- EnsureWindowState();
- UpdateIconGeometries(GetCenters());
- }
- });
+ LOG_DEBUG(logger) << tooltip_text() << " running now " << (running ? "true" : "false");
+ SetQuirk(Quirk::RUNNING, running);
+
+ if (running)
+ {
+ _source_manager.Remove(ICON_REMOVE_TIMEOUT);
+
+ /* It can happen that these values are not set
+ * during initialization if the view is closed
+ * very early, so we need to make sure that they
+ * are updated as soon as the view is re-opened. */
+ if (tooltip_text().empty())
+ tooltip_text = app_->title();
+
+ if (icon_name == DEFAULT_ICON)
+ {
+ std::string icon = app_->icon();
+ icon_name = (icon.empty() ? DEFAULT_ICON : icon);
+ }
+
+ EnsureWindowState();
+ UpdateIconGeometries(GetCenters());
+ }
+ });
app->visible.changed.connect([this](bool const& visible) {
- if (!IsSticky())
- SetQuirk(Quirk::VISIBLE, visible);
- });
+ if (!IsSticky())
+ SetQuirk(Quirk::VISIBLE, visible);
+ });
app->closed.connect([this]() {
- if (!IsSticky())
- {
- SetQuirk(Quirk::VISIBLE, false);
-
- /* Use a timeout to remove the icon, this avoids
- * that we remove an application that is going
- * to be reopened soon. So applications that
- * have a splash screen won't be removed from
- * the launcher while the splash is closed and
- * a new window is opened. */
- _source_manager.AddTimeoutSeconds(1, [&] {
- Remove();
- return false;
- }, ICON_REMOVE_TIMEOUT);
- }
- });
+ if (!IsSticky())
+ {
+ SetQuirk(Quirk::VISIBLE, false);
+
+ /* Use a timeout to remove the icon, this avoids
+ * that we remove an application that is going
+ * to be reopened soon. So applications that
+ * have a splash screen won't be removed from
+ * the launcher while the splash is closed and
+ * a new window is opened. */
+ _source_manager.AddTimeoutSeconds(1, [this] {
+ Remove();
+ return false;
+ }, ICON_REMOVE_TIMEOUT);
+ }
+ });
WindowManager& wm = WindowManager::Default();
wm.window_minimized.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMinimized));
@@ -262,7 +262,7 @@ void ApplicationLauncherIcon::ActivateLauncherIcon(ActionArg arg)
* an unmapped (!= minimized) window around and
* if so force "Focus" behaviour */
- if (arg.source != ActionArg::SWITCHER)
+ if (arg.source != ActionArg::Source::SWITCHER)
{
user_visible = app_->visible();
@@ -339,7 +339,7 @@ void ApplicationLauncherIcon::ActivateLauncherIcon(ActionArg arg)
}
else // #2 above
{
- if (arg.source != ActionArg::SWITCHER)
+ if (arg.source != ActionArg::Source::SWITCHER)
{
Spread(true, 0, false);
}
@@ -350,7 +350,7 @@ void ApplicationLauncherIcon::ActivateLauncherIcon(ActionArg arg)
if (scaleWasActive) // #4 above
{
Focus(arg);
- if (arg.source != ActionArg::SWITCHER)
+ if (arg.source != ActionArg::Source::SWITCHER)
Spread(true, 0, false);
}
else // #3 above
@@ -443,7 +443,7 @@ void ApplicationLauncherIcon::OnWindowMoved(guint32 moved_win)
if (!app_->OwnsWindow(moved_win))
return;
- _source_manager.AddTimeout(250, [&] {
+ _source_manager.AddTimeout(250, [this] {
EnsureWindowState();
UpdateIconGeometries(GetCenters());
@@ -468,31 +468,32 @@ void ApplicationLauncherIcon::UpdateDesktopFile()
glib::Object<GFile> desktop_file(g_file_new_for_path(_desktop_file.c_str()));
_desktop_file_monitor = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE,
nullptr, nullptr);
- g_file_monitor_set_rate_limit(_desktop_file_monitor, 1000);
-
- auto sig = new glib::Signal<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(_desktop_file_monitor, "changed",
- [&] (GFileMonitor*, GFile* f, GFile*, GFileMonitorEvent event_type) {
- switch (event_type)
- {
- case G_FILE_MONITOR_EVENT_DELETED:
- {
- glib::Object<GFile> file(f, glib::AddRef());
- _source_manager.AddTimeoutSeconds(1, [this, file] {
- if (!g_file_query_exists (file, nullptr))
- UnStick();
- return false;
- });
- break;
- }
- case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
- UpdateDesktopQuickList();
- UpdateBackgroundColor();
- break;
- default:
- break;
- }
- });
- _gsignals.Add(sig);
+ g_file_monitor_set_rate_limit(_desktop_file_monitor, 2000);
+
+ _gsignals.Add<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(_desktop_file_monitor, "changed",
+ [this] (GFileMonitor*, GFile* f, GFile*, GFileMonitorEvent event_type) {
+ switch (event_type)
+ {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ {
+ glib::Object<GFile> file(f, glib::AddRef());
+ _source_manager.AddTimeoutSeconds(1, [this, file] {
+ if (!g_file_query_exists (file, nullptr))
+ UnStick();
+ return false;
+ });
+ break;
+ }
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ {
+ UpdateDesktopQuickList();
+ UpdateBackgroundColor();
+ break;
+ }
+ default:
+ break;
+ }
+ });
}
}
@@ -591,7 +592,7 @@ void ApplicationLauncherIcon::Focus(ActionArg arg)
return;
}
- bool show_only_visible = arg.source == ActionArg::SWITCHER;
+ bool show_only_visible = arg.source == ActionArg::Source::SWITCHER;
app_->Focus(show_only_visible, arg.monitor);
}
@@ -645,7 +646,7 @@ void ApplicationLauncherIcon::UpdateDesktopQuickList()
{
for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next)
{
- _gsignals.Disconnect(l->data, "item-activated");
+ _gsignals.Disconnect(l->data, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED);
}
}
@@ -672,15 +673,12 @@ void ApplicationLauncherIcon::UpdateDesktopQuickList()
dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- dbusmenu_menuitem_property_set(item, "shortcut-nick", nicks[index]);
+ std::string nick(nicks[index]);
- auto sig = new glib::Signal<void, DbusmenuMenuitem*, gint>(item, "item-activated",
- [&] (DbusmenuMenuitem* item, gint) {
- const gchar *nick;
- nick = dbusmenu_menuitem_property_get(item, "shortcut-nick");
- indicator_desktop_shortcuts_nick_exec(_desktop_shortcuts, nick);
- });
- _gsignals.Add(sig);
+ _gsignals.Add<void, DbusmenuMenuitem*, gint>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [this, nick] (DbusmenuMenuitem* item, unsigned) {
+ indicator_desktop_shortcuts_nick_exec(_desktop_shortcuts, nick.c_str());
+ });
dbusmenu_menuitem_child_append(_menu_desktop_shortcuts, item);
index++;
@@ -729,8 +727,8 @@ void ApplicationLauncherIcon::EnsureMenuItemsWindowsReady()
dbusmenu_menuitem_property_set_int(menu_item, QuicklistMenuItem::MAXIMUM_LABEL_WIDTH_PROPERTY, MAXIMUM_QUICKLIST_WIDTH);
Window xid = w->window_id();
- _gsignals.Add<void, DbusmenuMenuitem*, int>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- [xid] (DbusmenuMenuitem*, int) {
+ _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [xid] (DbusmenuMenuitem*, unsigned) {
WindowManager& wm = WindowManager::Default();
wm.Activate(xid);
wm.Raise(xid);
@@ -821,8 +819,8 @@ void ApplicationLauncherIcon::EnsureMenuItemsReady()
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
- _gsignals.Add<void, DbusmenuMenuitem*, int>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- [&] (DbusmenuMenuitem*, int) {
+ _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [this] (DbusmenuMenuitem*, unsigned) {
ToggleSticky();
});
@@ -842,8 +840,8 @@ void ApplicationLauncherIcon::EnsureMenuItemsReady()
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
- _gsignals.Add<void, DbusmenuMenuitem*, int>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- [&] (DbusmenuMenuitem*, int) {
+ _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [this] (DbusmenuMenuitem*, unsigned) {
Quit();
});
@@ -945,9 +943,9 @@ AbstractLauncherIcon::MenuItemsVector ApplicationLauncherIcon::GetMenus()
dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, TRUE);
- _gsignals.Add<void, DbusmenuMenuitem*, int>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- [&] (DbusmenuMenuitem*, int timestamp) {
- _source_manager.AddIdle([&] {
+ _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [this] (DbusmenuMenuitem*, unsigned timestamp) {
+ _source_manager.AddIdle([this, timestamp] {
ActivateLauncherIcon(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
return false;
});
@@ -1102,7 +1100,7 @@ void ApplicationLauncherIcon::OnDndHovered()
void ApplicationLauncherIcon::OnDndEnter()
{
/* Disabled, since the DND code is currently disabled as well.
- _source_manager.AddTimeout(1000, [&] {
+ _source_manager.AddTimeout(1000, [this] {
OnDndHovered();
return false;
}, ICON_DND_OVER_TIMEOUT);
@@ -1152,7 +1150,7 @@ nux::DndAction ApplicationLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_dat
void ApplicationLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
{
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
OpenInstanceWithUris(ValidateUrisForLaunch(dnd_data), timestamp);
}
@@ -1169,7 +1167,7 @@ bool ApplicationLauncherIcon::ShowInSwitcher(bool current)
}
else
{
- for (int i = 0; i < max_num_monitors; i++)
+ for (int i = 0; i < max_num_monitors; ++i)
{
if (WindowVisibleOnMonitor(i))
{
diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp
index ee73cb274..0f4c6f020 100644
--- a/launcher/Launcher.cpp
+++ b/launcher/Launcher.cpp
@@ -303,7 +303,6 @@ void Launcher::SetIconUnderMouse(AbstractLauncherIcon::Ptr const& icon)
icon->mouse_enter.emit(monitor);
_icon_under_mouse = icon;
- tooltip_manager_.SetIcon(icon);
}
bool Launcher::MouseBeyondDragThreshold() const
@@ -2224,7 +2223,7 @@ void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned
void Launcher::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
{
SetMousePosition(x, y);
- tooltip_manager_.MouseMoved();
+ tooltip_manager_.MouseMoved(_icon_under_mouse);
if (!_hidden)
UpdateChangeInMousePosition(dx, dy);
@@ -2245,7 +2244,7 @@ void Launcher::RecvMouseWheel(int /*x*/, int /*y*/, int wheel_delta, unsigned lo
}
else if (_icon_under_mouse)
{
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
auto scroll_direction = (wheel_delta < 0) ? AbstractLauncherIcon::ScrollDirection::DOWN : AbstractLauncherIcon::ScrollDirection::UP;
_icon_under_mouse->PerformScroll(scroll_direction, timestamp);
}
diff --git a/launcher/LauncherController.cpp b/launcher/LauncherController.cpp
index 25da39a3a..eef602458 100644
--- a/launcher/LauncherController.cpp
+++ b/launcher/LauncherController.cpp
@@ -1262,9 +1262,9 @@ bool Controller::HandleLauncherKeyEvent(Display *display, unsigned int key_sym,
if (TimeUtil::TimeDelta(&current, &last_action_time) > local::ignore_repeat_shortcut_duration)
{
if (g_ascii_isdigit((gchar)(*it)->GetShortcut()) && (key_state & ShiftMask))
- (*it)->OpenInstance(ActionArg(ActionArg::LAUNCHER, 0, timestamp));
+ (*it)->OpenInstance(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
else
- (*it)->Activate(ActionArg(ActionArg::LAUNCHER, 0, timestamp));
+ (*it)->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
}
// disable the "tap on super" check
@@ -1384,10 +1384,10 @@ void Controller::KeyNavTerminate(bool activate)
if (activate)
{
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
pimpl->sources_.AddIdle([this, timestamp] {
- pimpl->model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0, timestamp));
+ pimpl->model_->Selection()->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
return false;
});
}
@@ -1488,8 +1488,8 @@ void Controller::Impl::ReceiveLauncherKeyPress(unsigned long eventType,
// <SPACE> (open a new instance)
case NUX_VK_SPACE:
{
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
- model_->Selection()->OpenInstance(ActionArg(ActionArg::LAUNCHER, 0, timestamp));
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
+ model_->Selection()->OpenInstance(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
parent_->KeyNavTerminate(false);
break;
}
diff --git a/launcher/LauncherIcon.cpp b/launcher/LauncherIcon.cpp
index 927df2763..7efe4b458 100644
--- a/launcher/LauncherIcon.cpp
+++ b/launcher/LauncherIcon.cpp
@@ -62,6 +62,8 @@ const std::string UNITY_THEME_NAME = "unity-icon-theme";
const std::string CENTER_STABILIZE_TIMEOUT = "center-stabilize-timeout";
const std::string PRESENT_TIMEOUT = "present-timeout";
const std::string QUIRK_DELAY_TIMEOUT = "quirk-delay-timeout";
+
+const unsigned TOOLTIP_FADE_DURATION = 80;
}
NUX_IMPLEMENT_OBJECT_TYPE(LauncherIcon);
@@ -86,6 +88,7 @@ LauncherIcon::LauncherIcon(IconType type)
, _parent_geo(max_num_monitors)
, _saved_center(max_num_monitors)
, _allow_quicklist_to_show(true)
+ , _tooltip_fade_animator(TOOLTIP_FADE_DURATION)
{
for (unsigned i = 0; i < unsigned(Quirk::LAST); ++i)
{
@@ -115,6 +118,19 @@ LauncherIcon::LauncherIcon(IconType type)
mouse_down.connect(sigc::mem_fun(this, &LauncherIcon::RecvMouseDown));
mouse_up.connect(sigc::mem_fun(this, &LauncherIcon::RecvMouseUp));
mouse_click.connect(sigc::mem_fun(this, &LauncherIcon::RecvMouseClick));
+
+ _tooltip_fade_animator.updated.connect([this] (double opacity) {
+ if (_tooltip)
+ {
+ _tooltip->SetOpacity(opacity);
+
+ if (opacity == 0.0f && _tooltip_fade_animator.GetStartValue() > _tooltip_fade_animator.GetFinishValue())
+ {
+ _tooltip->ShowWindow(false);
+ _tooltip->SetOpacity(0.0f);
+ }
+ }
+ });
}
LauncherIcon::~LauncherIcon()
@@ -143,6 +159,7 @@ LauncherIcon::~LauncherIcon()
void LauncherIcon::LoadTooltip()
{
_tooltip = new Tooltip();
+ _tooltip->SetOpacity(0.0f);
AddChild(_tooltip.GetPointer());
_tooltip->text = tooltip_text();
@@ -522,6 +539,11 @@ LauncherIcon::ShowTooltip()
_tooltip->ShowTooltipWithTipAt(tip_x, tip_y);
_tooltip->ShowWindow(!tooltip_text().empty());
tooltip_visible.emit(_tooltip);
+
+ if (_tooltip_fade_animator.CurrentState() == nux::animation::Animation::State::Running)
+ _tooltip_fade_animator.Reverse();
+ else
+ _tooltip_fade_animator.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
}
void
@@ -651,9 +673,9 @@ void LauncherIcon::RecvMouseUp(int button, int monitor, unsigned long key_flags)
void LauncherIcon::RecvMouseClick(int button, int monitor, unsigned long key_flags)
{
- auto timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
+ auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
- ActionArg arg(ActionArg::LAUNCHER, button, timestamp);
+ ActionArg arg(ActionArg::Source::LAUNCHER, button, timestamp);
arg.monitor = monitor;
bool shift_pressed = nux::GetKeyModifierState(key_flags, nux::NUX_STATE_SHIFT);
@@ -669,7 +691,13 @@ void LauncherIcon::RecvMouseClick(int button, int monitor, unsigned long key_fla
void LauncherIcon::HideTooltip()
{
if (_tooltip)
- _tooltip->ShowWindow(false);
+ {
+ if (_tooltip_fade_animator.CurrentState() == nux::animation::Animation::State::Running)
+ _tooltip_fade_animator.Reverse();
+ else
+ _tooltip_fade_animator.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
+ }
+
tooltip_visible.emit(nux::ObjectPtr<nux::View>(nullptr));
}
diff --git a/launcher/LauncherIcon.h b/launcher/LauncherIcon.h
index 26f8b04e4..68a783b60 100644
--- a/launcher/LauncherIcon.h
+++ b/launcher/LauncherIcon.h
@@ -21,12 +21,9 @@
#ifndef LAUNCHERICON_H
#define LAUNCHERICON_H
-#include <set>
-#include <boost/unordered_map.hpp>
-
#include <Nux/Nux.h>
#include <Nux/BaseWindow.h>
-#include <NuxCore/Math/MathInc.h>
+#include <NuxCore/Animation.h>
#include <gtk/gtk.h>
#include <libdbusmenu-glib/client.h>
@@ -338,6 +335,8 @@ private:
std::list<LauncherEntryRemote::Ptr> _entry_list;
+ nux::animation::AnimateValue<double> _tooltip_fade_animator;
+
protected:
glib::SourceManager _source_manager;
};
diff --git a/launcher/MockLauncherIcon.h b/launcher/MockLauncherIcon.h
index 06e0edb33..e1057515c 100644
--- a/launcher/MockLauncherIcon.h
+++ b/launcher/MockLauncherIcon.h
@@ -22,7 +22,6 @@
#define MOCKLAUNCHERICON_H
#include <Nux/Nux.h>
-#include <NuxCore/Math/MathInc.h>
#include <Nux/BaseWindow.h>
#include <Nux/View.h>
diff --git a/launcher/StandaloneLauncher.cpp b/launcher/StandaloneLauncher.cpp
index 777951f6f..cec0cd82d 100644
--- a/launcher/StandaloneLauncher.cpp
+++ b/launcher/StandaloneLauncher.cpp
@@ -18,7 +18,9 @@
*
*/
-#include "Nux/Nux.h"
+#include <Nux/Nux.h>
+#include <Nux/NuxTimerTickSource.h>
+#include <NuxCore/AnimationController.h>
#include <gtk/gtk.h>
#include "unity-shared/BackgroundEffectHelper.h"
@@ -43,6 +45,7 @@ struct LauncherWindow
{
LauncherWindow()
: wt(nux::CreateGUIThread("Unity Launcher", win_size.width, win_size.height, 0, &LauncherWindow::ThreadWidgetInit, this))
+ , animation_controller(tick_source)
{}
void Show()
@@ -85,6 +88,8 @@ private:
unity::Settings settings;
panel::Style panel_style;
std::shared_ptr<nux::WindowThread> wt;
+ nux::NuxTimerTickSource tick_source;
+ nux::animation::AnimationController animation_controller;
launcher::Controller::Ptr controller;
};
diff --git a/launcher/SwitcherController.cpp b/launcher/SwitcherController.cpp
index 89922e006..bd48fb74f 100644
--- a/launcher/SwitcherController.cpp
+++ b/launcher/SwitcherController.cpp
@@ -426,8 +426,8 @@ void Controller::Impl::Hide(bool accept_state)
Selection selection = GetCurrentSelection();
if (selection.application_)
{
- Time timestamp = -1;
- selection.application_->Activate(ActionArg(ActionArg::SWITCHER, 0,
+ Time timestamp = 0;
+ selection.application_->Activate(ActionArg(ActionArg::Source::SWITCHER, 0,
timestamp, selection.window_));
}
}
diff --git a/launcher/TooltipManager.cpp b/launcher/TooltipManager.cpp
index c34783233..dee8a5103 100644
--- a/launcher/TooltipManager.cpp
+++ b/launcher/TooltipManager.cpp
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Jacob Edwards <j.johan.edwards@gmail.com>
+ * Andrea Azzarone <andrea.azzarone@canonical.com>
*/
#include "TooltipManager.h"
@@ -23,104 +24,69 @@ namespace unity
{
namespace launcher
{
-
namespace
{
-const unsigned int TOOLTIPS_SHOW_TIMEOUT_LENGTH = 1000;
+const unsigned int TOOLTIPS_SHOW_TIMEOUT_LENGTH = 500;
}
TooltipManager::TooltipManager()
- : show_tooltips_(false)
- , hovered_(false)
- , timer_locked_(false)
+ : skip_timeout_(false)
{}
-void TooltipManager::SetIcon(AbstractLauncherIcon::Ptr const& newIcon)
-{
- if (icon_ == newIcon)
+void TooltipManager::MouseMoved(AbstractLauncherIcon::Ptr const& icon_under_mouse)
+{
+ if (icon_ == icon_under_mouse)
return;
- // Unlock hover timer, in case the previous icon had no valid tooltip
- timer_locked_ = false;
-
- if (show_tooltips_)
- {
- // Show new tooltip, get rid of the old olne
- if (icon_)
- icon_->HideTooltip();
- if (newIcon)
- newIcon->ShowTooltip();
- }
- else if (!newIcon)
- {
- // Stop the hover timer for null launcher space
- StopTimer();
- }
- else
- {
- AbstractLauncherIcon::IconType type = newIcon->GetIconType();
- if ((type == AbstractLauncherIcon::IconType::HOME ||
- type == AbstractLauncherIcon::IconType::HUD) &&
- newIcon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
- {
- // Lock the hover timer for no valid tooltip cases
- timer_locked_ = true;
- StopTimer();
- }
- }
+ StopTimer();
+ if (icon_)
+ icon_->HideTooltip();
+
+ icon_ = icon_under_mouse;
- icon_ = newIcon;
+ if (icon_ && !skip_timeout_)
+ ResetTimer(icon_);
+ else if (icon_ && skip_timeout_)
+ icon_->ShowTooltip();
}
-void TooltipManager::SetHover(bool on_launcher)
-{
- if (hovered_ == on_launcher)
- return;
- hovered_ = on_launcher;
-
- if (show_tooltips_ && !hovered_)
- {
- show_tooltips_ = false;
- if (icon_)
- icon_->HideTooltip();
- }
+void TooltipManager::IconClicked()
+{
+ if (icon_)
+ icon_->HideTooltip();
}
-void TooltipManager::MouseMoved()
+void TooltipManager::SetHover(bool hovered)
{
- if (!icon_ || show_tooltips_)
- return;
-
- ResetTimer();
+ if (!hovered)
+ Reset();
}
-void TooltipManager::IconClicked()
+void TooltipManager::Reset()
{
StopTimer();
- if (show_tooltips_ && icon_)
+
+ if (icon_)
icon_->HideTooltip();
- show_tooltips_ = false;
- timer_locked_ = true;
+ icon_ = AbstractLauncherIcon::Ptr();
+ skip_timeout_ = false;
}
-void TooltipManager::ResetTimer()
+void TooltipManager::ResetTimer(AbstractLauncherIcon::Ptr const& icon_under_mouse)
{
- if (timer_locked_)
- return;
-
hover_timer_.reset(new glib::Timeout(TOOLTIPS_SHOW_TIMEOUT_LENGTH));
hover_timer_->Run([&] () {
- show_tooltips_ = true;
- icon_->ShowTooltip();
+ skip_timeout_ = true;
+ icon_under_mouse->ShowTooltip();
return false;
});
-}
-
+ }
+
void TooltipManager::StopTimer()
{
- hover_timer_.reset();
+ hover_timer_.reset();
}
-} // namespace launcher
-} // namespace unity
+}
+}
diff --git a/launcher/TooltipManager.h b/launcher/TooltipManager.h
index f61fc199f..817239d26 100644
--- a/launcher/TooltipManager.h
+++ b/launcher/TooltipManager.h
@@ -15,10 +15,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Jacob Edwards <j.johan.edwards@gmail.com>
+ * Andrea Azzarone <andrea.azzarone@canonical.com>
*/
-#ifndef TOOLTIPMANAGER
-#define TOOLTIPMANAGER
+#ifndef LAUNCHER_TOOLTIP_MANAGER_H
+#define LAUNCHER_TOOLTIP_MANAGER_H
#include <boost/noncopyable.hpp>
#include <UnityCore/GLibSource.h>
@@ -35,23 +36,21 @@ class TooltipManager : public boost::noncopyable
public:
TooltipManager();
- void SetHover(bool on_launcher);
- void SetIcon(AbstractLauncherIcon::Ptr const& newIcon);
- void MouseMoved();
+ void SetHover(bool hovered);
+ void MouseMoved(AbstractLauncherIcon::Ptr const& icon_under_mouse);
void IconClicked();
private:
- void ResetTimer();
+ void Reset();
+ void ResetTimer(AbstractLauncherIcon::Ptr const& icon_under_mouse);
void StopTimer();
- bool show_tooltips_;
- bool hovered_;
+ bool skip_timeout_;
AbstractLauncherIcon::Ptr icon_;
- glib::Source::UniquePtr hover_timer_;
- bool timer_locked_;
+ glib::Source::UniquePtr hover_timer_;
};
-} // namespace launcher
-} // namespace unity
+}
+}
#endif
diff --git a/plugins/unityshell/src/unity-launcher-icon-accessible.cpp b/plugins/unityshell/src/unity-launcher-icon-accessible.cpp
index b0331eb00..66643eadf 100644
--- a/plugins/unityshell/src/unity-launcher-icon-accessible.cpp
+++ b/plugins/unityshell/src/unity-launcher-icon-accessible.cpp
@@ -465,7 +465,7 @@ unity_launcher_icon_accessible_do_action(AtkAction *action,
icon = dynamic_cast<LauncherIcon*>(nux_object);
- icon->Activate(ActionArg(ActionArg::LAUNCHER, 0));
+ icon->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0));
return TRUE;
}
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 0fabcffbb..f06cb360b 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -425,7 +425,6 @@ UnityScreen::~UnityScreen()
notify_uninit();
unity_a11y_finalize();
- ::unity::ui::IconRenderer::DestroyTextures();
QuicklistManager::Destroy();
reset_glib_logging();
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5db06e85e..dd5b73a1f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -33,6 +33,7 @@ shortcuts/ShortcutHintPrivate.cpp
shortcuts/ShortcutView.cpp
shortcuts/CompizShortcutModeller.cpp
shutdown/SessionView.cpp
+shutdown/SessionButton.cpp
services/panel-service.c
unity-shared/DashStyle.cpp
unity-shared/SearchBar.cpp
diff --git a/resources/launcher_icon_back_170.png b/resources/launcher_icon_back_170.png
deleted file mode 100644
index efc6794a4..000000000
--- a/resources/launcher_icon_back_170.png
+++ /dev/null
Binary files differ
diff --git a/resources/launcher_icon_edge_150.png b/resources/launcher_icon_edge_150.png
index df07bd264..9a982fefb 100644
--- a/resources/launcher_icon_edge_150.png
+++ b/resources/launcher_icon_edge_150.png
Binary files differ
diff --git a/resources/launcher_icon_edge_170.png b/resources/launcher_icon_edge_170.png
deleted file mode 100644
index 5ed464976..000000000
--- a/resources/launcher_icon_edge_170.png
+++ /dev/null
Binary files differ
diff --git a/resources/launcher_icon_edge_54.png b/resources/launcher_icon_edge_54.png
index e0f85f305..e97bfdb7f 100644
--- a/resources/launcher_icon_edge_54.png
+++ b/resources/launcher_icon_edge_54.png
Binary files differ
diff --git a/resources/launcher_icon_selected_back_170.png b/resources/launcher_icon_selected_back_170.png
deleted file mode 100644
index 303532ee2..000000000
--- a/resources/launcher_icon_selected_back_170.png
+++ /dev/null
Binary files differ
diff --git a/resources/launcher_icon_selected_edge_170.png b/resources/launcher_icon_selected_edge_170.png
deleted file mode 100644
index 4ec6455fe..000000000
--- a/resources/launcher_icon_selected_edge_170.png
+++ /dev/null
Binary files differ
diff --git a/resources/launcher_icon_shine_170.png b/resources/launcher_icon_shine_170.png
deleted file mode 100644
index 41aba4632..000000000
--- a/resources/launcher_icon_shine_170.png
+++ /dev/null
Binary files differ
diff --git a/resources/launcher_pip_large_ltr.png b/resources/launcher_pip_large_ltr.png
new file mode 100644
index 000000000..33f0a6d45
--- /dev/null
+++ b/resources/launcher_pip_large_ltr.png
Binary files differ
diff --git a/resources/launcher_pip_large_rtl.png b/resources/launcher_pip_large_rtl.png
new file mode 100644
index 000000000..9c036c921
--- /dev/null
+++ b/resources/launcher_pip_large_rtl.png
Binary files differ
diff --git a/shutdown/SessionButton.cpp b/shutdown/SessionButton.cpp
index ef45506c1..8af0b6ee7 100644
--- a/shutdown/SessionButton.cpp
+++ b/shutdown/SessionButton.cpp
@@ -22,7 +22,7 @@
#include <Nux/VLayout.h>
#include <UnityCore/Variant.h>
-
+#include <glib/gi18n-lib.h>
namespace unity
{
@@ -38,15 +38,47 @@ namespace style
NUX_IMPLEMENT_OBJECT_TYPE(Button);
-Button::Button(std::string const& label, std::string const& texture_name, NUX_FILE_LINE_DECL)
+Button::Button(Action action, NUX_FILE_LINE_DECL)
: nux::View(NUX_FILE_LINE_PARAM)
, highlighted(false)
+ , action([this] { return action_; })
, label([this] { return label_view_->GetText(); })
+ , action_(action)
{
SetAcceptKeyNavFocusOnMouseDown(false);
SetAcceptKeyNavFocusOnMouseEnter(true);
- std::string texture_prefix = PKGDATADIR"/" + texture_name;
+ std::string texture_prefix = PKGDATADIR"/";
+ std::string label;
+
+ switch (action_)
+ {
+ case Action::LOCK:
+ texture_prefix += "lockscreen";
+ label = _("Lock");
+ break;
+ case Action::LOGOUT:
+ texture_prefix += "logout";
+ label = _("Log Out");
+ break;
+ case Action::SUSPEND:
+ texture_prefix += "suspend";
+ label = _("Suspend");
+ break;
+ case Action::HIBERNATE:
+ texture_prefix += "hibernate";
+ label = _("Hibernate");
+ break;
+ case Action::SHUTDOWN:
+ texture_prefix += "shutdown";
+ label = _("Shut Down");
+ break;
+ case Action::REBOOT:
+ texture_prefix += "restart";
+ label = _("Restart");
+ break;
+ }
+
normal_tex_.Adopt(nux::CreateTexture2DFromFile((texture_prefix + ".png").c_str(), -1, true));
highlight_tex_.Adopt(nux::CreateTexture2DFromFile((texture_prefix + "_highlight.png").c_str(), -1, true));
diff --git a/shutdown/SessionButton.h b/shutdown/SessionButton.h
index f9b0ae362..055360048 100644
--- a/shutdown/SessionButton.h
+++ b/shutdown/SessionButton.h
@@ -37,9 +37,20 @@ class Button : public nux::View, public debug::Introspectable
{
NUX_DECLARE_OBJECT_TYPE(Button, nux::View);
public:
- Button(std::string const& label, std::string const& texture_name, NUX_FILE_LINE_PROTO);
+ enum class Action
+ {
+ LOCK,
+ LOGOUT,
+ SUSPEND,
+ HIBERNATE,
+ SHUTDOWN,
+ REBOOT
+ };
+
+ Button(Action, NUX_FILE_LINE_PROTO);
nux::Property<bool> highlighted;
+ nux::ROProperty<Action> action;
nux::ROProperty<std::string> label;
sigc::signal<void> activated;
@@ -54,6 +65,7 @@ protected:
private:
friend class TestSessionButton;
+ Action action_;
IconTexture* image_view_;
StaticCairoText* label_view_;
nux::ObjectPtr<nux::BaseTexture> normal_tex_;
diff --git a/shutdown/SessionView.cpp b/shutdown/SessionView.cpp
index 93e77c996..2fa8cf0cd 100644
--- a/shutdown/SessionView.cpp
+++ b/shutdown/SessionView.cpp
@@ -173,11 +173,11 @@ void View::Populate()
if (mode() == Mode::LOGOUT)
{
- auto* button = new Button(_("Lock"), "lockscreen", NUX_TRACKER_LOCATION);
+ auto* button = new Button(Button::Action::LOCK, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::LockScreen));
AddButton(button);
- button = new Button(_("Logout"), "logout", NUX_TRACKER_LOCATION);
+ button = new Button(Button::Action::LOGOUT, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Logout));
AddButton(button);
}
@@ -185,20 +185,20 @@ void View::Populate()
{
if (mode() == Mode::FULL)
{
- auto* button = new Button(_("Lock"), "lockscreen", NUX_TRACKER_LOCATION);
+ auto* button = new Button(Button::Action::LOCK, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::LockScreen));
AddButton(button);
if (manager_->CanSuspend())
{
- button = new Button(_("Suspend"), "suspend", NUX_TRACKER_LOCATION);
+ button = new Button(Button::Action::SUSPEND, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Suspend));
AddButton(button);
}
if (manager_->CanHibernate())
{
- button = new Button(_("Hibernate"), "hibernate", NUX_TRACKER_LOCATION);
+ button = new Button(Button::Action::HIBERNATE, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Hibernate));
AddButton(button);
}
@@ -206,17 +206,17 @@ void View::Populate()
if (manager_->CanShutdown())
{
- auto* button = new Button(_("Shutdown"), "shutdown", NUX_TRACKER_LOCATION);
- button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Shutdown));
+ auto *button = new Button(Button::Action::REBOOT, NUX_TRACKER_LOCATION);
+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Reboot));
AddButton(button);
- button = new Button(_("Restart"), "restart", NUX_TRACKER_LOCATION);
- button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Reboot));
+ button = new Button(Button::Action::SHUTDOWN, NUX_TRACKER_LOCATION);
+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Shutdown));
AddButton(button);
}
else if (mode() == Mode::FULL)
{
- auto* button = new Button(_("Logout"), "logout", NUX_TRACKER_LOCATION);
+ auto* button = new Button(Button::Action::LOGOUT, NUX_TRACKER_LOCATION);
button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Logout));
AddButton(button);
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8fdb8444f..d07dd17e2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -99,6 +99,27 @@ if (GTEST_SRC_DIR AND
test_service_panel.cpp)
target_link_libraries(test-gtest-service unity-shared ${LIBS})
+# gtest-slow, start moving things over that are slow running tests
+ set (GTEST_SLOW_SOURCES
+ test_main.cpp
+ logger_helper.cpp
+ test_im_text_entry_slow.cpp
+ test_im_text_entry_class.cpp
+ test_tooltip_manager.cpp
+ )
+
+ set (GTEST_SLOW_LIBS
+ gtest
+ gmock
+ launcher-lib
+ unity-shared
+ )
+
+ add_executable(test-gtest-slow ${GTEST_SLOW_SOURCES})
+
+ target_link_libraries(test-gtest-slow ${GTEST_SLOW_LIBS})
+
+ add_test(UnityGTestSlow test-gtest-slow)
# The actual test executable (xless) - do not put anything that requires X in here
set (GTEST_XLESS_SOURCES
@@ -218,6 +239,7 @@ if (ENABLE_X_SUPPORT)
test_hud_view.cpp
test_icon_loader.cpp
test_im_text_entry.cpp
+ test_im_text_entry_class.cpp
test_launcher.cpp
test_launcher_controller.cpp
test_launcher_drag_window.cpp
@@ -263,7 +285,6 @@ if (ENABLE_X_SUPPORT)
test_texture_cache.cpp
test_text_input.cpp
test_thumbnail_generator.cpp
- test_tooltip_manager.cpp
test_trash_launcher_icon.cpp
test_unity_settings.cpp
test_unity_window_style.cpp
@@ -322,6 +343,7 @@ if (ENABLE_X_SUPPORT)
set (GTEST_TEST_COMMAND_GESTURES ./test-gestures/test-gestures)
endif (ENABLE_X_SUPPORT)
set (GTEST_TEST_COMMAND_XLESS ./test-gtest-xless)
+set (GTEST_TEST_COMMAND_SLOW ./test-gtest-slow)
set (GTEST_TEST_COMMAND_DBUS dbus-test-runner --task ./test-gtest-service --task ./test-gtest-dbus)
set (TEST_COMMAND
@@ -330,6 +352,7 @@ set (TEST_COMMAND
&& ${GTEST_TEST_COMMAND_XLESS} --gtest_output=xml:./
&& ${GTEST_TEST_COMMAND_GESTURES} --gtest_output=xml:./
&& ${GTEST_TEST_COMMAND_DBUS} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_SLOW} --gtest_output=xml:./
)
set (TEST_COMMAND_HEADLESS
@@ -340,7 +363,7 @@ set (TEST_COMMAND_HEADLESS
if (GTEST_SRC_DIR)
if (ENABLE_X_SUPPORT)
- add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gestures)
+ add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-slow test-gtest-xless test-gtest-dbus test-gestures)
add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gestures)
add_custom_target (gcheck COMMAND ${DBUS_TEST_COMMAND} DEPENDS test-gtest test-gtest-xless)
else ()
diff --git a/tests/autopilot/unity/emulators/launcher.py b/tests/autopilot/unity/emulators/launcher.py
index ac7842192..0f74d9bff 100644
--- a/tests/autopilot/unity/emulators/launcher.py
+++ b/tests/autopilot/unity/emulators/launcher.py
@@ -494,7 +494,7 @@ class LauncherModel(UnityIntrospectionObject):
looking for an icon. For example, to find an icon with a particular
desktop_id, one might do this from within a test:
- >>> self.launcher.model.get_icon(desktop_id="gnome-calculator.desktop")
+ >>> self.launcher.model.get_icon(desktop_id="gcalctool.desktop")
This method returns only one icon. It is the callers responsibility to
ensure that the filter matches only one icon.
diff --git a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
index c7c0847b1..da6e38cae 100644
--- a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
+++ b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
@@ -315,7 +315,7 @@ class LauncherDragIconsBehavior(LauncherTestCase):
# not exist, and we don't want to wait for 10 seconds, so we do this
# the old fashioned way.
get_icon_fn = lambda: self.unity.launcher.model.get_children_by_type(
- ApplicationLauncherIcon, desktop_id="gnome-calculator.desktop")
+ ApplicationLauncherIcon, desktop_id="gcalctool.desktop")
calc_icon = get_icon_fn()
if calc_icon:
self.launcher_instance.unlock_from_launcher(calc_icon[0])
diff --git a/tests/autopilot/unity/tests/test_dash.py b/tests/autopilot/unity/tests/test_dash.py
index 26e092402..64d61d8b6 100644
--- a/tests/autopilot/unity/tests/test_dash.py
+++ b/tests/autopilot/unity/tests/test_dash.py
@@ -972,6 +972,12 @@ class PreviewNavigateTests(DashTestCase):
self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
+ def test_overlay_text(self):
+ """Fallback overlay text is internationalized, should always be valid."""
+ cover_art = self.get_current_preview().cover_art[0]
+ self.assertThat(cover_art.overlay_text,
+ Eventually(Equals("No Image Available")))
+
class PreviewClickCancelTests(DashTestCase):
"""Tests that the preview closes when left, middle, and right clicking in the preview"""
diff --git a/tests/autopilot/unity/tests/test_hud.py b/tests/autopilot/unity/tests/test_hud.py
index 97938b9d9..bc040a1ed 100644
--- a/tests/autopilot/unity/tests/test_hud.py
+++ b/tests/autopilot/unity/tests/test_hud.py
@@ -459,6 +459,17 @@ class HudBehaviorTests(HudTestsBase):
self.assertProperty(char_win, is_active=True)
+ def test_mouse_does_not_steal_button_focus(self):
+ """When typing in the hud the mouse must not steal button focus."""
+
+ self.unity.hud.ensure_visible()
+
+ (x,y,w,h) = self.unity.hud.view.geometry
+ self.mouse.move(w/4, h/4)
+
+ self.keyboard.type("a")
+ self.assertThat(self.unity.hud.view.selected_button, Eventually(Equals(1)))
+
class HudLauncherInteractionsTests(HudTestsBase):
diff --git a/tests/test_application_launcher_icon.cpp b/tests/test_application_launcher_icon.cpp
index ed8ff310e..d1fc452b1 100644
--- a/tests/test_application_launcher_icon.cpp
+++ b/tests/test_application_launcher_icon.cpp
@@ -30,9 +30,11 @@
#include "StandaloneWindowManager.h"
#include "mock-application.h"
#include "StandaloneWindowManager.h"
+#include "test_utils.h"
-using namespace unity;
+using namespace testing;
using namespace testmocks;
+using namespace unity;
using namespace unity::launcher;
namespace
@@ -41,22 +43,39 @@ const std::string DEFAULT_EMPTY_ICON = "application-default-icon";
const std::string USC_DESKTOP = BUILDDIR"/tests/data/applications/ubuntu-software-center.desktop";
const std::string NO_ICON_DESKTOP = BUILDDIR"/tests/data/applications/no-icon.desktop";
-class TestApplicationLauncherIcon : public testing::Test
+struct MockApplicationLauncherIcon : ApplicationLauncherIcon
+{
+ MockApplicationLauncherIcon(ApplicationPtr const& app)
+ : ApplicationLauncherIcon(app)
+ {}
+
+ MOCK_METHOD1(ActivateLauncherIcon, void(ActionArg));
+};
+
+MATCHER_P(AreArgsEqual, a, "")
+{
+ return arg.source == a.source &&
+ arg.button == a.button &&
+ arg.timestamp == a.timestamp &&
+ arg.target == a.target;
+ arg.monitor = a.monitor;
+}
+
+struct TestApplicationLauncherIcon : Test
{
-public:
virtual void SetUp()
{
WM = dynamic_cast<StandaloneWindowManager*>(&WindowManager::Default());
- usc_app.reset(new MockApplication(USC_DESKTOP, "softwarecenter"));
- usc_icon = new launcher::ApplicationLauncherIcon(usc_app);
+ usc_app = std::make_shared<MockApplication>(USC_DESKTOP, "softwarecenter");
+ usc_icon = new NiceMock<MockApplicationLauncherIcon>(usc_app);
ASSERT_EQ(usc_icon->DesktopFile(), USC_DESKTOP);
- empty_app.reset(new MockApplication(NO_ICON_DESKTOP));
- empty_icon = new launcher::ApplicationLauncherIcon(empty_app);
+ empty_app = std::make_shared<MockApplication>(NO_ICON_DESKTOP);
+ empty_icon = new NiceMock<MockApplicationLauncherIcon>(empty_app);
ASSERT_EQ(empty_icon->DesktopFile(), NO_ICON_DESKTOP);
- mock_app.reset(new MockApplication(""));
- mock_icon = new launcher::ApplicationLauncherIcon(mock_app);
+ mock_app = std::make_shared<MockApplication>("");
+ mock_icon = new NiceMock<MockApplicationLauncherIcon>(mock_app);
ASSERT_TRUE(mock_icon->DesktopFile().empty());
}
@@ -76,9 +95,9 @@ public:
std::shared_ptr<MockApplication> usc_app;
std::shared_ptr<MockApplication> empty_app;
std::shared_ptr<MockApplication> mock_app;
- nux::ObjectPtr<launcher::ApplicationLauncherIcon> usc_icon;
- nux::ObjectPtr<launcher::ApplicationLauncherIcon> empty_icon;
- nux::ObjectPtr<launcher::ApplicationLauncherIcon> mock_icon;
+ nux::ObjectPtr<MockApplicationLauncherIcon> usc_icon;
+ nux::ObjectPtr<MockApplicationLauncherIcon> empty_icon;
+ nux::ObjectPtr<MockApplicationLauncherIcon> mock_icon;
};
TEST_F(TestApplicationLauncherIcon, Position)
@@ -443,4 +462,29 @@ TEST_F(TestApplicationLauncherIcon, WindowListMenusWithEmptyTitles)
ASSERT_EQ(menu1_it, menus.end());
}
+TEST_F(TestApplicationLauncherIcon, QuicklistMenuItemForAppName)
+{
+ mock_app->title_ = "MockApplicationTitle";
+
+ auto const& menus = mock_icon->Menus();
+ auto app_it = std::find_if(menus.begin(), menus.end(), [this] (glib::Object<DbusmenuMenuitem> it) {
+ auto* label = dbusmenu_menuitem_property_get(it, DBUSMENU_MENUITEM_PROP_LABEL);
+ return (label && std::string(label) == ("<b>"+mock_app->title_+"</b>"));
+ });
+
+ ASSERT_NE(app_it, menus.end());
+
+ bool method_called = false;
+ ON_CALL(*mock_icon, ActivateLauncherIcon(_)).WillByDefault(Invoke([&method_called] (ActionArg arg) {
+ method_called = true;
+ }));
+
+ unsigned time = g_random_int();
+ EXPECT_CALL(*mock_icon, ActivateLauncherIcon(AreArgsEqual(ActionArg(ActionArg::Source::LAUNCHER, 0, time))));
+ dbusmenu_menuitem_handle_event(*app_it, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);
+
+ Utils::WaitUntilMSec(method_called);
+ EXPECT_TRUE(method_called);
+}
+
}
diff --git a/tests/test_im_text_entry.cpp b/tests/test_im_text_entry.cpp
index 2c5457119..334b6ab9d 100644
--- a/tests/test_im_text_entry.cpp
+++ b/tests/test_im_text_entry.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Canonical Ltd.
+ * Copyright 2012-2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3, as
@@ -19,49 +19,12 @@
*
*/
-#include <gmock/gmock.h>
-#include "unity-shared/IMTextEntry.h"
+#include "test_im_text_entry.h"
using namespace testing;
using namespace unity;
using namespace nux;
-namespace
-{
-
-class TestEvent : public nux::Event
-{
-public:
- TestEvent(nux::KeyModifier keymod, unsigned long keysym)
- {
- type = NUX_KEYDOWN;
- key_modifiers = keymod;
- x11_keysym = keysym;
- }
-
- TestEvent(unsigned long keysym)
- {
- type = NUX_KEYDOWN;
- x11_keysym = keysym;
- }
-};
-
-class MockTextEntry : public IMTextEntry
-{
-public:
- MOCK_METHOD0(CutClipboard, void());
- MOCK_METHOD0(CopyClipboard, void());
- MOCK_METHOD0(PasteClipboard, void());
- MOCK_METHOD0(PastePrimaryClipboard, void());
-
- bool InspectKeyEvent(nux::Event const& event)
- {
- key_down.emit(event.type, event.GetKeySym(), event.GetKeyState(), nullptr, 0);
- return IMTextEntry::InspectKeyEvent(event);
- }
-};
-
-
TEST(TestIMTextEntry, CopyCtrlC)
{
MockTextEntry text_entry;
@@ -173,27 +136,3 @@ TEST(TestIMTextEntry, CtrlKeybindings)
EXPECT_TRUE(text_entry.InspectKeyEvent(event));
}
}
-
-TEST(TestIMTextEntry, AltKeybindings)
-{
- MockTextEntry text_entry;
-
- for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
- {
- TestEvent event(KEY_MODIFIER_ALT, keysym);
- EXPECT_FALSE(text_entry.InspectKeyEvent(event));
- }
-}
-
-TEST(TestIMTextEntry, SuperKeybindings)
-{
- MockTextEntry text_entry;
-
- for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
- {
- TestEvent event(KEY_MODIFIER_SUPER, keysym);
- EXPECT_FALSE(text_entry.InspectKeyEvent(event));
- }
-}
-
-}
diff --git a/tests/test_im_text_entry.h b/tests/test_im_text_entry.h
new file mode 100644
index 000000000..1fa0e8f10
--- /dev/null
+++ b/tests/test_im_text_entry.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
+ *
+ */
+
+#ifndef TEST_IM_TEXT_ENTRY_H
+#define TEST_IM_TEXT_ENTRY_H
+
+#include <gmock/gmock.h>
+#include "unity-shared/IMTextEntry.h"
+
+class TestEvent : public nux::Event
+{
+public:
+ TestEvent(nux::KeyModifier keymod, unsigned long keysym);
+
+ TestEvent(unsigned long keysym);
+};
+
+class MockTextEntry : public unity::IMTextEntry
+{
+public:
+ MOCK_METHOD0(CutClipboard, void());
+ MOCK_METHOD0(CopyClipboard, void());
+ MOCK_METHOD0(PasteClipboard, void());
+ MOCK_METHOD0(PastePrimaryClipboard, void());
+
+ bool InspectKeyEvent(nux::Event const& event);
+};
+
+#endif // TEST_IM_TEXT_ENTRY_H
diff --git a/tests/test_im_text_entry_class.cpp b/tests/test_im_text_entry_class.cpp
new file mode 100644
index 000000000..52083994f
--- /dev/null
+++ b/tests/test_im_text_entry_class.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012-2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
+ *
+ */
+
+#include "test_im_text_entry.h"
+
+TestEvent::TestEvent(nux::KeyModifier keymod, unsigned long keysym)
+{
+ type = nux::NUX_KEYDOWN;
+ key_modifiers = keymod;
+ x11_keysym = keysym;
+}
+
+TestEvent::TestEvent(unsigned long keysym)
+{
+ type = nux::NUX_KEYDOWN;
+ x11_keysym = keysym;
+}
+
+bool MockTextEntry::InspectKeyEvent(nux::Event const& event)
+{
+ key_down.emit(event.type, event.GetKeySym(), event.GetKeyState(), nullptr, 0);
+ return IMTextEntry::InspectKeyEvent(event);
+}
diff --git a/tests/test_im_text_entry_slow.cpp b/tests/test_im_text_entry_slow.cpp
new file mode 100644
index 000000000..caa3493b8
--- /dev/null
+++ b/tests/test_im_text_entry_slow.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
+ *
+ */
+
+#include "test_im_text_entry.h"
+
+using namespace nux;
+
+TEST(TestIMTextEntry, AltKeybindings)
+{
+ MockTextEntry text_entry;
+
+ for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
+ {
+ TestEvent event(KEY_MODIFIER_ALT, keysym);
+ EXPECT_FALSE(text_entry.InspectKeyEvent(event));
+ }
+}
+
+TEST(TestIMTextEntry, SuperKeybindings)
+{
+ MockTextEntry text_entry;
+
+ for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
+ {
+ TestEvent event(KEY_MODIFIER_SUPER, keysym);
+ EXPECT_FALSE(text_entry.InspectKeyEvent(event));
+ }
+}
diff --git a/tests/test_session_button.cpp b/tests/test_session_button.cpp
index a108a7373..67e28d496 100644
--- a/tests/test_session_button.cpp
+++ b/tests/test_session_button.cpp
@@ -31,7 +31,7 @@ struct TestSessionButton : testing::Test
{
struct ButtonWrap : Button
{
- ButtonWrap() : Button("ButtonLabel", "hibernate") {}
+ ButtonWrap() : Button(Action::LOCK) {}
using Button::AcceptKeyNavFocusOnMouseEnter;
using Button::AcceptKeyNavFocusOnMouseDown;
@@ -46,8 +46,8 @@ struct TestSessionButton : testing::Test
TEST_F(TestSessionButton, Construct)
{
+ EXPECT_EQ(button.action(), Button::Action::LOCK);
EXPECT_FALSE(button.highlighted());
- EXPECT_EQ(button.label(), "ButtonLabel");
EXPECT_TRUE(button.AcceptKeyNavFocusOnMouseEnter());
EXPECT_FALSE(button.AcceptKeyNavFocusOnMouseDown());
}
@@ -120,5 +120,50 @@ TEST_F(TestSessionButton, KeyFocusActivatesIt)
EXPECT_TRUE(activated);
}
+// Action typed buttons tests
+
+struct ActionButton : public testing::TestWithParam<Button::Action> {
+ ActionButton()
+ : button(GetParam())
+ {}
+
+ std::string GetExpectedLabel()
+ {
+ switch (GetParam())
+ {
+ case Button::Action::LOCK:
+ return "Lock";
+ case Button::Action::LOGOUT:
+ return "Log Out";
+ case Button::Action::SUSPEND:
+ return "Suspend";
+ case Button::Action::HIBERNATE:
+ return "Hibernate";
+ case Button::Action::SHUTDOWN:
+ return "Shut Down";
+ case Button::Action::REBOOT:
+ return "Restart";
+ }
+
+ return "";
+ }
+
+ Button button;
+};
+
+INSTANTIATE_TEST_CASE_P(TestSessionButtonTypes, ActionButton,
+ testing::Values(Button::Action::LOCK, Button::Action::LOGOUT, Button::Action::SUSPEND,
+ Button::Action::HIBERNATE, Button::Action::SHUTDOWN, Button::Action::REBOOT));
+
+TEST_P(/*TestSessionButtonTypes*/ActionButton, Label)
+{
+ EXPECT_EQ(button.label(), GetExpectedLabel());
+}
+
+TEST_P(/*TestSessionButtonTypes*/ActionButton, Action)
+{
+ EXPECT_EQ(button.action(), GetParam());
+}
+
} // session
} // unity \ No newline at end of file
diff --git a/tests/test_session_view.cpp b/tests/test_session_view.cpp
index 5b65178e6..4cdebefad 100644
--- a/tests/test_session_view.cpp
+++ b/tests/test_session_view.cpp
@@ -60,16 +60,30 @@ struct TestSessionView : testing::Test
return buttons;
}
- Button* GetButtonByLabel(std::string const& label) const
+ Button* GetButtonByAction(Button::Action action) const
{
for (auto const& button : GetButtons())
{
- if (button->label() == label)
+ if (button->action() == action)
return button;
}
return nullptr;
}
+
+ int GetButtonPosition(Button::Action action) const
+ {
+ int pos = 0;
+ for (auto const& button : GetButtons())
+ {
+ if (button->action() == action)
+ return pos;
+
+ ++pos;
+ }
+
+ return -1;
+ }
};
void TearDown()
@@ -129,29 +143,29 @@ TEST_F(TestSessionView, FullModeButtons)
ON_CALL(*manager, CanHibernate()).WillByDefault(testing::Return(true));
view.mode.changed.emit(View::Mode::FULL);
- EXPECT_EQ(view.GetButtonByLabel("Logout"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Lock"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Suspend"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Hibernate"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Shutdown"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Restart"), nullptr);
+ EXPECT_EQ(view.GetButtonByAction(Button::Action::LOGOUT), nullptr);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::LOCK), 0);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::SUSPEND), 1);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::HIBERNATE), 2);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::REBOOT), 3);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::SHUTDOWN), 4);
ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(false));
view.mode.changed.emit(View::Mode::FULL);
- EXPECT_NE(view.GetButtonByLabel("Logout"), nullptr);
- EXPECT_EQ(view.GetButtonByLabel("Shutdown"), nullptr);
- EXPECT_EQ(view.GetButtonByLabel("Restart"), nullptr);
+ EXPECT_NE(view.GetButtonByAction(Button::Action::LOGOUT), nullptr);
+ EXPECT_EQ(view.GetButtonByAction(Button::Action::SHUTDOWN), nullptr);
+ EXPECT_EQ(view.GetButtonByAction(Button::Action::REBOOT), nullptr);
ON_CALL(*manager, CanSuspend()).WillByDefault(testing::Return(false));
view.mode.changed.emit(View::Mode::FULL);
- EXPECT_EQ(view.GetButtonByLabel("Suspend"), nullptr);
+ EXPECT_EQ(view.GetButtonByAction(Button::Action::SUSPEND), nullptr);
ON_CALL(*manager, CanHibernate()).WillByDefault(testing::Return(false));
view.mode.changed.emit(View::Mode::FULL);
- EXPECT_EQ(view.GetButtonByLabel("Hibernate"), nullptr);
+ EXPECT_EQ(view.GetButtonByAction(Button::Action::HIBERNATE), nullptr);
}
TEST_F(TestSessionView, ShutdownModeButtons)
@@ -160,8 +174,8 @@ TEST_F(TestSessionView, ShutdownModeButtons)
view.mode = View::Mode::SHUTDOWN;
EXPECT_EQ(view.GetButtons().size(), 2);
- EXPECT_NE(view.GetButtonByLabel("Shutdown"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Restart"), nullptr);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::REBOOT), 0);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::SHUTDOWN), 1);
}
TEST_F(TestSessionView, LogoutModeButtons)
@@ -169,8 +183,8 @@ TEST_F(TestSessionView, LogoutModeButtons)
view.mode = View::Mode::LOGOUT;
EXPECT_EQ(view.GetButtons().size(), 2);
- EXPECT_NE(view.GetButtonByLabel("Logout"), nullptr);
- EXPECT_NE(view.GetButtonByLabel("Lock"), nullptr);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::LOCK), 0);
+ EXPECT_EQ(view.GetButtonPosition(Button::Action::LOGOUT), 1);
}
TEST_F(TestSessionView, FullModeTitle)
@@ -198,7 +212,7 @@ TEST_F(TestSessionView, ButtonsActivateRequestsHide)
bool request_hide = false;
view.request_hide.connect([&request_hide] { request_hide = true; });
- auto button = view.GetButtonByLabel("Lock");
+ auto button = view.GetButtonByAction(Button::Action::LOCK);
ASSERT_NE(button, nullptr);
button->activated.emit();
@@ -207,7 +221,7 @@ TEST_F(TestSessionView, ButtonsActivateRequestsHide)
TEST_F(TestSessionView, ButtonsActivateDeselectButton)
{
- auto button = view.GetButtonByLabel("Lock");
+ auto button = view.GetButtonByAction(Button::Action::LOCK);
ASSERT_NE(button, nullptr);
button->highlighted = true;
button->activated.emit();
@@ -218,7 +232,7 @@ TEST_F(TestSessionView, ButtonsActivateDeselectButton)
TEST_F(TestSessionView, LockButtonActivateLocks)
{
EXPECT_CALL(*manager, LockScreen());
- auto button = view.GetButtonByLabel("Lock");
+ auto button = view.GetButtonByAction(Button::Action::LOCK);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
@@ -227,7 +241,7 @@ TEST_F(TestSessionView, LogoutButtonActivateLogouts)
{
view.mode = View::Mode::LOGOUT;
EXPECT_CALL(*manager, Logout());
- auto button = view.GetButtonByLabel("Logout");
+ auto button = view.GetButtonByAction(Button::Action::LOGOUT);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
@@ -238,7 +252,7 @@ TEST_F(TestSessionView, SuspendButtonActivateSuspends)
view.mode.changed.emit(View::Mode::FULL);
EXPECT_CALL(*manager, Suspend());
- auto button = view.GetButtonByLabel("Suspend");
+ auto button = view.GetButtonByAction(Button::Action::SUSPEND);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
@@ -249,7 +263,7 @@ TEST_F(TestSessionView, HibernateButtonActivateHibernates)
view.mode.changed.emit(View::Mode::FULL);
EXPECT_CALL(*manager, Hibernate());
- auto button = view.GetButtonByLabel("Hibernate");
+ auto button = view.GetButtonByAction(Button::Action::HIBERNATE);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
@@ -260,7 +274,7 @@ TEST_F(TestSessionView, ShutdownButtonActivateShutsdown)
view.mode = View::Mode::SHUTDOWN;
EXPECT_CALL(*manager, Shutdown());
- auto button = view.GetButtonByLabel("Shutdown");
+ auto button = view.GetButtonByAction(Button::Action::SHUTDOWN);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
@@ -271,7 +285,7 @@ TEST_F(TestSessionView, RebootButtonActivateReboots)
view.mode = View::Mode::SHUTDOWN;
EXPECT_CALL(*manager, Reboot());
- auto button = view.GetButtonByLabel("Restart");
+ auto button = view.GetButtonByAction(Button::Action::REBOOT);
ASSERT_NE(button, nullptr);
button->activated.emit();
}
diff --git a/tests/test_tooltip_manager.cpp b/tests/test_tooltip_manager.cpp
index c7f2583ed..5badb4edf 100644
--- a/tests/test_tooltip_manager.cpp
+++ b/tests/test_tooltip_manager.cpp
@@ -15,40 +15,79 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Jacob Edwards <j.johan.edwards@gmail.com>
+ * Andrea Azzarone <andrea.azzarone@gmail.com>
*/
-#include <gtest/gtest.h>
+#include <gmock/gmock.h>
using namespace testing;
#include "launcher/TooltipManager.h"
#include "launcher/MockLauncherIcon.h"
+using unity::launcher::MockLauncherIcon;
+using unity::launcher::TooltipManager;
+
#include "test_utils.h"
-namespace unity
-{
-namespace launcher
+namespace
{
-namespace
+bool CheckIsTooltipVisible(nux::ObjectPtr<MockLauncherIcon> const& icon, bool value) {
+ return icon->IsTooltipVisible() == value;
+}
+
+struct TestTooltipManager : public Test {
+ TooltipManager tooltip_manager;
+};
+
+TEST_F(TestTooltipManager, MouseMoved)
{
+ nux::ObjectPtr<MockLauncherIcon> icon1(new MockLauncherIcon());
+ nux::ObjectPtr<MockLauncherIcon> icon2(new MockLauncherIcon());
+
+ tooltip_manager.MouseMoved(icon1);
+ ASSERT_FALSE(icon1->IsTooltipVisible()); // don't skip the timeout!
+ Utils::WaitUntil(std::bind(CheckIsTooltipVisible, icon1, true));
+ Utils::WaitUntil(std::bind(CheckIsTooltipVisible, icon2, false));
+
+ tooltip_manager.MouseMoved(icon2);
+ ASSERT_FALSE(icon1->IsTooltipVisible());
+ ASSERT_TRUE(icon2->IsTooltipVisible());
+
+ tooltip_manager.MouseMoved(nux::ObjectPtr<MockLauncherIcon>());
+ ASSERT_FALSE(icon1->IsTooltipVisible());
+ ASSERT_FALSE(icon2->IsTooltipVisible());
-TEST(TestTooltipManager, TestHideAndShowTooltip)
+ tooltip_manager.MouseMoved(icon1);
+ ASSERT_TRUE(icon1->IsTooltipVisible());
+ ASSERT_FALSE(icon2->IsTooltipVisible());
+}
+
+TEST_F(TestTooltipManager, IconClicked)
{
- // Makes sure that TooltipManager calls icon->ShowTooltip() when the mouse
- // hovers it, and icon->HideTooltip() after the mouse dehovers it.
- TooltipManager tm;
- MockLauncherIcon* icon = new MockLauncherIcon();
-
- tm.SetIcon(AbstractLauncherIcon::Ptr(icon));
- tm.MouseMoved();
- Utils::WaitForTimeoutMSec(1050);
-
- EXPECT_TRUE(icon->IsTooltipVisible());
- tm.SetIcon(AbstractLauncherIcon::Ptr());
- EXPECT_FALSE(icon->IsTooltipVisible());
+ nux::ObjectPtr<MockLauncherIcon> icon(new MockLauncherIcon());
+
+ tooltip_manager.MouseMoved(icon);
+ ASSERT_FALSE(icon->IsTooltipVisible()); // don't skip the timeout!
+ Utils::WaitUntil(std::bind(CheckIsTooltipVisible, icon, true));
+
+ tooltip_manager.IconClicked();
+ ASSERT_FALSE(icon->IsTooltipVisible());
}
+TEST_F(TestTooltipManager, SetHover)
+{
+ nux::ObjectPtr<MockLauncherIcon> icon(new MockLauncherIcon());
+
+ tooltip_manager.MouseMoved(icon);
+ ASSERT_FALSE(icon->IsTooltipVisible()); // don't skip the timeout!
+ Utils::WaitUntil(std::bind(CheckIsTooltipVisible, icon, true));
+
+ tooltip_manager.SetHover(false);
+ ASSERT_FALSE(icon->IsTooltipVisible());
+
+ tooltip_manager.MouseMoved(icon);
+ ASSERT_FALSE(icon->IsTooltipVisible()); // don't skip the timeout!
+ Utils::WaitUntil(std::bind(CheckIsTooltipVisible, icon, true));
}
-} // launcher
-} // unity
+}
diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp
index 97375a6c2..23ef8ce44 100644
--- a/unity-shared/CoverArt.cpp
+++ b/unity-shared/CoverArt.cpp
@@ -20,6 +20,7 @@
* Nick Dedekind <nick.dedekind@canonical.com>
*
*/
+#include "config.h"
#include "CoverArt.h"
#include "unity-shared/IntrospectableWrappers.h"
@@ -29,6 +30,7 @@
#include "DashStyle.h"
#include "IconLoader.h"
#include "PreviewStyle.h"
+#include <glib/gi18n-lib.h>
namespace unity
{
@@ -83,7 +85,8 @@ void CoverArt::AddProperties(GVariantBuilder* builder)
variant::BuilderWrapper(builder)
.add(GetAbsoluteGeometry())
.add("image-hint", image_hint_)
- .add("waiting", waiting_);
+ .add("waiting", waiting_)
+ .add("overlay-text", overlay_text_->GetText());
}
void CoverArt::SetImage(std::string const& image_hint)
@@ -446,7 +449,7 @@ void CoverArt::SetupViews()
overlay_text_->SetTextAlignment(StaticCairoText::NUX_ALIGN_CENTRE);
overlay_text_->SetFont("Ubuntu 14");
overlay_text_->SetLines(-3);
- overlay_text_->SetText("No Image Available");
+ overlay_text_->SetText(_("No Image Available"));
dash::Style& style = dash::Style::Instance();
spin_ = style.GetSearchSpinIcon();
diff --git a/unity-shared/IconRenderer.cpp b/unity-shared/IconRenderer.cpp
index 39153795b..da8c2b868 100644
--- a/unity-shared/IconRenderer.cpp
+++ b/unity-shared/IconRenderer.cpp
@@ -25,7 +25,9 @@
#include <NuxGraphics/GpuDevice.h>
#include <NuxGraphics/GLTextureResourceManager.h>
+#include <UnityCore/GLibWrapper.h>
#include <NuxGraphics/CairoGraphics.h>
+#include "unity-shared/CairoTexture.h"
#include "GraphicsUtils.h"
#include <gtk/gtk.h>
@@ -39,6 +41,8 @@ namespace unity
{
namespace ui
{
+namespace
+{
#ifdef USE_GLES
#define VertexShaderHeader "#version 100\n"
@@ -171,6 +175,7 @@ LRP temp, factor.x, color, desat; \n\
MUL result.color.rgb, temp, colorify_color; \n\
MOV result.color.a, color; \n\
END");
+} // anonymous namespace
// The local namespace is purely for namespacing the file local variables below.
namespace local
@@ -181,58 +186,83 @@ enum IconSize
{
SMALL = 0,
BIG,
- LAST,
+ SIZE,
};
+} // anonymous namespace
+} // local namespace
+
+struct IconRenderer::TexturesPool
+{
+ static std::shared_ptr<TexturesPool> Get()
+ {
+ static std::shared_ptr<TexturesPool> instance(new TexturesPool());
+ return instance;
+ }
-bool textures_created = false;
-nux::BaseTexture* progress_bar_trough = 0;
-nux::BaseTexture* progress_bar_fill = 0;
-nux::BaseTexture* pip_ltr = 0;
-nux::BaseTexture* pip_rtl = 0;
-nux::BaseTexture* arrow_ltr = 0;
-nux::BaseTexture* arrow_rtl = 0;
-nux::BaseTexture* arrow_empty_ltr = 0;
-nux::BaseTexture* arrow_empty_rtl = 0;
-
-// nux::BaseTexture* squircle_base = 0;
-// nux::BaseTexture* squircle_base_selected = 0;
-// nux::BaseTexture* squircle_edge = 0;
-// nux::BaseTexture* squircle_glow = 0;
-// nux::BaseTexture* squircle_shadow = 0;
-// nux::BaseTexture* squircle_shine = 0;
-
-std::vector<nux::BaseTexture*> icon_background;
-std::vector<nux::BaseTexture*> icon_selected_background;
-std::vector<nux::BaseTexture*> icon_edge;
-std::vector<nux::BaseTexture*> icon_glow;
-std::vector<nux::BaseTexture*> icon_shadow;
-std::vector<nux::BaseTexture*> icon_shine;
-nux::ObjectPtr<nux::IOpenGLBaseTexture> offscreen_progress_texture;
-nux::ObjectPtr<nux::IOpenGLShaderProgram> shader_program_uv_persp_correction;
+ nux::ObjectPtr<nux::BaseTexture> RenderLabelTexture(char label, int icon_size, nux::Color const& bg_color);
+
+ BaseTexturePtr progress_bar_trough;
+ BaseTexturePtr progress_bar_fill;
+ BaseTexturePtr pip_ltr;
+ BaseTexturePtr large_pip_ltr;
+ // BaseTexturePtr pip_rtl;
+ // BaseTexturePtr large_pip_rtl;
+ BaseTexturePtr arrow_ltr;
+ BaseTexturePtr arrow_rtl;
+ BaseTexturePtr arrow_empty_ltr;
+ // BaseTexturePtr arrow_empty_rtl;
+
+ // BaseTexturePtr squircle_base;
+ // BaseTexturePtr squircle_base_selected;
+ // BaseTexturePtr squircle_edge;
+ // BaseTexturePtr squircle_glow;
+ // BaseTexturePtr squircle_shadow;
+ // BaseTexturePtr squircle_shine;
+
+ BaseTexturePtr icon_background[local::IconSize::SIZE];
+ BaseTexturePtr icon_selected_background[local::IconSize::SIZE];
+ BaseTexturePtr icon_edge[local::IconSize::SIZE];
+ BaseTexturePtr icon_glow[local::IconSize::SIZE];
+ BaseTexturePtr icon_shadow[local::IconSize::SIZE];
+ BaseTexturePtr icon_shine[local::IconSize::SIZE];
+
+ nux::ObjectPtr<nux::IOpenGLBaseTexture> offscreen_progress_texture;
+ nux::ObjectPtr<nux::IOpenGLShaderProgram> shader_program_uv_persp_correction;
#ifndef USE_GLES
-nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> asm_shader;
+ nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> asm_shader;
#endif
-std::map<char, nux::BaseTexture*> label_map;
-void generate_textures();
-void destroy_textures();
-}
-}
+ std::map<char, BaseTexturePtr> labels;
+
+private:
+ TexturesPool();
+
+ inline void LoadTexture(BaseTexturePtr &texture_ptr, std::string const& filename)
+ {
+ texture_ptr.Adopt(nux::CreateTexture2DFromFile(filename.c_str(), -1, true));
+ }
+
+ inline void GenerateTextures(BaseTexturePtr (&texture)[local::IconSize::SIZE],
+ std::string const& big_file, std::string const& small_file)
+ {
+ LoadTexture(texture[local::IconSize::SMALL], small_file);
+ LoadTexture(texture[local::IconSize::BIG], big_file);
+ }
+
+ void SetupShaders();
+};
IconRenderer::IconRenderer()
: icon_size(0)
, image_size(0)
, spacing(0)
+ , textures_(TexturesPool::Get())
{
pip_style = OUTSIDE_TILE;
-
- if (!local::textures_created)
- local::generate_textures();
}
IconRenderer::~IconRenderer()
-{
-}
+{}
void IconRenderer::SetTargetSize(int tile_size, int image_size_, int spacing_)
{
@@ -248,7 +278,7 @@ void IconRenderer::PreprocessIcons(std::list<RenderArg>& args, nux::Geometry con
nux::Matrix4 ProjectionMatrix;
nux::Matrix4 ViewProjectionMatrix;
- _stored_projection_matrix = nux::GetWindowThread()->GetGraphicsEngine().GetOpenGLModelViewProjectionMatrix();
+ stored_projection_matrix_ = nux::GetWindowThread()->GetGraphicsEngine().GetOpenGLModelViewProjectionMatrix();
GetInverseScreenPerspectiveMatrix(ViewMatrix, ProjectionMatrix, geo.width, geo.height, 0.1f, 1000.0f, DEGTORAD(90));
@@ -404,19 +434,20 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
nux::Color background_tile_color = arg.icon->BackgroundColor();
nux::Color glow_color = arg.icon->GlowColor();
- nux::Color edge_color(0x55555555);
+ nux::Color edge_color = nux::color::White;
nux::Color colorify = arg.colorify;
nux::Color background_tile_colorify = arg.colorify;
+ nux::Color edge_tile_colorify = nux::color::White;
bool colorify_background = arg.colorify_background;
float backlight_intensity = arg.backlight_intensity;
float glow_intensity = arg.glow_intensity;
float shadow_intensity = 0.6f;
- nux::BaseTexture* background = local::icon_background[size];
- nux::BaseTexture* edge = local::icon_edge[size];
- nux::BaseTexture* glow = local::icon_glow[size];
- nux::BaseTexture* shine = local::icon_shine[size];
- nux::BaseTexture* shadow = local::icon_shadow[size];
+ BaseTexturePtr background = textures_->icon_background[size];
+ BaseTexturePtr const& edge = textures_->icon_edge[size];
+ BaseTexturePtr const& glow = textures_->icon_glow[size];
+ BaseTexturePtr const& shine = textures_->icon_shine[size];
+ BaseTexturePtr const& shadow = textures_->icon_shadow[size];
nux::Color shortcut_color = arg.colorify;
@@ -445,7 +476,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
glow_intensity = 1.0f;
shadow_intensity = 0.0f;
- background = local::icon_selected_background[size];
+ background = textures_->icon_selected_background[size];
}
else
{
@@ -477,8 +508,6 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
{
nux::Color shadow_color = background_tile_colorify * 0.3f;
- // FIXME it is using the same transformation of the glow,
- // should have its own transformation.
RenderElement(GfxContext,
arg,
shadow->GetDeviceTexture(),
@@ -502,10 +531,9 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
backlight_intensity * arg.alpha,
force_filter,
tile_transform);
- }
- edge_color = edge_color + ((background_tile_color - edge_color) * backlight_intensity);
- nux::Color edge_tile_colorify = background_tile_colorify;
+ edge_color = edge_color + ((background_tile_color - edge_color) * backlight_intensity);
+ }
if (colorify_background && !arg.keyboard_nav_hl)
{
@@ -575,7 +603,7 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
RenderElement(GfxContext,
arg,
- local::icon_glow[size]->GetDeviceTexture(),
+ textures_->icon_glow[size]->GetDeviceTexture(),
arg.icon->GlowColor(),
nux::color::White,
fade_out * arg.alpha,
@@ -588,17 +616,17 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
// draw progress bar
if (arg.progress_bias > -1.0f && arg.progress_bias < 1.0f)
{
- if (local::offscreen_progress_texture->GetWidth() != icon_size ||
- local::offscreen_progress_texture->GetHeight() != icon_size)
+ if (textures_->offscreen_progress_texture->GetWidth() != icon_size ||
+ textures_->offscreen_progress_texture->GetHeight() != icon_size)
{
- local::offscreen_progress_texture = nux::GetGraphicsDisplay()->GetGpuDevice()
+ textures_->offscreen_progress_texture = nux::GetGraphicsDisplay()->GetGpuDevice()
->CreateSystemCapableDeviceTexture(icon_size, icon_size, 1, nux::BITFMT_R8G8B8A8);
}
- RenderProgressToTexture(GfxContext, local::offscreen_progress_texture, arg.progress, arg.progress_bias);
+ RenderProgressToTexture(GfxContext, textures_->offscreen_progress_texture, arg.progress, arg.progress_bias);
RenderElement(GfxContext,
arg,
- local::offscreen_progress_texture,
+ textures_->offscreen_progress_texture,
nux::color::White,
nux::color::White,
arg.alpha,
@@ -631,12 +659,22 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
{
char shortcut = (char) arg.shortcut_label;
- if (local::label_map.find(shortcut) == local::label_map.end())
- local::label_map[shortcut] = RenderCharToTexture(shortcut, icon_size, icon_size, shortcut_color);
+ BaseTexturePtr label;
+ auto label_it = textures_->labels.find(shortcut);
+
+ if (label_it != textures_->labels.end())
+ {
+ label = label_it->second;
+ }
+ else
+ {
+ label = textures_->RenderLabelTexture(shortcut, icon_size, shortcut_color);
+ textures_->labels[shortcut] = label;
+ }
RenderElement(GfxContext,
arg,
- local::label_map[shortcut]->GetDeviceTexture(),
+ label->GetDeviceTexture(),
nux::Color(0xFFFFFFFF),
nux::color::White,
arg.alpha,
@@ -645,23 +683,19 @@ void IconRenderer::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const&
}
}
-nux::BaseTexture* IconRenderer::RenderCharToTexture(char label, int width, int height, nux::Color const& bg_color)
+nux::ObjectPtr<nux::BaseTexture> IconRenderer::TexturesPool::RenderLabelTexture(char label, int icon_size, nux::Color const& bg_color)
{
- nux::BaseTexture* texture = NULL;
- nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
- cairo_t* cr = cg.GetInternalContext();
- PangoLayout* layout = NULL;
- PangoFontDescription* desc = NULL;
- GtkSettings* settings = gtk_settings_get_default(); // not ref'ed
- gchar* fontName = NULL;
-
- double label_ratio = 0.44f;
- double label_size = icon_size * label_ratio;
- double label_x = (icon_size - label_size) / 2;
- double label_y = (icon_size - label_size) / 2;
- double label_w = label_size;
- double label_h = label_size;
- double label_radius = 3.0f;
+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, icon_size, icon_size);
+ cairo_t* cr = cg.GetInternalContext();
+ glib::String font_name;
+
+ const double label_ratio = 0.44f;
+ const double label_size = icon_size * label_ratio;
+ const double label_x = (icon_size - label_size) / 2.0f;
+ const double label_y = (icon_size - label_size) / 2.0f;
+ const double label_w = label_size;
+ const double label_h = label_size;
+ const double label_radius = 3.0f;
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
@@ -673,35 +707,27 @@ nux::BaseTexture* IconRenderer::RenderCharToTexture(char label, int width, int h
cairo_set_source_rgba(cr, bg_color.red, bg_color.green, bg_color.blue, 0.20f);
cairo_fill(cr);
- double text_ratio = 0.75;
- double text_size = label_size * text_ratio;
- layout = pango_cairo_create_layout(cr);
- g_object_get(settings, "gtk-font-name", &fontName, NULL);
- desc = pango_font_description_from_string(fontName);
- pango_font_description_set_absolute_size(desc, text_size * PANGO_SCALE);
- pango_layout_set_font_description(layout, desc);
+ const double text_ratio = 0.75;
+ double text_size = label_size * text_ratio;
+ glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr));
+ g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL);
+ std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name),
+ pango_font_description_free);
+ pango_font_description_set_absolute_size(desc.get(), text_size * PANGO_SCALE);
+ pango_layout_set_font_description(layout, desc.get());
pango_layout_set_text(layout, &label, 1);
- PangoRectangle logRect;
- PangoRectangle inkRect;
- pango_layout_get_extents(layout, &inkRect, &logRect);
+ nux::Size extents;
+ pango_layout_get_pixel_size(layout, &extents.width, &extents.height);
// position and paint text
cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
- double x = label_x - ((logRect.width / PANGO_SCALE) - label_w) / 2.0f;
- double y = label_y - ((logRect.height / PANGO_SCALE) - label_h) / 2.0f - 1;
+ double x = label_x - std::round((extents.width - label_w) / 2.0f);
+ double y = label_y - std::round((extents.height - label_h) / 2.0f);
cairo_move_to(cr, x, y);
pango_cairo_show_layout(cr, layout);
- nux::NBitmapData* bitmap = cg.GetBitmap();
- texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
- texture->Update(bitmap);
- delete bitmap;
- g_object_unref(layout);
- pango_font_description_free(desc);
- g_free(fontName);
-
- return texture;
+ return texture_ptr_from_cairo_graphics(cg);
}
void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
@@ -783,28 +809,28 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
if (nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath())
{
- local::shader_program_uv_persp_correction->Begin();
+ textures_->shader_program_uv_persp_correction->Begin();
- int TextureObjectLocation = local::shader_program_uv_persp_correction->GetUniformLocationARB("TextureObject0");
- VertexLocation = local::shader_program_uv_persp_correction->GetAttributeLocation("iVertex");
- TextureCoord0Location = local::shader_program_uv_persp_correction->GetAttributeLocation("iTexCoord0");
- FragmentColor = local::shader_program_uv_persp_correction->GetUniformLocationARB("color0");
- ColorifyColor = local::shader_program_uv_persp_correction->GetUniformLocationARB("colorify_color");
- DesatFactor = local::shader_program_uv_persp_correction->GetUniformLocationARB("desat_factor");
+ int TextureObjectLocation = textures_->shader_program_uv_persp_correction->GetUniformLocationARB("TextureObject0");
+ VertexLocation = textures_->shader_program_uv_persp_correction->GetAttributeLocation("iVertex");
+ TextureCoord0Location = textures_->shader_program_uv_persp_correction->GetAttributeLocation("iTexCoord0");
+ FragmentColor = textures_->shader_program_uv_persp_correction->GetUniformLocationARB("color0");
+ ColorifyColor = textures_->shader_program_uv_persp_correction->GetUniformLocationARB("colorify_color");
+ DesatFactor = textures_->shader_program_uv_persp_correction->GetUniformLocationARB("desat_factor");
if (TextureObjectLocation != -1)
CHECKGL(glUniform1iARB(TextureObjectLocation, 0));
- int VPMatrixLocation = local::shader_program_uv_persp_correction->GetUniformLocationARB("ViewProjectionMatrix");
+ int VPMatrixLocation = textures_->shader_program_uv_persp_correction->GetUniformLocationARB("ViewProjectionMatrix");
if (VPMatrixLocation != -1)
{
- local::shader_program_uv_persp_correction->SetUniformLocMatrix4fv((GLint)VPMatrixLocation, 1, false, (GLfloat*) & (_stored_projection_matrix.m));
+ textures_->shader_program_uv_persp_correction->SetUniformLocMatrix4fv((GLint)VPMatrixLocation, 1, false, (GLfloat*) & (stored_projection_matrix_.m));
}
}
#ifndef USE_GLES
else
{
- local::asm_shader->Begin();
+ textures_->asm_shader->Begin();
VertexLocation = nux::VTXATTRIB_POSITION;
TextureCoord0Location = nux::VTXATTRIB_TEXCOORD0;
@@ -866,12 +892,12 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
if (nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath())
{
- local::shader_program_uv_persp_correction->End();
+ textures_->shader_program_uv_persp_correction->End();
}
else
{
#ifndef USE_GLES
- local::asm_shader->End();
+ textures_->asm_shader->End();
#endif
}
}
@@ -890,8 +916,8 @@ void IconRenderer::RenderIndicators(nux::GraphicsEngine& GfxContext,
if (running > 0)
{
int scale = 1;
-
int markerX;
+
if (pip_style == OUTSIDE_TILE)
{
markerX = geo.x;
@@ -899,8 +925,7 @@ void IconRenderer::RenderIndicators(nux::GraphicsEngine& GfxContext,
else
{
auto bounds = arg.icon->GetTransform(ui::IconTextureSource::TRANSFORM_TILE, monitor);
- markerX = bounds[0].x + 2;
- scale = 2;
+ markerX = bounds[0].x + 1;
}
nux::TexCoordXForm texxform;
@@ -914,46 +939,66 @@ void IconRenderer::RenderIndicators(nux::GraphicsEngine& GfxContext,
color = color * alpha;
- nux::BaseTexture* texture;
+ BaseTexturePtr texture;
// markers are well outside screen bounds to start
int markers [3] = {-100, -100, -100};
if (!arg.running_on_viewport)
{
+ scale = (pip_style == OUTSIDE_TILE) ? 1 : 2;
markers[0] = markerCenter;
- texture = local::arrow_empty_ltr;
+ texture = textures_->arrow_empty_ltr;
}
else if (running == 1)
{
+ scale = (pip_style == OUTSIDE_TILE) ? 1 : 2;
markers[0] = markerCenter;
- texture = local::arrow_ltr;
+ texture = textures_->arrow_ltr;
}
else if (running == 2)
{
- markers[0] = markerCenter - 2 * scale;
- markers[1] = markerCenter + 2 * scale;
- texture = local::pip_ltr;
+ if (pip_style == OUTSIDE_TILE)
+ {
+ texture = textures_->pip_ltr;
+ markers[0] = markerCenter - 2;
+ markers[1] = markerCenter + 2;
+ }
+ else
+ {
+ texture = textures_->large_pip_ltr;
+ markers[0] = markerCenter - 4;
+ markers[1] = markerCenter + 4;
+ }
}
else
{
- markers[0] = markerCenter - 4 * scale;
- markers[1] = markerCenter;
- markers[2] = markerCenter + 4 * scale;
- texture = local::pip_ltr;
+ if (pip_style == OUTSIDE_TILE)
+ {
+ texture = textures_->pip_ltr;
+ markers[0] = markerCenter - 4;
+ markers[1] = markerCenter;
+ markers[2] = markerCenter + 4;
+ }
+ else
+ {
+ texture = textures_->large_pip_ltr;
+ markers[0] = markerCenter - 8;
+ markers[1] = markerCenter;
+ markers[2] = markerCenter + 8;
+ }
}
-
for (int i = 0; i < 3; i++)
{
int center = markers[i];
if (center == -100)
break;
-
+
GfxContext.QRP_1Tex(markerX,
- center - ((texture->GetHeight() * scale) / 2) - 1,
- (float) texture->GetWidth() * scale,
- (float) texture->GetHeight() * scale,
+ center - std::round((texture->GetHeight() * scale) / 2.0f),
+ texture->GetWidth() * scale,
+ texture->GetHeight() * scale,
texture->GetDeviceTexture(),
texxform,
color);
@@ -965,11 +1010,11 @@ void IconRenderer::RenderIndicators(nux::GraphicsEngine& GfxContext,
nux::TexCoordXForm texxform;
nux::Color color = nux::color::LightGrey * alpha;
- GfxContext.QRP_1Tex((geo.x + geo.width) - local::arrow_rtl->GetWidth(),
- markerCenter - (local::arrow_rtl->GetHeight() / 2) - 1,
- (float) local::arrow_rtl->GetWidth(),
- (float) local::arrow_rtl->GetHeight(),
- local::arrow_rtl->GetDeviceTexture(),
+ GfxContext.QRP_1Tex((geo.x + geo.width) - textures_->arrow_rtl->GetWidth(),
+ markerCenter - std::round(textures_->arrow_rtl->GetHeight() / 2.0f),
+ textures_->arrow_rtl->GetWidth(),
+ textures_->arrow_rtl->GetHeight(),
+ textures_->arrow_rtl->GetDeviceTexture(),
texxform,
color);
}
@@ -984,10 +1029,10 @@ void IconRenderer::RenderProgressToTexture(nux::GraphicsEngine& GfxContext,
int height = texture->GetHeight();
int progress_width = icon_size;
- int progress_height = local::progress_bar_trough->GetHeight();
+ int progress_height = textures_->progress_bar_trough->GetHeight();
int fill_width = image_size - (icon_size - image_size);
- int fill_height = local::progress_bar_fill->GetHeight();
+ int fill_height = textures_->progress_bar_fill->GetHeight();
int fill_offset = (progress_width - fill_width) / 2;
@@ -1022,10 +1067,10 @@ void IconRenderer::RenderProgressToTexture(nux::GraphicsEngine& GfxContext,
// left door
GfxContext.PushClippingRectangle(nux::Geometry(left_edge, 0, half_size, height));
GfxContext.QRP_1Tex(left_edge, progress_y, progress_width, progress_height,
- local::progress_bar_trough->GetDeviceTexture(), texxform,
+ textures_->progress_bar_trough->GetDeviceTexture(), texxform,
nux::color::White);
GfxContext.QRP_1Tex(left_edge + fill_offset, fill_y, fill_width, fill_height,
- local::progress_bar_fill->GetDeviceTexture(), texxform,
+ textures_->progress_bar_fill->GetDeviceTexture(), texxform,
nux::color::White);
GfxContext.PopClippingRectangle();
@@ -1033,11 +1078,11 @@ void IconRenderer::RenderProgressToTexture(nux::GraphicsEngine& GfxContext,
GfxContext.PushClippingRectangle(nux::Geometry(left_edge + half_size, 0, half_size, height));
GfxContext.QRP_1Tex(right_edge - progress_width, progress_y,
progress_width, progress_height,
- local::progress_bar_trough->GetDeviceTexture(), texxform,
+ textures_->progress_bar_trough->GetDeviceTexture(), texxform,
nux::color::White);
GfxContext.QRP_1Tex(right_edge - progress_width + fill_offset, fill_y,
fill_width, fill_height,
- local::progress_bar_fill->GetDeviceTexture(), texxform,
+ textures_->progress_bar_fill->GetDeviceTexture(), texxform,
nux::color::White);
GfxContext.PopClippingRectangle();
@@ -1045,16 +1090,9 @@ void IconRenderer::RenderProgressToTexture(nux::GraphicsEngine& GfxContext,
unity::graphics::PopOffscreenRenderTarget();
}
-void IconRenderer::DestroyTextures()
-{
- local::destroy_textures();
-}
-
void IconRenderer::DestroyShortcutTextures()
{
- for (auto texture : local::label_map)
- texture.second->UnReference();
- local::label_map.clear();
+ TexturesPool::Get()->labels.clear();
}
void IconRenderer::GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& PerspectiveMatrix,
@@ -1142,12 +1180,57 @@ void IconRenderer::GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, n
PerspectiveMatrix.Perspective(Fovy, AspectRatio, NearClipPlane, FarClipPlane);
}
-// The local namespace is purely for namespacing the file local variables below.
-namespace local
+IconRenderer::TexturesPool::TexturesPool()
+ : offscreen_progress_texture(nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, nux::BITFMT_R8G8B8A8))
{
-namespace
-{
-void setup_shaders()
+ LoadTexture(progress_bar_trough, PKGDATADIR"/progress_bar_trough.png");
+ LoadTexture(progress_bar_fill, PKGDATADIR"/progress_bar_fill.png");
+ LoadTexture(pip_ltr, PKGDATADIR"/launcher_pip_ltr.png");
+ LoadTexture(large_pip_ltr, PKGDATADIR"/launcher_pip_large_ltr.png");
+ // LoadTexture(pip_rtl, PKGDATADIR"/launcher_pip_rtl.png");
+ // LoadTexture(large_pip_rtl, PKGDATADIR"/launcher_pip_large_rtl.png");
+ LoadTexture(arrow_ltr, PKGDATADIR"/launcher_arrow_ltr.png");
+ LoadTexture(arrow_rtl, PKGDATADIR"/launcher_arrow_rtl.png");
+ LoadTexture(arrow_empty_ltr, PKGDATADIR"/launcher_arrow_outline_ltr.png");
+ // LoadTexture(arrow_empty_rtl, PKGDATADIR"/launcher_arrow_outline_rtl.png");
+
+ // LoadTexture(squircle_base, PKGDATADIR"/squircle_base_54.png");
+ // LoadTexture(squircle_base_selected, PKGDATADIR"/squircle_base_selected_54.png");
+ // LoadTexture(squircle_edge, PKGDATADIR"/squircle_edge_54.png");
+ // LoadTexture(squircle_glow, PKGDATADIR"/squircle_glow_62.png");
+ // LoadTexture(squircle_shadow, PKGDATADIR"/squircle_shadow_62.png");
+ // LoadTexture(squircle_shine, PKGDATADIR"/squircle_shine_54.png");
+
+ // BaseTexturePtr icon_background[local::IconSize::SIZE];
+ // BaseTexturePtr icon_selected_background[local::IconSize::SIZE];
+ // BaseTexturePtr icon_edge[local::IconSize::SIZE];
+ // BaseTexturePtr icon_glow[local::IconSize::SIZE];
+ // BaseTexturePtr icon_shadow[local::IconSize::SIZE];
+ // BaseTexturePtr icon_shine[local::IconSize::SIZE];
+
+ GenerateTextures(icon_background,
+ PKGDATADIR"/launcher_icon_back_150.png",
+ PKGDATADIR"/launcher_icon_back_54.png");
+ GenerateTextures(icon_selected_background,
+ PKGDATADIR"/launcher_icon_selected_back_150.png",
+ PKGDATADIR"/launcher_icon_back_54.png");
+ GenerateTextures(icon_edge,
+ PKGDATADIR"/launcher_icon_edge_150.png",
+ PKGDATADIR"/launcher_icon_edge_54.png");
+ GenerateTextures(icon_glow,
+ PKGDATADIR"/launcher_icon_glow_200.png",
+ PKGDATADIR"/launcher_icon_glow_62.png");
+ GenerateTextures(icon_shadow,
+ PKGDATADIR"/launcher_icon_shadow_200.png",
+ PKGDATADIR"/launcher_icon_shadow_62.png");
+ GenerateTextures(icon_shine,
+ PKGDATADIR"/launcher_icon_shine_150.png",
+ PKGDATADIR"/launcher_icon_shine_54.png");
+
+ SetupShaders();
+}
+
+void IconRenderer::TexturesPool::SetupShaders()
{
if (nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath())
{
@@ -1178,107 +1261,5 @@ void setup_shaders()
}
}
-
-inline nux::BaseTexture* load_texture(const char* filename)
-{
- return nux::CreateTexture2DFromFile(filename, -1, true);
-}
-
-void generate_textures(std::vector<nux::BaseTexture*>& icons, const char* big_file, const char* small_file)
-{
- icons.resize(IconSize::LAST);
- icons[IconSize::BIG] = load_texture(big_file);
- icons[IconSize::SMALL] = load_texture(small_file);
-}
-
-void generate_textures()
-{
- progress_bar_trough = load_texture(PKGDATADIR"/progress_bar_trough.png");
- progress_bar_fill = load_texture(PKGDATADIR"/progress_bar_fill.png");
-
- generate_textures(icon_background,
- PKGDATADIR"/launcher_icon_back_150.png",
- PKGDATADIR"/launcher_icon_back_54.png");
- generate_textures(icon_selected_background,
- PKGDATADIR"/launcher_icon_selected_back_150.png",
- PKGDATADIR"/launcher_icon_back_54.png");
- generate_textures(icon_edge,
- PKGDATADIR"/launcher_icon_edge_150.png",
- PKGDATADIR"/launcher_icon_edge_54.png");
- generate_textures(icon_glow,
- PKGDATADIR"/launcher_icon_glow_200.png",
- PKGDATADIR"/launcher_icon_glow_62.png");
- generate_textures(icon_shadow,
- PKGDATADIR"/launcher_icon_shadow_200.png",
- PKGDATADIR"/launcher_icon_shadow_62.png");
- generate_textures(icon_shine,
- PKGDATADIR"/launcher_icon_shine_150.png",
- PKGDATADIR"/launcher_icon_shine_54.png");
-
- // squircle_base = load_texture(PKGDATADIR"/squircle_base_54.png");
- // squircle_base_selected = load_texture(PKGDATADIR"/squircle_base_selected_54.png");
- // squircle_edge = load_texture(PKGDATADIR"/squircle_edge_54.png");
- // squircle_glow = load_texture(PKGDATADIR"/squircle_glow_62.png");
- // squircle_shadow = load_texture(PKGDATADIR"/squircle_shadow_62.png");
- // squircle_shine = load_texture(PKGDATADIR"/squircle_shine_54.png");
-
- pip_ltr = load_texture(PKGDATADIR"/launcher_pip_ltr.png");
- arrow_ltr = load_texture(PKGDATADIR"/launcher_arrow_ltr.png");
- arrow_empty_ltr = load_texture(PKGDATADIR"/launcher_arrow_outline_ltr.png");
-
- pip_rtl = load_texture(PKGDATADIR"/launcher_pip_rtl.png");
- arrow_rtl = load_texture(PKGDATADIR"/launcher_arrow_rtl.png");
- arrow_empty_rtl = load_texture(PKGDATADIR"/launcher_arrow_outline_rtl.png");
-
- offscreen_progress_texture = nux::GetGraphicsDisplay()->GetGpuDevice()
- ->CreateSystemCapableDeviceTexture(2, 2, 1, nux::BITFMT_R8G8B8A8);
-
- setup_shaders();
- textures_created = true;
-}
-
-void destroy_textures(std::vector<nux::BaseTexture*>& icons)
-{
- icons[SMALL]->UnReference();
- icons[BIG]->UnReference();
- icons.clear();
-}
-
-void destroy_textures()
-{
- if (!textures_created)
- return;
-
- progress_bar_trough->UnReference();
- progress_bar_fill->UnReference();
- pip_ltr->UnReference();
- pip_rtl->UnReference();
- arrow_ltr->UnReference();
- arrow_rtl->UnReference();
- arrow_empty_ltr->UnReference();
- arrow_empty_rtl->UnReference();
-
- destroy_textures(icon_background);
- destroy_textures(icon_selected_background);
- destroy_textures(icon_edge);
- destroy_textures(icon_glow);
- destroy_textures(icon_shadow);
- destroy_textures(icon_shine);
-
- // squircle_base->UnReference();
- // squircle_base_selected->UnReference();
- // squircle_edge->UnReference();
- // squircle_glow->UnReference();
- // squircle_shadow->UnReference();
- // squircle_shine->UnReference();
-
- IconRenderer::DestroyShortcutTextures();
-
- textures_created = false;
-}
-
-} // anon namespace
-} // namespace local
-
} // namespace ui
} // namespace unity
diff --git a/unity-shared/IconRenderer.h b/unity-shared/IconRenderer.h
index e3e458bb5..00b5985d8 100644
--- a/unity-shared/IconRenderer.h
+++ b/unity-shared/IconRenderer.h
@@ -45,12 +45,9 @@ public:
void SetTargetSize(int tile_size, int image_size, int spacing);
- static void DestroyTextures();
static void DestroyShortcutTextures();
protected:
- nux::BaseTexture* RenderCharToTexture(char label, int width, int height, nux::Color const& bg_color);
-
void RenderElement(nux::GraphicsEngine& GfxContext,
RenderArg const& arg,
nux::ObjectPtr<nux::IOpenGLBaseTexture> const& icon,
@@ -90,7 +87,9 @@ private:
int image_size;
int spacing;
- nux::Matrix4 _stored_projection_matrix;
+ struct TexturesPool;
+ std::shared_ptr<TexturesPool> textures_;
+ nux::Matrix4 stored_projection_matrix_;
};
}
diff --git a/unity-shared/SearchBar.cpp b/unity-shared/SearchBar.cpp
index bb6b8c15f..80e850457 100644
--- a/unity-shared/SearchBar.cpp
+++ b/unity-shared/SearchBar.cpp
@@ -187,7 +187,7 @@ void SearchBar::Init()
show_filters_->SetFont(SHOW_FILTERS_LABEL_DEFAULT_FONT.c_str());
show_filters_->SetTextColor(nux::color::White);
show_filters_->SetTextAlignment(StaticCairoText::NUX_ALIGN_RIGHT);
- show_filters_->SetLines(1);
+ show_filters_->SetLines(-1);
nux::BaseTexture* arrow;
arrow = style.GetGroupExpandIcon();
diff --git a/unity-shared/SearchBar.h b/unity-shared/SearchBar.h
index 8095f8348..5b502ffb7 100644
--- a/unity-shared/SearchBar.h
+++ b/unity-shared/SearchBar.h
@@ -68,7 +68,6 @@ public:
sigc::signal<void, std::string const&> live_search_reached;
private:
-
void Init();
void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
diff --git a/unity-shared/StaticCairoText.cpp b/unity-shared/StaticCairoText.cpp
index 7def057c8..e1e0de781 100644
--- a/unity-shared/StaticCairoText.cpp
+++ b/unity-shared/StaticCairoText.cpp
@@ -67,6 +67,8 @@ struct StaticCairoText::Impl
std::shared_ptr<CairoGraphics> cr;
};
+
+ void UpdateBaseSize();
Size GetTextExtents() const;
void SetAttributes(PangoLayout* layout);
@@ -92,7 +94,7 @@ struct StaticCairoText::Impl
EllipsizeState ellipsize_;
AlignState align_;
AlignState valign_;
- UnderlineState underline_;
+ UnderlineState underline_;
std::string font_;
@@ -114,7 +116,7 @@ StaticCairoText::Impl::Impl(StaticCairoText* parent, std::string const& text)
, text_color_(color::White)
, ellipsize_(NUX_ELLIPSIZE_END)
, align_(NUX_ALIGN_LEFT)
- , valign_(NUX_ALIGN_TOP)
+ , valign_(NUX_ALIGN_CENTRE)
, underline_(NUX_UNDERLINE_NONE)
, lines_(-2) // should find out why -2...
// the desired height of the layout in Pango units if positive, or desired
@@ -173,7 +175,6 @@ StaticCairoText::StaticCairoText(std::string const& text,
: View(NUX_FILE_LINE_PARAM)
, pimpl(new Impl(this, text))
{
- SetMinimumSize(1, 1);
SetAcceptKeyNavFocusOnMouseDown(false);
}
@@ -182,7 +183,6 @@ StaticCairoText::StaticCairoText(std::string const& text, bool escape_text,
: View(NUX_FILE_LINE_PARAM)
, pimpl(new Impl(this, escape_text ? GetEscapedText(text) : text))
{
- SetMinimumSize(1, 1);
SetAcceptKeyNavFocusOnMouseDown(false);
}
@@ -226,17 +226,14 @@ void StaticCairoText::SetLineSpacing(float line_spacing)
void StaticCairoText::PreLayoutManagement()
{
- Geometry geo = GetGeometry();
+ Geometry const& geo = GetGeometry();
pimpl->pre_layout_size_.width = geo.width;
pimpl->pre_layout_size_.height = geo.height;
+ pimpl->UpdateBaseSize();
- SetBaseSize(pimpl->cached_extent_.width,
- pimpl->cached_extent_.height);
if (pimpl->textures2D_.empty())
- {
pimpl->UpdateTexture();
- }
View::PreLayoutManagement();
}
@@ -293,15 +290,28 @@ void StaticCairoText::Draw(GraphicsEngine& gfxContext, bool forceDraw)
gfxContext.GetRenderStates().GetBlend(alpha, src, dest);
gfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- Color col = color::Black;
- col.alpha = 0;
- gfxContext.QRP_Color(base.x,
- base.y,
- base.width,
- base.height,
- col);
+ gfxContext.QRP_Color(base.x, base.y, base.width, base.height, color::Transparent);
+
+ int current_x = base.x;
+ int current_y = base.y;
- int current_y = base.y + ((base.height - pimpl->cached_extent_.height) / 2);
+ if (pimpl->align_ == NUX_ALIGN_CENTRE)
+ {
+ current_x += std::round((base.width - pimpl->cached_extent_.width) / 2.0f);
+ }
+ else if (pimpl->align_ == NUX_ALIGN_RIGHT)
+ {
+ current_x += base.width - pimpl->cached_extent_.width;
+ }
+
+ if (pimpl->valign_ == NUX_ALIGN_CENTRE)
+ {
+ current_y += std::round((base.height - pimpl->cached_extent_.height) / 2.0f);
+ }
+ else if (pimpl->valign_ == NUX_ALIGN_BOTTOM)
+ {
+ current_y += base.height - pimpl->cached_extent_.height;
+ }
for (BaseTexturePtr tex : pimpl->textures2D_)
{
@@ -309,7 +319,7 @@ void StaticCairoText::Draw(GraphicsEngine& gfxContext, bool forceDraw)
if (!text_tex)
break;
- gfxContext.QRP_1Tex(base.x,
+ gfxContext.QRP_1Tex(current_x,
current_y,
text_tex->GetWidth(),
text_tex->GetHeight(),
@@ -406,7 +416,7 @@ void StaticCairoText::SetTextColor(Color const& textColor)
void StaticCairoText::SetFont(std::string const& font)
{
if (pimpl->font_ != font)
- {
+ {
pimpl->font_ = font;
pimpl->need_new_extent_cache_ = true;
Size s = GetTextExtents();
@@ -501,7 +511,8 @@ std::string StaticCairoText::GetName() const
void StaticCairoText::AddProperties(GVariantBuilder* builder)
{
unity::variant::BuilderWrapper(builder)
- .add(GetGeometry());
+ .add(GetGeometry())
+ .add("text", pimpl->text_);
}
std::string StaticCairoText::Impl::GetEffectiveFont() const
@@ -524,8 +535,6 @@ Size StaticCairoText::Impl::GetTextExtents() const
PangoLayout* layout = NULL;
PangoFontDescription* desc = NULL;
PangoContext* pangoCtx = NULL;
- PangoRectangle inkRect = {0, 0, 0, 0};
- PangoRectangle logRect = {0, 0, 0, 0};
int dpi = 0;
GdkScreen* screen = gdk_screen_get_default(); // is not ref'ed
GtkSettings* settings = gtk_settings_get_default(); // is not ref'ed
@@ -537,8 +546,7 @@ Size StaticCairoText::Impl::GetTextExtents() const
Size result;
std::string font = GetEffectiveFont();
-
- int maxwidth = parent_->GetMaximumWidth();
+ nux::Size layout_size(-1, lines_ < 0 ? lines_ : std::numeric_limits<int>::min());
surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1);
cr = cairo_create(surface);
@@ -550,8 +558,8 @@ Size StaticCairoText::Impl::GetTextExtents() const
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, GetPangoEllipsizeMode());
pango_layout_set_alignment(layout, GetPangoAlignment());
- pango_layout_set_height(layout, lines_);
- pango_layout_set_width(layout, maxwidth * PANGO_SCALE);
+ pango_layout_set_width(layout, layout_size.width);
+ pango_layout_set_height(layout, layout_size.height);
pango_layout_set_markup(layout, text_.c_str(), -1);
pango_layout_set_spacing(layout, line_spacing_ * PANGO_SCALE);
@@ -570,15 +578,15 @@ Size StaticCairoText::Impl::GetTextExtents() const
(float) dpi / (float) PANGO_SCALE);
}
pango_layout_context_changed(layout);
- pango_layout_get_extents(layout, &inkRect, &logRect);
+ pango_layout_get_pixel_size(layout, &result.width, &result.height);
- // logRect has some issues using italic style
- if (inkRect.x + inkRect.width > logRect.x + logRect.width)
- result.width = std::ceil(static_cast<float>(inkRect.x + inkRect.width - logRect.x) / PANGO_SCALE);
- else
- result.width = std::ceil(static_cast<float>(logRect.width) / PANGO_SCALE);
+ if (result.width > parent_->GetMaximumWidth())
+ {
+ pango_layout_set_width(layout, parent_->GetMaximumWidth() * PANGO_SCALE);
+ pango_layout_context_changed(layout);
+ pango_layout_get_pixel_size(layout, &result.width, &result.height);
+ }
- result.height = std::ceil(static_cast<float>(logRect.height) / PANGO_SCALE);
cached_extent_ = result;
baseline_ = pango_layout_get_baseline(layout) / PANGO_SCALE;
need_new_extent_cache_ = false;
@@ -671,22 +679,8 @@ void StaticCairoText::Impl::DrawText(CacheTexture::Ptr const& texture)
if (!texture)
return;
- nux::Size tex_size(parent_->GetMaximumWidth(), parent_->GetMaximumHeight());
- nux::Size layout_size(tex_size.width * PANGO_SCALE, tex_size.height * PANGO_SCALE);
-
- if (tex_size.width == nux::AREA_MAX_WIDTH)
- {
- tex_size.width = parent_->GetWidth();
- layout_size.width = -1;
- }
-
- if (tex_size.height == nux::AREA_MAX_HEIGHT)
- {
- tex_size.height = parent_->GetHeight();
- layout_size.height = -1;
- }
-
- texture->cr.reset(new CairoGraphics(CAIRO_FORMAT_ARGB32, tex_size.width, tex_size.height));
+ nux::Size layout_size(-1, lines_ < 0 ? lines_ : std::numeric_limits<int>::min());
+ texture->cr.reset(new CairoGraphics(CAIRO_FORMAT_ARGB32, cached_extent_.width, cached_extent_.height));
cairo_t* cr = texture->cr->GetInternalContext();
PangoLayout* layout = NULL;
@@ -702,8 +696,9 @@ void StaticCairoText::Impl::DrawText(CacheTexture::Ptr const& texture)
cairo_set_font_options(cr, gdk_screen_get_font_options(screen));
layout = pango_cairo_create_layout(cr);
- desc = pango_font_description_from_string(font.c_str());
+
+ desc = pango_font_description_from_string(font.c_str());
pango_layout_set_font_description(layout, desc);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, GetPangoEllipsizeMode());
@@ -713,8 +708,6 @@ void StaticCairoText::Impl::DrawText(CacheTexture::Ptr const& texture)
pango_layout_set_height(layout, layout_size.height);
pango_layout_set_spacing(layout, line_spacing_ * PANGO_SCALE);
- pango_layout_set_height(layout, lines_);
-
SetAttributes(layout);
pangoCtx = pango_layout_get_context(layout); // is not ref'ed
@@ -732,14 +725,22 @@ void StaticCairoText::Impl::DrawText(CacheTexture::Ptr const& texture)
(float) dpi / (float) PANGO_SCALE);
}
+ Size result;
+ pango_layout_context_changed(layout);
+ pango_layout_get_pixel_size(layout, &result.width, &result.height);
+
+ if (result.width > parent_->GetMaximumWidth())
+ {
+ pango_layout_set_width(layout, parent_->GetMaximumWidth() * PANGO_SCALE);
+ pango_layout_context_changed(layout);
+ }
+
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, text_color_.red, text_color_.green, text_color_.blue, text_color_.alpha);
- pango_layout_context_changed(layout);
-
cairo_move_to(cr, 0.0f, 0.0f);
pango_cairo_show_layout(cr, layout);
@@ -750,10 +751,15 @@ void StaticCairoText::Impl::DrawText(CacheTexture::Ptr const& texture)
g_object_unref(layout);
}
+void StaticCairoText::Impl::UpdateBaseSize()
+{
+ parent_->SetBaseSize(cached_extent_.width, cached_extent_.height);
+}
+
void StaticCairoText::Impl::UpdateTexture()
{
- auto const& size = GetTextExtents();
- parent_->SetBaseSize(size.width, size.height);
+ GetTextExtents();
+ UpdateBaseSize();
textures2D_.clear();
for (auto const& texture : cache_textures_)
diff --git a/unity-shared/Timer.h b/unity-shared/Timer.h
index 8669164b5..a646dec62 100644
--- a/unity-shared/Timer.h
+++ b/unity-shared/Timer.h
@@ -20,7 +20,6 @@
#ifndef UNITY_TIMER_H
#define UNITY_TIMER_H
-#include <iosfwd>
#include <string>
#include <glib.h>