summaryrefslogtreecommitdiff
diff options
-rw-r--r--UnityCore/DBusIndicators.cpp33
-rw-r--r--UnityCore/DBusIndicators.h4
-rw-r--r--UnityCore/Indicator.cpp15
-rw-r--r--UnityCore/Indicator.h1
-rwxr-xr-xdash/LensView.cpp2
-rwxr-xr-xdash/PlacesGroup.cpp22
-rw-r--r--dash/PlacesGroup.h5
-rw-r--r--dash/previews/ActionButton.cpp2
-rw-r--r--dash/previews/SocialPreviewContent.cpp77
-rw-r--r--dash/previews/SocialPreviewContent.h4
-rw-r--r--launcher/Launcher.cpp4
-rw-r--r--launcher/TrashLauncherIcon.cpp2
-rw-r--r--launcher/VolumeImp.cpp8
-rw-r--r--manual-tests/Panel.txt16
-rw-r--r--panel/PanelController.cpp3
-rw-r--r--panel/PanelView.cpp2
-rw-r--r--plugins/unityshell/src/unityshell.cpp63
-rw-r--r--plugins/unityshell/src/unityshell.h2
-rw-r--r--plugins/unityshell/src/unityshell_glow.cpp86
-rw-r--r--po/POTFILES.in1
-rw-r--r--tests/CMakeLists.txt10
-rw-r--r--tests/autopilot/unity/tests/test_hud.py4
-rw-r--r--tests/test_dbus_indicators.cpp99
-rw-r--r--tests/test_indicator.cpp3
-rw-r--r--tests/test_launcher.cpp20
-rw-r--r--tests/test_places_group.cpp103
-rw-r--r--tests/test_service_main.c4
-rw-r--r--tests/test_service_panel.c253
-rw-r--r--tests/test_service_panel.h46
-rw-r--r--tests/test_utils.h14
-rwxr-xr-xunity-shared/DashStyle.cpp4
-rwxr-xr-xunity-shared/DashStyle.h6
-rw-r--r--unity-shared/DashStyleInterface.h53
-rw-r--r--unity-shared/IconLoader.cpp48
-rw-r--r--unity-shared/SearchBar.cpp39
35 files changed, 857 insertions, 201 deletions
diff --git a/UnityCore/DBusIndicators.cpp b/UnityCore/DBusIndicators.cpp
index 2e3df31ce..49250973f 100644
--- a/UnityCore/DBusIndicators.cpp
+++ b/UnityCore/DBusIndicators.cpp
@@ -48,7 +48,7 @@ const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service");
class DBusIndicators::Impl
{
public:
- Impl(DBusIndicators* owner);
+ Impl(std::string const& dbus_name, DBusIndicators* owner);
void CheckLocalService();
void RequestSyncAll();
@@ -84,9 +84,9 @@ public:
// Public Methods
-DBusIndicators::Impl::Impl(DBusIndicators* owner)
+DBusIndicators::Impl::Impl(std::string const& dbus_name, DBusIndicators* owner)
: owner_(owner)
- , gproxy_(SERVICE_NAME, SERVICE_PATH, SERVICE_IFACE,
+ , gproxy_(dbus_name, SERVICE_PATH, SERVICE_IFACE,
G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
{
gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync));
@@ -276,6 +276,8 @@ void DBusIndicators::Impl::Sync(GVariant* args)
return;
std::map<Indicator::Ptr, Indicator::Entries> indicators;
+ int wantedIndex = 0;
+ bool anyIndexDifferent = false;
g_variant_get(args, "(a(ssssbbusbbi))", &iter);
while (g_variant_iter_loop(iter, "(ssssbbusbbi)",
@@ -305,7 +307,18 @@ void DBusIndicators::Impl::Sync(GVariant* args)
// Null entries (entry_id == "") are empty indicators.
if (entry != "")
{
- Entry::Ptr e = indicator->GetEntry(entry_id);
+ Entry::Ptr e;
+ if (!anyIndexDifferent)
+ {
+ // Indicators can only add or remove entries, so if
+ // there is a index change we can't reuse the existing ones
+ // after that index
+ int existingEntryIndex = indicator->EntryIndex(entry_id);
+ if (wantedIndex == existingEntryIndex)
+ e = indicator->GetEntry(entry_id);
+ else
+ anyIndexDifferent = true;
+ }
if (!e)
{
@@ -321,6 +334,7 @@ void DBusIndicators::Impl::Sync(GVariant* args)
}
entries.push_back(e);
+ wantedIndex++;
}
}
g_variant_iter_free(iter);
@@ -393,12 +407,21 @@ void DBusIndicators::Impl::SyncGeometries(std::string const& name,
}
DBusIndicators::DBusIndicators()
- : pimpl(new Impl(this))
+ : pimpl(new Impl(SERVICE_NAME, this))
+{}
+
+DBusIndicators::DBusIndicators(std::string const& dbus_name)
+ : pimpl(new Impl(dbus_name, this))
{}
DBusIndicators::~DBusIndicators()
{}
+bool DBusIndicators::IsConnected() const
+{
+ return pimpl->gproxy_.IsConnected();
+}
+
void DBusIndicators::SyncGeometries(std::string const& name,
EntryLocationMap const& locations)
{
diff --git a/UnityCore/DBusIndicators.h b/UnityCore/DBusIndicators.h
index 13bf445eb..5ac1111c8 100644
--- a/UnityCore/DBusIndicators.h
+++ b/UnityCore/DBusIndicators.h
@@ -50,6 +50,10 @@ public:
virtual void OnShowAppMenu(unsigned int xid, int x, int y,
unsigned int timestamp);
+protected:
+ DBusIndicators(std::string const& dbus_name);
+ bool IsConnected() const;
+
private:
class Impl;
std::unique_ptr<Impl> pimpl;
diff --git a/UnityCore/Indicator.cpp b/UnityCore/Indicator.cpp
index c5eb9f127..8fe03252c 100644
--- a/UnityCore/Indicator.cpp
+++ b/UnityCore/Indicator.cpp
@@ -115,6 +115,21 @@ Entry::Ptr Indicator::GetEntry(std::string const& entry_id) const
return Entry::Ptr();
}
+int Indicator::EntryIndex(std::string const& entry_id) const
+{
+ int i = 0;
+ for (auto entry : entries_)
+ {
+ if (entry->id() == entry_id)
+ {
+ return i;
+ }
+ ++i;
+ }
+
+ return -1;
+}
+
void Indicator::OnEntryShowMenu(std::string const& entry_id, unsigned int xid,
int x, int y, unsigned int button, unsigned int timestamp)
{
diff --git a/UnityCore/Indicator.h b/UnityCore/Indicator.h
index 1fe8f1c27..23b4bd575 100644
--- a/UnityCore/Indicator.h
+++ b/UnityCore/Indicator.h
@@ -48,6 +48,7 @@ public:
void Sync(Entries const& new_entries);
Entry::Ptr GetEntry(std::string const& entry_id) const;
+ int EntryIndex(std::string const& entry_id) const;
Entries GetEntries() const;
// Signals
diff --git a/dash/LensView.cpp b/dash/LensView.cpp
index 3dab2dd1d..444905b50 100755
--- a/dash/LensView.cpp
+++ b/dash/LensView.cpp
@@ -308,7 +308,7 @@ void LensView::OnCategoryAdded(Category const& category)
if (existing_group->GetCategoryIndex() == index) return;
}
- PlacesGroup* group = new PlacesGroup();
+ PlacesGroup* group = new PlacesGroup(dash::Style::Instance());
AddChild(group);
group->SetName(name);
group->SetIcon(icon_hint);
diff --git a/dash/PlacesGroup.cpp b/dash/PlacesGroup.cpp
index 47e7d0e65..43031695e 100755
--- a/dash/PlacesGroup.cpp
+++ b/dash/PlacesGroup.cpp
@@ -31,8 +31,6 @@
#include <UnityCore/GLibWrapper.h>
#include "unity-shared/StaticCairoText.h"
-#include "unity-shared/DashStyle.h"
-#include "unity-shared/LineSeparator.h"
#include "unity-shared/ubus-server.h"
#include "unity-shared/UBusMessages.h"
@@ -112,8 +110,9 @@ protected:
NUX_IMPLEMENT_OBJECT_TYPE(PlacesGroup);
-PlacesGroup::PlacesGroup()
+PlacesGroup::PlacesGroup(dash::StyleInterface& style)
: nux::View(NUX_TRACKER_LOCATION),
+ _style(style),
_child_view(nullptr),
_is_expanded(false),
_n_visible_items_in_unexpand_mode(0),
@@ -122,15 +121,13 @@ PlacesGroup::PlacesGroup()
_coverflow_enabled(false),
disabled_header_count_(false)
{
- dash::Style& style = dash::Style::Instance();
-
SetAcceptKeyNavFocusOnMouseDown(false);
SetAcceptKeyNavFocusOnMouseEnter(false);
- nux::BaseTexture* arrow = style.GetGroupUnexpandIcon();
+ nux::BaseTexture* arrow = _style.GetGroupExpandIcon();
- _background = style.GetCategoryBackground();
- _background_nofilters = style.GetCategoryBackgroundNoFilters();
+ _background = _style.GetCategoryBackground();
+ _background_nofilters = _style.GetCategoryBackgroundNoFilters();
nux::ROPConfig rop;
rop.Blend = true;
@@ -154,7 +151,7 @@ PlacesGroup::PlacesGroup()
_group_layout->AddView(_header_view, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL);
_header_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
- _header_layout->SetLeftAndRightPadding(style.GetCategoryHeaderLeftPadding(), 0);
+ _header_layout->SetLeftAndRightPadding(_style.GetCategoryHeaderLeftPadding(), 0);
_header_layout->SetSpaceBetweenChildren(10);
_header_view->SetLayout(_header_layout);
@@ -449,7 +446,7 @@ long PlacesGroup::ComputeContentSize()
// only the width matters
if (_cached_geometry.GetWidth() != geo.GetWidth())
{
- _focus_layer.reset(dash::Style::Instance().FocusOverlay(geo.width - kHighlightLeftPadding - kHighlightRightPadding, kHighlightHeight));
+ _focus_layer.reset(_style.FocusOverlay(geo.width - kHighlightLeftPadding - kHighlightRightPadding, kHighlightHeight));
_cached_geometry = geo;
}
return ret;
@@ -552,11 +549,10 @@ PlacesGroup::SetExpanded(bool is_expanded)
Refresh();
- dash::Style& style = dash::Style::Instance();
if (_is_expanded)
- _expand_icon->SetTexture(style.GetGroupUnexpandIcon());
+ _expand_icon->SetTexture(_style.GetGroupUnexpandIcon());
else
- _expand_icon->SetTexture(style.GetGroupExpandIcon());
+ _expand_icon->SetTexture(_style.GetGroupExpandIcon());
expanded.emit(this);
}
diff --git a/dash/PlacesGroup.h b/dash/PlacesGroup.h
index a7c10dae6..6f068b952 100644
--- a/dash/PlacesGroup.h
+++ b/dash/PlacesGroup.h
@@ -28,6 +28,7 @@
#include <sigc++/sigc++.h>
+#include "unity-shared/DashStyleInterface.h"
#include "unity-shared/IconTexture.h"
#include "unity-shared/Introspectable.h"
#include "unity-shared/StaticCairoText.h"
@@ -53,7 +54,7 @@ class PlacesGroup : public nux::View, public debug::Introspectable
NUX_DECLARE_OBJECT_TYPE(PlacesGroup, nux::View);
public:
- PlacesGroup();
+ PlacesGroup(dash::StyleInterface& style);
void SetIcon(std::string const& icon);
void SetName(std::string const& name);
@@ -114,6 +115,8 @@ private:
void RefreshLabel();
private:
+ dash::StyleInterface& _style;
+
nux::VLayout* _group_layout;
nux::View* _header_view;
nux::HLayout* _header_layout;
diff --git a/dash/previews/ActionButton.cpp b/dash/previews/ActionButton.cpp
index 7c392787f..76582f6a4 100644
--- a/dash/previews/ActionButton.cpp
+++ b/dash/previews/ActionButton.cpp
@@ -199,7 +199,7 @@ void ActionButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::Butt
void ActionButton::RedrawFocusOverlay(nux::Geometry const& geom, cairo_t* cr)
{
- Style::Instance().ButtonFocusOverlay(cr);
+ Style::Instance().ButtonFocusOverlay(cr, 0.20f);
}
long ActionButton::ComputeContentSize()
diff --git a/dash/previews/SocialPreviewContent.cpp b/dash/previews/SocialPreviewContent.cpp
index f1f476241..7b224e686 100644
--- a/dash/previews/SocialPreviewContent.cpp
+++ b/dash/previews/SocialPreviewContent.cpp
@@ -38,14 +38,19 @@ namespace previews
namespace
{
nux::logging::Logger logger("unity.dash.previews.socialpreviewcontent");
+
+const int BUBBLE_WIDTH = 300;
+const int BUBBLE_HEIGHT = 250;
+const int TAIL_HEIGHT = 50;
+const int TAIL_POS_FROM_RIGHT = 60;
}
inline nux::Geometry GetBubbleGeometry(nux::Geometry const& geo)
{
- return nux::Geometry(geo.x + geo.width*0.1,
- geo.y + geo.height*0.1,
- geo.width - 2*(geo.width*0.1),
- geo.height - 2*(geo.height*0.1));
+ int width = MIN(BUBBLE_WIDTH, geo.width);
+ int height = MIN(BUBBLE_HEIGHT + TAIL_HEIGHT, geo.height);
+
+ return nux::Geometry(geo.x + (geo.width - width)/2, geo.y + (geo.height - height)/2, width, height);
}
NUX_IMPLEMENT_OBJECT_TYPE(SocialPreviewContent);
@@ -98,7 +103,7 @@ void SocialPreviewContent::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw
tex->GetHeight(),
tex,
texxform,
- nux::Color(0.2f, 0.2f, 0.2f, 0.2f));
+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
gfx_engine.GetRenderStates().SetBlend(alpha, src, dest);
@@ -145,10 +150,8 @@ void SocialPreviewContent::UpdateBaloonTexture()
nux::Geometry geo_cr(GetBubbleGeometry(geo));
- double tail_width = MAX(0, MIN(geo_cr.width - 2*15.0, MIN(geo_cr.width*0.125, geo_cr.height*0.125)));
-
int max_width = geo_cr.width - 2*(geo_cr.width*0.1);
- int max_height = geo_cr.height - 2*(geo_cr.height*0.1) - tail_width;
+ int max_height = (geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1);
// this will update the texture with the actual size of the text.
text_->SetMaximumHeight(max_height);
@@ -156,8 +159,8 @@ void SocialPreviewContent::UpdateBaloonTexture()
nux::Geometry const& geo_text = text_->GetGeometry();
// center text
- text_->SetBaseX(geo.x + geo.width/2 - geo_text.width/2);
- text_->SetBaseY(geo.y + geo.height/2 - geo_text.height/2 - tail_width/2);
+ text_->SetBaseX(geo_cr.x + geo_cr.width/2 - geo_text.width/2);
+ text_->SetBaseY(geo_cr.y + geo_cr.height/2 - geo_text.height/2 - TAIL_HEIGHT/2);
if (geo_cr.width > 0 && geo_cr.height > 0)
{
@@ -167,21 +170,18 @@ void SocialPreviewContent::UpdateBaloonTexture()
void SocialPreviewContent::RedrawBubble(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state)
{
- double blur = 4.0;
+ double line_width = 6.0;
+ double radius = 28.0;
+ double x = 0.0;
+ double y = 0.0;
- double line_width = 1.0;
- double radius = 20.0;
- double tailWidthPercentage = 0.125;
- double tailPositionPercentage = 0.7;
- double x = 0.0 + blur;
- double y = 0.0 + blur;
- double width = cairo_image_surface_get_width(cairo_get_target(cr)) - 2*blur;
- double height = cairo_image_surface_get_height(cairo_get_target(cr)) - 2*blur;
+ double width = MAX(0, cairo_image_surface_get_width(cairo_get_target(cr)));
+ double height = MAX(0, cairo_image_surface_get_height(cairo_get_target(cr)) - TAIL_HEIGHT);
+ double tailPosition = x + width - TAIL_POS_FROM_RIGHT - TAIL_HEIGHT;
if (width > 0 && height > 0)
{
- DrawBubble(cr, line_width, radius, x, y, width, height, tailPositionPercentage, tailWidthPercentage);
- dash::Style::Instance().Blur(cr, blur);
+ DrawBubble(cr, line_width, radius, x, y, width, height, tailPosition, TAIL_HEIGHT);
}
}
@@ -214,8 +214,8 @@ void SocialPreviewContent::DrawBubble(cairo_t* cr,
double y,
double width,
double height,
- double tailPositionPercentage,
- double tailWidthPercentage)
+ double tailPosition,
+ double tailWidth)
{
// sanity check
if (cairo_status(cr) != CAIRO_STATUS_SUCCESS &&
@@ -224,16 +224,6 @@ void SocialPreviewContent::DrawBubble(cairo_t* cr,
cairo_set_line_width(cr, line_width);
- double tailWidth = MAX(0, MIN(width - 2*radius, MIN(width*tailWidthPercentage, height*tailWidthPercentage)));
- double tail_start_pos = x + tailPositionPercentage*width - tailWidth/2;
-
- // recitfications for outer draw.
- x += line_width/2;
- y += line_width/2;
- height -= line_width;
- height -= tailWidth;
- width -= line_width;
-
bool odd = true;
odd = line_width != double((int)line_width);
@@ -262,16 +252,16 @@ void SocialPreviewContent::DrawBubble(cairo_t* cr,
0.0f * G_PI / 180.0f,
90.0f * G_PI / 180.0f);
- if (tailWidth > 0.0)
+ if (tailWidth > 0.0 && tailPosition > 0 && tailPosition <= (x + width - tailWidth - radius))
{
// tail-right, tail top
- cairo_line_to(cr, _align(tail_start_pos + tailWidth, odd), _align(y + height, odd));
+ cairo_line_to(cr, _align(tailPosition + tailWidth, odd), _align(y + height, odd));
// tail-right, tail bottom
- cairo_line_to(cr, _align(tail_start_pos + tailWidth, odd), _align(y + height + tailWidth, odd));
+ cairo_line_to(cr, _align(tailPosition + tailWidth, odd), _align(y + height + tailWidth, odd));
// tail-right, tail bottom
- cairo_line_to(cr, _align(tail_start_pos, odd), _align(y + height, odd));
+ cairo_line_to(cr, _align(tailPosition, odd), _align(y + height, odd));
}
// bottom-left, right of the corner
@@ -293,14 +283,13 @@ void SocialPreviewContent::DrawBubble(cairo_t* cr,
180.0f * G_PI / 180.0f,
270.0f * G_PI / 180.0f);
+ nux::Color color_fill(1.0, 1.0, 1.0, 0.2);
+ cairo_set_source_rgba(cr, color_fill.red, color_fill.green, color_fill.blue, color_fill.alpha);
+ cairo_fill_preserve(cr);
- nux::Color color(0.53, 1.0, 0.66, 0.5);
- if (color.alpha != 0.0)
- {
- cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
- cairo_fill_preserve(cr);
- }
- cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OUT);
+ nux::Color color_stroke(1.0, 1.0, 1.0, 0.5);
+ cairo_set_source_rgba(cr, color_stroke.red, color_stroke.green, color_stroke.blue, color_stroke.alpha);
cairo_stroke(cr);
}
diff --git a/dash/previews/SocialPreviewContent.h b/dash/previews/SocialPreviewContent.h
index 8dedef436..308a99e32 100644
--- a/dash/previews/SocialPreviewContent.h
+++ b/dash/previews/SocialPreviewContent.h
@@ -66,8 +66,8 @@ protected:
double y,
double width,
double height,
- double tailPositionPercentage,
- double tailWidthPercentage);
+ double tailPosition,
+ double tailWidth);
virtual std::string GetName() const;
virtual void AddProperties(GVariantBuilder* builder);
diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp
index 29a1b5709..dffa1c375 100644
--- a/launcher/Launcher.cpp
+++ b/launcher/Launcher.cpp
@@ -2054,9 +2054,7 @@ void Launcher::EndIconDrag()
{
if (!_drag_window->Cancelled() && _model->IconIndex(_drag_icon) != _drag_icon_position)
{
- if (_drag_icon->GetIconType() == AbstractLauncherIcon::IconType::DEVICE)
- _drag_icon->Stick(false);
-
+ _drag_icon->Stick(false);
_model->Save();
}
diff --git a/launcher/TrashLauncherIcon.cpp b/launcher/TrashLauncherIcon.cpp
index 865d3edfe..928474b32 100644
--- a/launcher/TrashLauncherIcon.cpp
+++ b/launcher/TrashLauncherIcon.cpp
@@ -127,7 +127,7 @@ void TrashLauncherIcon::UpdateTrashIconCb(GObject* source,
if (info)
{
- glib::Object<GIcon> icon(g_file_info_get_icon(info));
+ glib::Object<GIcon> icon(g_file_info_get_icon(info), glib::AddRef());
glib::String icon_string(g_icon_to_string(icon));
self->icon_name = icon_string.Str();
diff --git a/launcher/VolumeImp.cpp b/launcher/VolumeImp.cpp
index 2616b5424..51b96ce3c 100644
--- a/launcher/VolumeImp.cpp
+++ b/launcher/VolumeImp.cpp
@@ -127,7 +127,7 @@ public:
g_volume_eject_with_operation(volume_,
(GMountUnmountFlags)0,
mount_op,
- nullptr,
+ cancellable_,
(GAsyncReadyCallback)OnEjectReady,
this);
}
@@ -155,7 +155,7 @@ public:
g_volume_mount(volume_,
(GMountMountFlags) 0,
mount_op,
- nullptr,
+ cancellable_,
(GAsyncReadyCallback) &Impl::OnMountFinish,
this);
}
@@ -195,7 +195,7 @@ public:
g_drive_stop(drive,
(GMountUnmountFlags)0,
mount_op,
- nullptr, nullptr, nullptr);
+ cancellable_, nullptr, nullptr);
}
void Unmount()
@@ -209,7 +209,7 @@ public:
g_mount_unmount_with_operation(mount,
(GMountUnmountFlags)0,
op,
- nullptr, nullptr, nullptr);
+ cancellable_, nullptr, nullptr);
}
VolumeImp* parent_;
diff --git a/manual-tests/Panel.txt b/manual-tests/Panel.txt
index d36af4588..d7d74676a 100644
--- a/manual-tests/Panel.txt
+++ b/manual-tests/Panel.txt
@@ -95,3 +95,19 @@ Expected Result:
At no point during the actions should the panel (or launcher) blink or
flicker out of existence.
+
+Panel shadow overdraw
+---------------------
+Setup:
+#. Install Google Chrome or Chromium.
+
+Actions:
+#. Maximize a Chrome window.
+#. Open several tabs so that the titles of some tabs are not fully visible
+ and fade out to the right.
+#. Hover the mouse over the very top part of some tabs so tooltips appear.
+
+Expected Result:
+ No part of the panel shadow should ever appear on top of the maximized
+ Chrome window.
+
diff --git a/panel/PanelController.cpp b/panel/PanelController.cpp
index 250c040a7..69ed3b0b5 100644
--- a/panel/PanelController.cpp
+++ b/panel/PanelController.cpp
@@ -301,7 +301,8 @@ float Controller::Impl::opacity() const
}
Controller::Controller()
- : pimpl(new Impl())
+ : launcher_width(64)
+ , pimpl(new Impl())
{
UScreen* screen = UScreen::GetDefault();
screen->changed.connect(sigc::mem_fun(this, &Controller::OnScreenChanged));
diff --git a/panel/PanelView.cpp b/panel/PanelView.cpp
index ac2fad3c6..95704e3a1 100644
--- a/panel/PanelView.cpp
+++ b/panel/PanelView.cpp
@@ -64,7 +64,7 @@ PanelView::PanelView(NUX_FILE_LINE_DECL)
, _opacity(1.0f)
, _monitor(0)
, _stored_dash_width(0)
- , _launcher_width(0)
+ , _launcher_width(64)
{
panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelView::ForceUpdateBackground));
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 306539e36..37d5c741d 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -112,7 +112,7 @@ namespace decoration
const unsigned CLOSE_SIZE = 19;
const unsigned ITEMS_PADDING = 5;
const unsigned RADIUS = 8;
-const unsigned GLOW = 20;
+const unsigned GLOW = 30;
const nux::Color GLOW_COLOR(221, 72, 20);
} // decoration namespace
} // scale namespace
@@ -560,6 +560,9 @@ void UnityScreen::setPanelShadowMatrix(const GLMatrix& matrix)
void UnityScreen::paintPanelShadow(const CompRegion& clip)
{
+ if (panel_controller_->opacity() == 0.0f)
+ return;
+
if (sources_.GetSource(local::RELAYOUT_TIMEOUT))
return;
@@ -585,22 +588,6 @@ void UnityScreen::paintPanelShadow(const CompRegion& clip)
if (redraw.isEmpty())
return;
- const CompRect& bounds(redraw.boundingRect());
-
- // Sub-rectangle of the shadow needing redrawing:
- float x1 = bounds.x1();
- float y1 = bounds.y1();
- float x2 = bounds.x2();
- float y2 = bounds.y2();
-
- // Texture coordinates of the above rectangle:
- float tx1 = (x1 - shadowX) / shadowWidth;
- float ty1 = (y1 - shadowY) / shadowHeight;
- float tx2 = (x2 - shadowX) / shadowWidth;
- float ty2 = (y2 - shadowY) / shadowHeight;
-
- nuxPrologue();
-
// compiz doesn't use the same method of tracking monitors as our toolkit
// we need to make sure we properly associate with the right monitor
int current_monitor = -1;
@@ -616,8 +603,14 @@ void UnityScreen::paintPanelShadow(const CompRegion& clip)
i++;
}
- if (!(launcher_controller_->IsOverlayOpen() && current_monitor == overlay_monitor_)
- && panel_controller_->opacity() > 0.0f)
+ if (launcher_controller_->IsOverlayOpen() && current_monitor == overlay_monitor_)
+ return;
+
+ nuxPrologue();
+
+ const CompRect::vector& rects = redraw.rects();
+
+ for (auto const& r : rects)
{
foreach(GLTexture * tex, _shadow_texture)
{
@@ -639,6 +632,18 @@ void UnityScreen::paintPanelShadow(const CompRegion& clip)
(GLushort)(panel_controller_->opacity() * 0xFFFF)
};
+ // Sub-rectangle of the shadow needing redrawing:
+ float x1 = r.x1();
+ float y1 = r.y1();
+ float x2 = r.x2();
+ float y2 = r.y2();
+
+ // Texture coordinates of the above rectangle:
+ float tx1 = (x1 - shadowX) / shadowWidth;
+ float ty1 = (y1 - shadowY) / shadowHeight;
+ float tx2 = (x2 - shadowX) / shadowWidth;
+ float ty2 = (y2 - shadowY) / shadowHeight;
+
vertexData = {
x1, y1, 0,
x1, y2, 0,
@@ -2466,6 +2471,15 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
}
}
+ if (WindowManager::Default().IsScaleActive() && ScaleScreen::get(screen)->getSelectedWindow() == window->id())
+ {
+ nux::Geometry scaled_geo = GetScaledGeometry();
+ int inside_glow = scale::decoration::RADIUS/4;
+ scaled_geo.Expand(-inside_glow, -inside_glow);
+ glow::Quads const& quads = computeGlowQuads(scaled_geo, glow_texture_, scale::decoration::GLOW);
+ paintGlow(matrix, attrib, region, quads, glow_texture_, scale::decoration::GLOW_COLOR, mask);
+ }
+
return gWindow->glPaint(wAttrib, matrix, region, mask);
}
@@ -2527,17 +2541,6 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
uScreen->paintPanelShadow(region);
}
- if (WindowManager::Default().IsScaleActive() &&
- ScaleScreen::get(screen)->getSelectedWindow() == window->id())
- {
- if (!region.isEmpty())
- {
- double scale = ScaleWindow::get(window)->getCurrentPosition().scale;
- glow::Quads const& quads = computeGlowQuads(glow_texture_, scale::decoration::GLOW, scale);
- paintGlow(matrix, attrib, region, quads, glow_texture_, scale::decoration::GLOW_COLOR, mask);
- }
- }
-
return ret;
}
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 3a9112df2..48e2d2f53 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -450,7 +450,7 @@ private:
void DrawTexture(GLTexture::List const& textures, GLWindowPaintAttrib const&,
GLMatrix const&, unsigned mask, int x, int y, double aspect = 1.0f);
- glow::Quads computeGlowQuads(GLTexture::List const& texture, int glow_size, double window_aspect = 1.0f);
+ glow::Quads computeGlowQuads(nux::Geometry const& geo, GLTexture::List const& texture, int glow_size);
void paintGlow(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&,
glow::Quads const&, GLTexture::List const&, nux::Color const&, unsigned mask);
diff --git a/plugins/unityshell/src/unityshell_glow.cpp b/plugins/unityshell/src/unityshell_glow.cpp
index bc150c434..004ac54b0 100644
--- a/plugins/unityshell/src/unityshell_glow.cpp
+++ b/plugins/unityshell/src/unityshell_glow.cpp
@@ -130,7 +130,7 @@ UnityWindow::paintGlow(GLMatrix const& transform, GLWindowPaintAttrib const& att
* adjusted by the matrix scale factor (matrix->xx and matrix->yy)
*
*/
-glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int glow_size, double window_aspect)
+glow::Quads UnityWindow::computeGlowQuads(nux::Geometry const& geo, GLTexture::List const& texture, int glow_size)
{
glow::Quads glow_quads;
@@ -139,13 +139,11 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
int x1, x2, y1, y2;
int glow_offset;
- CompRect const& border_rect = window->borderRect();
GLTexture::Matrix const& matrix = texture.front()->matrix();
CompRect *box;
GLTexture::Matrix *quadMatrix;
- glow_size /= window_aspect;
glow_offset = (glow_size * texture::GLOW_OFFSET / texture::GLOW_SIZE) + 1;
/* Top left corner */
@@ -156,8 +154,8 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
/* Set the desired rect dimentions
* for the part of the glow we are painting */
- x1 = border_rect.x() - glow_size + glow_offset;
- y1 = border_rect.y() - glow_size + glow_offset;
+ x1 = geo.x - glow_size + glow_offset;
+ y1 = geo.y - glow_size + glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -175,10 +173,8 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
quadMatrix->x0 = -(x1 * quadMatrix->xx);
quadMatrix->y0 = -(y1 * quadMatrix->yy);
- x2 = std::min<int>(border_rect.x() + glow_offset,
- border_rect.x() + (border_rect.width() / 2));
- y2 = std::min<int>(border_rect.y() + glow_offset,
- border_rect.y() + (border_rect.height() / 2));
+ x2 = std::min<int>(geo.x + glow_offset, geo.x + (geo.width / 2));
+ y2 = std::min<int>(geo.y + glow_offset, geo.y + (geo.height / 2));
box->setGeometry(x1, y1, x2 - x1, y2 - y1);
@@ -190,9 +186,9 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
/* Set the desired rect dimentions
* for the part of the glow we are painting */
- x1 = border_rect.x() + border_rect.width() - glow_offset;
- y1 = border_rect.y() - glow_size + glow_offset;
- x2 = border_rect.x() + border_rect.width() + glow_size - glow_offset;
+ x1 = geo.x + geo.width - glow_offset;
+ y1 = geo.y - glow_size + glow_offset;
+ x2 = geo.x + geo.width + glow_size - glow_offset;
/*
* 2x2 Matrix here, adjust both x and y scale factors
@@ -213,10 +209,8 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
quadMatrix->y0 = -(y1 * quadMatrix->yy);
- x1 = std::max<int>(border_rect.x() + border_rect.width() - glow_offset,
- border_rect.x() + (border_rect.width() / 2));
- y2 = std::min<int>(border_rect.y() + glow_offset,
- border_rect.y() + (border_rect.height() / 2));
+ x1 = std::max<int>(geo.x + geo.width - glow_offset, geo.x + (geo.width / 2));
+ y2 = std::min<int>(geo.y + glow_offset, geo.y + (geo.height / 2));
box->setGeometry(x1, y1, x2 - x1, y2 - y1);
@@ -225,10 +219,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::BOTTOMLEFT].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::BOTTOMLEFT].matrix;
- x1 = border_rect.x() - glow_size + glow_offset;
- y1 = border_rect.y() + border_rect.height() - glow_offset;
- x2 = border_rect.x() + glow_offset;
- y2 = border_rect.y() + border_rect.height() + glow_size - glow_offset;
+ x1 = geo.x - glow_size + glow_offset;
+ y1 = geo.y + geo.height - glow_offset;
+ x2 = geo.x + glow_offset;
+ y2 = geo.y + geo.height + glow_size - glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -248,10 +242,8 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
quadMatrix->x0 = -(x1 * quadMatrix->xx);
quadMatrix->y0 = 1.0f - (y1 * quadMatrix->yy);
- y1 = std::max<int>(border_rect.y() + border_rect.height() - glow_offset,
- border_rect.y() + (border_rect.height() / 2));
- x2 = std::min<int>(border_rect.x() + glow_offset,
- border_rect.x() + (border_rect.width() / 2));
+ y1 = std::max<int>(geo.y + geo.height - glow_offset, geo.y + (geo.height / 2));
+ x2 = std::min<int>(geo.x + glow_offset, geo.x + (geo.width / 2));
box->setGeometry(x1, y1, x2 - x1, y2 - y1);
@@ -260,10 +252,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::BOTTOMRIGHT].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::BOTTOMRIGHT].matrix;
- x1 = border_rect.x() + border_rect.width() - glow_offset;
- y1 = border_rect.y() + border_rect.height() - glow_offset;
- x2 = border_rect.x() + border_rect.width() + glow_size - glow_offset;
- y2 = border_rect.y() + border_rect.height() + glow_size - glow_offset;
+ x1 = geo.x + geo.width - glow_offset;
+ y1 = geo.y + geo.height - glow_offset;
+ x2 = geo.x + geo.width + glow_size - glow_offset;
+ y2 = geo.y + geo.height + glow_size - glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -281,10 +273,8 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
quadMatrix->y0 = 1.0 - (y1 * quadMatrix->yy);
- x1 = std::max<int>(border_rect.x() + border_rect.width() - glow_offset,
- border_rect.x() + (border_rect.width() / 2));
- y1 = std::max<int>(border_rect.y() + border_rect.height() - glow_offset,
- border_rect.y() + (border_rect.height() / 2));
+ x1 = std::max<int>(geo.x + geo.width - glow_offset, geo.x + (geo.width / 2));
+ y1 = std::max<int>(geo.y + geo.height - glow_offset, geo.y + (geo.height / 2));
box->setGeometry(x1, y1, x2 - x1, y2 - y1);
@@ -293,10 +283,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::TOP].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::TOP].matrix;
- x1 = border_rect.x() + glow_offset;
- y1 = border_rect.y() - glow_size + glow_offset;
- x2 = border_rect.x() + border_rect.width() - glow_offset;
- y2 = border_rect.y() + glow_offset;
+ x1 = geo.x + glow_offset;
+ y1 = geo.y - glow_size + glow_offset;
+ x2 = geo.x + geo.width - glow_offset;
+ y2 = geo.y + glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -321,10 +311,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::BOTTOM].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::BOTTOM].matrix;
- x1 = border_rect.x() + glow_offset;
- y1 = border_rect.y() + border_rect.height() - glow_offset;
- x2 = border_rect.x() + border_rect.width() - glow_offset;
- y2 = border_rect.y() + border_rect.height() + glow_size - glow_offset;
+ x1 = geo.x + glow_offset;
+ y1 = geo.y + geo.height - glow_offset;
+ x2 = geo.x + geo.width - glow_offset;
+ y2 = geo.y + geo.height + glow_size - glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -349,10 +339,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::LEFT].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::LEFT].matrix;
- x1 = border_rect.x() - glow_size + glow_offset;
- y1 = border_rect.y() + glow_offset;
- x2 = border_rect.x() + glow_offset;
- y2 = border_rect.y() + border_rect.height() - glow_offset;
+ x1 = geo.x - glow_size + glow_offset;
+ y1 = geo.y + glow_offset;
+ x2 = geo.x + glow_offset;
+ y2 = geo.y + geo.height - glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
@@ -377,10 +367,10 @@ glow::Quads UnityWindow::computeGlowQuads(GLTexture::List const& texture, int gl
glow_quads[glow::QuadPos::RIGHT].matrix = matrix;
quadMatrix = &glow_quads[glow::QuadPos::RIGHT].matrix;
- x1 = border_rect.x() + border_rect.width() - glow_offset;
- y1 = border_rect.y() + glow_offset;
- x2 = border_rect.x() + border_rect.width() + glow_size - glow_offset;
- y2 = border_rect.y() + border_rect.height() - glow_offset;
+ x1 = geo.x + geo.width - glow_offset;
+ y1 = geo.y + glow_offset;
+ x2 = geo.x + geo.width + glow_size - glow_offset;
+ y2 = geo.y + geo.height - glow_offset;
/* 2x2 Matrix here, adjust both x and y scale factors
* and the x and y position
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b25d00fca..ef26966ae 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ launcher/ApplicationLauncherIcon.cpp
launcher/BFBLauncherIcon.cpp
launcher/DesktopLauncherIcon.cpp
launcher/DeviceNotificationDisplayImp.cpp
+launcher/ExpoLauncherIcon.cpp
launcher/LauncherController.cpp
launcher/SoftwareCenterLauncherIcon.cpp
launcher/SpacerLauncherIcon.cpp
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 43d9679d1..d4fe3b703 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -110,7 +110,9 @@ if (GTEST_SRC_DIR AND
test_service_lens.h
test_service_main.c
test_service_model.c
- test_service_model.h)
+ test_service_model.h
+ test_service_panel.c
+ test_service_panel.c)
target_link_libraries(test-gtest-service unity-shared ${LIBS})
add_dependencies (test-gtest-service unity-core-${UNITY_API_VERSION} gtest)
@@ -194,6 +196,7 @@ if (GTEST_SRC_DIR AND
test_utils.h
test_ratings_filter.cpp
test_results.cpp
+ test_dbus_indicators.cpp
)
target_link_libraries(test-gtest-dbus gtest unity-shared ${LIBS})
add_test(UnityGTestDBus test-gtest-dbus)
@@ -220,6 +223,7 @@ if (GTEST_SRC_DIR AND
test_launcher_icon.cpp
test_keyboard_util.cpp
test_panel_style.cpp
+ test_places_group.cpp
test_previews_application.cpp
test_previews_generic.cpp
test_previews_movie.cpp
@@ -244,6 +248,10 @@ if (GTEST_SRC_DIR AND
gmockvolume.c
${CMAKE_SOURCE_DIR}/dash/DashViewPrivate.cpp
${CMAKE_SOURCE_DIR}/dash/ResultRenderer.cpp
+ ${CMAKE_SOURCE_DIR}/dash/PlacesGroup.cpp
+ ${CMAKE_SOURCE_DIR}/dash/ResultRenderer.cpp
+ ${CMAKE_SOURCE_DIR}/dash/ResultRendererHorizontalTile.cpp
+ ${CMAKE_SOURCE_DIR}/dash/ResultRendererTile.cpp
${CMAKE_SOURCE_DIR}/dash/ResultView.cpp
${CMAKE_SOURCE_DIR}/dash/ResultViewGrid.cpp
${CMAKE_SOURCE_DIR}/dash/previews/ActionButton.cpp
diff --git a/tests/autopilot/unity/tests/test_hud.py b/tests/autopilot/unity/tests/test_hud.py
index 6cd171d43..2ccb3b580 100644
--- a/tests/autopilot/unity/tests/test_hud.py
+++ b/tests/autopilot/unity/tests/test_hud.py
@@ -417,10 +417,10 @@ class HudBehaviorTests(HudTestsBase):
(x,y,w,h) = self.hud.geometry
(screen_x,screen_y,screen_w,screen_h) = self.screen_geo.get_monitor_geometry(current_monitor)
-
+
self.mouse.move(x + w + (screen_w-((screen_x-x)+w))/2, y + h + (screen_h-((screen_y-y)+h))/2)
self.mouse.click()
-
+
self.assertThat(self.hud.visible, Eventually(Equals(False)))
def test_closes_then_focuses_window_on_mouse_down(self):
diff --git a/tests/test_dbus_indicators.cpp b/tests/test_dbus_indicators.cpp
new file mode 100644
index 000000000..f1406cf75
--- /dev/null
+++ b/tests/test_dbus_indicators.cpp
@@ -0,0 +1,99 @@
+#include <gtest/gtest.h>
+
+#include <UnityCore/GLibDBusProxy.h>
+#include <UnityCore/GLibSource.h>
+#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/DBusIndicators.h>
+
+#include "test_utils.h"
+
+using namespace unity;
+using namespace unity::indicator;
+
+namespace
+{
+
+class DBusIndicatorsTest : public DBusIndicators
+{
+public:
+ DBusIndicatorsTest() : DBusIndicators("com.canonical.Unity.Test")
+ {
+ }
+
+ bool HasIndicators() const
+ {
+ return !GetIndicators().empty();
+ }
+
+ using DBusIndicators::IsConnected;
+};
+
+class TestDBusIndicators : public ::testing::Test
+{
+public:
+ void SetUp()
+ {
+ session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
+ g_dbus_connection_set_exit_on_close(session, FALSE);
+
+ dbus_indicators.reset(new DBusIndicatorsTest ());
+
+ // wait until the dbus indicator has connected to the panel service
+ Utils::WaitUntil(sigc::mem_fun(*dbus_indicators, &DBusIndicatorsTest::IsConnected));
+ }
+
+ bool TriggerResync1Sent() const
+ {
+ GVariant *ret = CallPanelMethod("TriggerResync1Sent");
+ return g_variant_get_boolean(g_variant_get_child_value(ret, 0));
+ }
+
+ GVariant* CallPanelMethod(std::string const& name) const
+ {
+ return g_dbus_connection_call_sync(session,
+ "com.canonical.Unity.Test",
+ "/com/canonical/Unity/Panel/Service",
+ "com.canonical.Unity.Panel.Service",
+ name.c_str(),
+ NULL,
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ }
+
+ glib::Object<GDBusConnection> session;
+ std::shared_ptr<DBusIndicatorsTest> dbus_indicators;
+};
+
+TEST_F(TestDBusIndicators, TestConstruction)
+{
+ EXPECT_EQ(dbus_indicators->IsConnected(), true);
+}
+
+TEST_F(TestDBusIndicators, TestSync)
+{
+ // wait until the dbus indicator gets any indicator from the panel service
+ Utils::WaitUntil(sigc::mem_fun(*dbus_indicators, &DBusIndicatorsTest::HasIndicators));
+
+ EXPECT_EQ(dbus_indicators->GetIndicators().size(), 1);
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().size(), 2);
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().front()->id(), "test_entry_id");
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().back()->id(), "test_entry_id2");
+
+ // Tell the service to trigger a resync and to send the entries in the reverse order
+ CallPanelMethod("TriggerResync1");
+
+ Utils::WaitUntil(sigc::mem_fun(this, &TestDBusIndicators::TriggerResync1Sent));
+ // We know the resync has been sent, but it may have not been processed
+ // so do one interation of the main loop more
+ g_main_context_iteration(g_main_context_get_thread_default(), TRUE);
+
+ EXPECT_EQ(dbus_indicators->GetIndicators().size(), 1);
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().size(), 2);
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().front()->id(), "test_entry_id2");
+ EXPECT_EQ(dbus_indicators->GetIndicators().front()->GetEntries().back()->id(), "test_entry_id");
+}
+
+}
diff --git a/tests/test_indicator.cpp b/tests/test_indicator.cpp
index cb90d012d..5d3ac5aa6 100644
--- a/tests/test_indicator.cpp
+++ b/tests/test_indicator.cpp
@@ -35,6 +35,7 @@ TEST(TestIndicator, Construction)
EXPECT_EQ(indicator.name(), "indicator-test");
EXPECT_FALSE(indicator.IsAppmenu());
EXPECT_EQ(indicator.GetEntry("test-entry"), nullptr);
+ EXPECT_EQ(indicator.EntryIndex("test-entry"), -1);
EXPECT_TRUE(indicator.GetEntries().empty());
}
@@ -76,6 +77,7 @@ TEST(TestIndicator, Syncing)
indicator.Sync(sync_data);
EXPECT_EQ(indicator.GetEntries().size(), 3);
EXPECT_EQ(indicator.GetEntry("test-entry-2"), entry2);
+ EXPECT_EQ(indicator.EntryIndex("test-entry-2"), 1);
EXPECT_EQ(added.size(), 3);
EXPECT_EQ(added.front()->id(), "test-entry-1");
EXPECT_EQ(added.back()->id(), "test-entry-3");
@@ -91,6 +93,7 @@ TEST(TestIndicator, Syncing)
indicator.Sync(sync_data);
EXPECT_EQ(indicator.GetEntries().size(), 2);
EXPECT_EQ(indicator.GetEntry("test-entry-2"), nullptr);
+ EXPECT_EQ(indicator.EntryIndex("test-entry-2"), -1);
EXPECT_EQ(added.size(), 0);
EXPECT_EQ(removed.size(), 1);
EXPECT_EQ(removed.front(), entry2->id());
diff --git a/tests/test_launcher.cpp b/tests/test_launcher.cpp
index 907395ccc..542bd2652 100644
--- a/tests/test_launcher.cpp
+++ b/tests/test_launcher.cpp
@@ -362,6 +362,7 @@ TEST_F(TestLauncher, DragLauncherIconSavesIconOrderIfPositionHasChanged)
bool model_saved = false;
model_->saved.connect([&model_saved] { model_saved = true; });
+ EXPECT_CALL(*icon2, Stick(false));
ASSERT_NE(launcher_->GetDragIconPosition(), model_->IconIndex(icon2));
launcher_->EndIconDrag();
@@ -423,6 +424,25 @@ TEST_F(TestLauncher, DragLauncherIconSavesIconOrderIfPositionHasNotChanged)
EXPECT_EQ(launcher_->GetDraggedIcon(), nullptr);
}
+TEST_F(TestLauncher, DragLauncherIconSticksApplicationIcon)
+{
+ auto const& icons = AddMockIcons(1);
+
+ MockMockLauncherIcon::Ptr app(new MockMockLauncherIcon(AbstractLauncherIcon::IconType::APPLICATION));
+ model_->AddIcon(app);
+
+ // Start dragging app icon
+ launcher_->StartIconDrag(app);
+ launcher_->ShowDragWindow();
+
+ // Moving app icon to the beginning
+ auto const& center = icons[0]->GetCenter(launcher_->monitor());
+ launcher_->UpdateDragWindowPosition(center.x, center.y);
+
+ EXPECT_CALL(*app, Stick(false));
+ launcher_->EndIconDrag();
+}
+
TEST_F(TestLauncher, DragLauncherIconSticksDeviceIcon)
{
auto const& icons = AddMockIcons(1);
diff --git a/tests/test_places_group.cpp b/tests/test_places_group.cpp
new file mode 100644
index 000000000..f70617b1f
--- /dev/null
+++ b/tests/test_places_group.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#include "config.h"
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/PaintLayer.h>
+
+#include "PlacesGroup.h"
+using namespace unity;
+
+namespace {
+
+class MockDashStyle : public dash::StyleInterface
+{
+public:
+ MockDashStyle()
+ {
+ std::string full_path = PKGDATADIR "album_missing.png";
+ glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file_at_size(full_path.c_str(), 20, 20, nullptr));
+ base_texture_.Adopt(nux::CreateTexture2DFromPixbuf(pixbuf, true));
+ }
+
+ MOCK_METHOD2(FocusOverlay, nux::AbstractPaintLayer*(int width, int height));
+ MOCK_METHOD0(GetCategoryBackground, nux::BaseTexture*());
+ MOCK_METHOD0(GetCategoryBackgroundNoFilters, nux::BaseTexture*());
+
+ MOCK_METHOD0(GetGroupExpandIcon, nux::BaseTexture*());
+ MOCK_METHOD0(GetGroupUnexpandIcon, nux::BaseTexture*());
+
+ MOCK_CONST_METHOD0(GetCategoryHeaderLeftPadding, int());
+ MOCK_CONST_METHOD0(GetPlacesGroupTopSpace, int());
+
+ nux::ObjectPtr<nux::BaseTexture> base_texture_;
+};
+
+
+class TestPlacesGroup : public Test
+{
+public:
+ void SetUp()
+ {
+ SetupMockDashStyle();
+
+ places_group_ = new PlacesGroup(dash_style_);
+ }
+
+ void SetupMockDashStyle()
+ {
+ ON_CALL(dash_style_, FocusOverlay(_, _))
+ .WillByDefault(Return(new nux::ColorLayer(nux::color::White)));
+
+ ON_CALL(dash_style_, GetCategoryBackground())
+ .WillByDefault(Return(dash_style_.base_texture_.GetPointer()));
+
+ ON_CALL(dash_style_, GetCategoryBackgroundNoFilters())
+ .WillByDefault(Return(dash_style_.base_texture_.GetPointer()));
+
+ ON_CALL(dash_style_, GetGroupExpandIcon())
+ .WillByDefault(Return(dash_style_.base_texture_.GetPointer()));
+
+ ON_CALL(dash_style_, GetGroupUnexpandIcon())
+ .WillByDefault(Return(dash_style_.base_texture_.GetPointer()));
+ }
+
+ NiceMock<MockDashStyle> dash_style_;
+ nux::ObjectPtr<PlacesGroup> places_group_;
+};
+
+
+TEST_F(TestPlacesGroup, Constructor)
+{
+ EXPECT_CALL(dash_style_, GetGroupExpandIcon())
+ .Times(1);
+
+ EXPECT_CALL(dash_style_, GetGroupUnexpandIcon())
+ .Times(0);
+
+ PlacesGroup places_group(dash_style_);
+
+ EXPECT_FALSE(places_group.GetExpanded());
+}
+
+}
diff --git a/tests/test_service_main.c b/tests/test_service_main.c
index 921027e63..02688da98 100644
--- a/tests/test_service_main.c
+++ b/tests/test_service_main.c
@@ -3,6 +3,7 @@
#include "test_service_lens.h"
#include "test_service_model.h"
#include "test_service_hud.h"
+#include "test_service_panel.h"
#include "test_service_gdbus_wrapper.h"
static void on_bus_aquired(GDBusConnection* conn, const gchar* name, gpointer null);
@@ -37,6 +38,7 @@ static GMainLoop* loop_ = NULL;
static ServiceLens* lens_ = NULL;
static ServiceModel* model_ = NULL;
static ServiceHud* hud_ = NULL;
+static ServicePanel* panel_ = NULL;
static ServiceGDBusWrapper* gdbus_wrapper_ = NULL;
gint
main(gint argc, gchar** argv)
@@ -48,6 +50,7 @@ main(gint argc, gchar** argv)
lens_ = service_lens_new();
model_ = service_model_new();
hud_ = service_hud_new();
+ panel_ = service_panel_new();
gdbus_wrapper_ = service_gdbus_wrapper_new();
g_bus_own_name(G_BUS_TYPE_SESSION,
@@ -65,6 +68,7 @@ main(gint argc, gchar** argv)
//g_object_unref(lens_);
//g_object_unref(model_);
g_object_unref(hud_);
+ g_object_unref(panel_);
g_dbus_node_info_unref(introspection_data);
return 0;
diff --git a/tests/test_service_panel.c b/tests/test_service_panel.c
new file mode 100644
index 000000000..e5c29ffb1
--- /dev/null
+++ b/tests/test_service_panel.c
@@ -0,0 +1,253 @@
+#include "test_service_panel.h"
+#include <unity.h>
+#include <gio/gio.h>
+
+static const char * panel_interface =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<node name=\"/\">\n"
+" <interface name=\"com.canonical.Unity.Panel.Service\">\n"
+"\n"
+"<!-- Begin of real methods/signals -->\n"
+" <method name='Sync'>"
+" <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"
+" </method>"
+"\n"
+" <signal name='ReSync'>"
+" <arg type='s' name='indicator_id' />"
+" </signal>"
+"\n"
+"<!-- Begin of test only methods/signals -->\n"
+"\n"
+" <method name='TriggerResync1' />"
+"\n"
+" <method name='TriggerResync1Sent'>"
+" <arg type='b' name='sent' direction='out'/>"
+" </method>"
+"\n"
+" </interface>\n"
+"</node>\n"
+;
+static void bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data);
+static void bus_method (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data);
+
+G_DEFINE_TYPE(ServicePanel, service_panel, G_TYPE_OBJECT);
+static GDBusNodeInfo * node_info = NULL;
+static GDBusInterfaceInfo * iface_info = NULL;
+static GDBusInterfaceVTable bus_vtable = {
+ method_call: bus_method,
+ get_property: NULL,
+ set_property: NULL,
+};
+
+struct _ServicePanelPrivate
+{
+ GDBusConnection * bus;
+ GCancellable * bus_lookup;
+ guint bus_registration;
+ guint sig_emission_handle;
+};
+
+static void
+service_panel_dispose(GObject* object)
+{
+ ServicePanel* self = SERVICE_PANEL(object);
+ if (self->priv->bus_lookup != NULL) {
+ g_cancellable_cancel(self->priv->bus_lookup);
+ g_object_unref(self->priv->bus_lookup);
+ self->priv->bus_lookup = NULL;
+ }
+
+ if (self->priv->bus_registration != 0) {
+ g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration);
+ self->priv->bus_registration = 0;
+ }
+
+ if (self->priv->bus != NULL) {
+ g_object_unref(self->priv->bus);
+ self->priv->bus = NULL;
+ }
+
+ if (self->priv->sig_emission_handle) {
+ g_source_remove(self->priv->sig_emission_handle);
+ self->priv->sig_emission_handle = 0;
+ }
+
+}
+
+static void
+service_panel_class_init(ServicePanelClass* klass)
+{
+ G_OBJECT_CLASS(klass)->dispose = service_panel_dispose;
+ g_type_class_add_private (klass, sizeof (ServicePanelPrivate));
+
+ if (node_info == NULL)
+ {
+ GError * error = NULL;
+
+ node_info = g_dbus_node_info_new_for_xml(panel_interface, &error);
+ if (error != NULL)
+ {
+ g_error("Unable to parse Panel interface: %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ if (node_info != NULL && iface_info == NULL)
+ {
+ iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.Unity.Panel.Service");
+ if (iface_info == NULL)
+ {
+ g_error("Unable to find interface 'com.canonical.Unity.Panel.Service'");
+ }
+ }
+
+}
+
+static void
+service_panel_init(ServicePanel* self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_PANEL, ServicePanelPrivate);
+ self->priv->bus = NULL;
+ self->priv->bus_lookup = NULL;
+ self->priv->bus_registration = 0;
+
+ self->priv->bus_lookup = g_cancellable_new();
+ g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self);
+}
+
+ServicePanel*
+service_panel_new()
+{
+ return g_object_new(SERVICE_TYPE_PANEL, NULL);
+}
+
+static void
+bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data)
+{
+ GError * error = NULL;
+ ServicePanel * self = SERVICE_PANEL(user_data);
+ GDBusConnection * bus;
+
+ bus = g_bus_get_finish(res, &error);
+ if (error != NULL) {
+ g_critical("Unable to get bus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ self->priv->bus = bus;
+
+ /* Register object */
+ self->priv->bus_registration = g_dbus_connection_register_object(bus,
+ /* path */ "/com/canonical/Unity/Panel/Service",
+ /* interface */ iface_info,
+ /* vtable */ &bus_vtable,
+ /* userdata */ self,
+ /* destroy */ NULL,
+ /* error */ &error);
+
+ if (error != NULL) {
+ g_critical ("Unable to create bus connection object, %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ return;
+}
+
+static void
+add_entry_id(GVariantBuilder *b)
+{
+ g_variant_builder_add (b, "(ssssbbusbbi)",
+ "test_indicator_id",
+ "test_entry_id",
+ "test_entry_name_hint",
+ "test_entry_label",
+ TRUE, /* label sensitive */
+ TRUE, /* label visible */
+ 0, /* image type */
+ "", /* image_data */
+ TRUE, /* image sensitive */
+ TRUE, /* image visible */
+ 1 /* priority */);
+}
+
+static void
+add_entry_id_2(GVariantBuilder *b)
+{
+ g_variant_builder_add (b, "(ssssbbusbbi)",
+ "test_indicator_id",
+ "test_entry_id2",
+ "test_entry_name_hint2",
+ "test_entry_label2",
+ TRUE, /* label sensitive */
+ TRUE, /* label visible */
+ 0, /* image type */
+ "", /* image_data */
+ TRUE, /* image sensitive */
+ TRUE, /* image visible */
+ 1 /* priority */);
+}
+
+static int sync_return_mode = 0;
+static int trigger_resync1_sent = FALSE;
+
+static void
+bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+ if (g_strcmp0(method_name, "Sync") == 0)
+ {
+ GVariantBuilder b;
+
+ g_variant_builder_init (&b, G_VARIANT_TYPE ("(a(ssssbbusbbi))"));
+ g_variant_builder_open (&b, G_VARIANT_TYPE ("a(ssssbbusbbi)"));
+
+ if (sync_return_mode == 0)
+ {
+ add_entry_id(&b);
+ add_entry_id_2(&b);
+ }
+ else if (sync_return_mode == 1)
+ {
+ add_entry_id_2(&b);
+ add_entry_id(&b);
+ }
+
+ g_variant_builder_close (&b);
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_builder_end (&b));
+
+ if (sync_return_mode == 1)
+ {
+ trigger_resync1_sent = TRUE;
+ }
+ }
+ else if (g_strcmp0(method_name, "TriggerResync1") == 0)
+ {
+ sync_return_mode = 1;
+ trigger_resync1_sent = FALSE;
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ GVariantBuilder ret_builder;
+ g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE);
+ g_variant_builder_add_value(&ret_builder, g_variant_new_string(""));
+ g_dbus_connection_emit_signal (connection, NULL, "/com/canonical/Unity/Panel/Service", "com.canonical.Unity.Panel.Service", "ReSync", g_variant_builder_end(&ret_builder), NULL);
+ }
+ else if (g_strcmp0(method_name, "TriggerResync1Sent") == 0)
+ {
+ GVariantBuilder ret_builder;
+ g_variant_builder_init(&ret_builder, G_VARIANT_TYPE ("(b)"));
+ g_variant_builder_add_value (&ret_builder, g_variant_new_boolean(trigger_resync1_sent));
+ g_dbus_method_invocation_return_value(invocation, g_variant_builder_end (&ret_builder));
+ }
+
+ return;
+}
+
diff --git a/tests/test_service_panel.h b/tests/test_service_panel.h
new file mode 100644
index 000000000..aa160e231
--- /dev/null
+++ b/tests/test_service_panel.h
@@ -0,0 +1,46 @@
+#ifndef _SERVICE_PANEL_H_
+#define _SERVICE_PANEL_H_
+
+#include <glib-object.h>
+G_BEGIN_DECLS
+
+#define SERVICE_TYPE_PANEL (service_panel_get_type ())
+
+#define SERVICE_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+ SERVICE_TYPE_PANEL, ServicePanel))
+
+#define SERVICE_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
+ SERVICE_TYPE_PANEL, ServicePanelClass))
+
+#define SERVICE_IS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ SERVICE_TYPE_PANEL))
+
+#define SERVICE_IS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+ SERVICE_TYPE_PANEL))
+
+#define ServicePanel_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+ SERVICE_TYPE_PANEL, ServicePanelClass))
+
+typedef struct _ServicePanel ServicePanel;
+typedef struct _ServicePanelClass ServicePanelClass;
+typedef struct _ServicePanelPrivate ServicePanelPrivate;
+
+struct _ServicePanel
+{
+ GObject parent;
+
+ ServicePanelPrivate *priv;
+};
+
+struct _ServicePanelClass
+{
+ GObjectClass parent_class;
+};
+
+GType service_panel_get_type(void) G_GNUC_CONST;
+
+ServicePanel* service_panel_new(void);
+
+G_END_DECLS
+
+#endif /* _SERVICE_PANEL_H_ */
diff --git a/tests/test_utils.h b/tests/test_utils.h
index 975acae04..9cc978048 100644
--- a/tests/test_utils.h
+++ b/tests/test_utils.h
@@ -46,6 +46,20 @@ public:
EXPECT_TRUE(success);
}
+ static void WaitUntil(std::function<bool()> check_function, bool result = true, unsigned int max_wait = 10)
+ {
+ bool timeout_reached = false;
+ guint32 timeout_id = ScheduleTimeout(&timeout_reached, max_wait * 1000);
+
+ while (!check_function() && !timeout_reached)
+ g_main_context_iteration(g_main_context_get_thread_default(), TRUE);
+
+ if (check_function())
+ g_source_remove(timeout_id);
+
+ EXPECT_EQ(check_function(), result);
+ }
+
static guint32 ScheduleTimeout(bool* timeout_reached, unsigned int timeout_duration = 10)
{
return g_timeout_add(timeout_duration, TimeoutCallback, timeout_reached);
diff --git a/unity-shared/DashStyle.cpp b/unity-shared/DashStyle.cpp
index 4e9d6220e..168a9deea 100755
--- a/unity-shared/DashStyle.cpp
+++ b/unity-shared/DashStyle.cpp
@@ -1760,7 +1760,7 @@ bool Style::SquareButton(cairo_t* cr, nux::ButtonVisualState state,
return true;
}
-bool Style::ButtonFocusOverlay(cairo_t* cr)
+bool Style::ButtonFocusOverlay(cairo_t* cr, float alpha)
{
// sanity checks
if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
@@ -1773,7 +1773,7 @@ bool Style::ButtonFocusOverlay(cairo_t* cr)
double h = cairo_image_surface_get_height(cairo_get_target(cr));
nux::Color color(nux::color::White);
- color.alpha = 0.50f;
+ color.alpha = alpha;
cairo_set_line_width(cr, pimpl->button_label_border_size_[nux::VISUAL_STATE_NORMAL]);
RoundedRect(cr,
diff --git a/unity-shared/DashStyle.h b/unity-shared/DashStyle.h
index 0f816a71f..2273a7175 100755
--- a/unity-shared/DashStyle.h
+++ b/unity-shared/DashStyle.h
@@ -20,6 +20,8 @@
#ifndef DASH_STYLE_H
#define DASH_STYLE_H
+#include "DashStyleInterface.h"
+
#include <Nux/Nux.h>
#include <Nux/View.h>
#include <Nux/AbstractButton.h>
@@ -83,7 +85,7 @@ enum class Arrow {
};
-class Style
+class Style : public StyleInterface
{
public:
Style ();
@@ -104,7 +106,7 @@ public:
virtual nux::AbstractPaintLayer* FocusOverlay(int width, int height);
- virtual bool ButtonFocusOverlay(cairo_t* cr);
+ virtual bool ButtonFocusOverlay(cairo_t* cr, float alpha = 0.50f);
virtual bool MultiRangeSegment(cairo_t* cr,
nux::ButtonVisualState state,
diff --git a/unity-shared/DashStyleInterface.h b/unity-shared/DashStyleInterface.h
new file mode 100644
index 000000000..43d488bc4
--- /dev/null
+++ b/unity-shared/DashStyleInterface.h
@@ -0,0 +1,53 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2012 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#ifndef UNITYSHELL_DASH_STYLE_INTERFACE_H
+#define UNITYSHELL_DASH_STYLE_INTERFACE_H
+
+#include <memory>
+
+namespace nux {
+ class AbstractPaintLayer;
+ class BaseTexture;
+}
+
+namespace unity {
+namespace dash {
+
+class StyleInterface
+{
+public:
+ virtual ~StyleInterface() {};
+
+ virtual nux::AbstractPaintLayer* FocusOverlay(int width, int height) = 0;
+
+ virtual nux::BaseTexture* GetCategoryBackground() = 0;
+ virtual nux::BaseTexture* GetCategoryBackgroundNoFilters() = 0;
+
+ virtual nux::BaseTexture* GetGroupUnexpandIcon() = 0;
+ virtual nux::BaseTexture* GetGroupExpandIcon() = 0;
+
+ virtual int GetCategoryHeaderLeftPadding() const = 0;
+ virtual int GetPlacesGroupTopSpace() const = 0;
+};
+
+}
+}
+
+#endif
diff --git a/unity-shared/IconLoader.cpp b/unity-shared/IconLoader.cpp
index a5aca60ea..89f47c417 100644
--- a/unity-shared/IconLoader.cpp
+++ b/unity-shared/IconLoader.cpp
@@ -212,15 +212,27 @@ private:
if (icon.IsType(UNITY_PROTOCOL_TYPE_ANNOTATED_ICON))
{
- UnityProtocolAnnotatedIcon *anno;
- anno = UNITY_PROTOCOL_ANNOTATED_ICON(icon.RawPtr());
+ glib::Object<UnityProtocolAnnotatedIcon> anno(glib::object_cast<UnityProtocolAnnotatedIcon>(icon));
GIcon* base_icon = unity_protocol_annotated_icon_get_icon(anno);
glib::String gicon_string(g_icon_to_string(base_icon));
+ // ensure that annotated icons aren't cached by the IconLoader
no_cache = true;
- auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::BaseIconLoaded), glib::object_cast<UnityProtocolAnnotatedIcon>(icon));
- int base_icon_width = max_width > 0 ? max_width - RIBBON_PADDING * 2 : -1;
- int base_icon_height = base_icon_width < 0 ? max_height - RIBBON_PADDING *2 : max_height;
+
+ auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::BaseIconLoaded), anno);
+ int base_icon_width, base_icon_height;
+ if (unity_protocol_annotated_icon_get_use_small_icon(anno))
+ {
+ // FIXME: although this pretends to be generic, we're just making
+ // sure that icons requested to have 96px will be 64
+ base_icon_width = max_width > 0 ? max_width * 2 / 3 : max_width;
+ base_icon_height = max_height > 0 ? max_height * 2 / 3 : max_height;
+ }
+ else
+ {
+ base_icon_width = max_width > 0 ? max_width - RIBBON_PADDING * 2 : -1;
+ base_icon_height = base_icon_width < 0 ? max_height - RIBBON_PADDING *2 : max_height;
+ }
helper_handle = impl->LoadFromGIconString(gicon_string.Str(),
base_icon_width,
base_icon_height,
@@ -518,7 +530,7 @@ private:
}
void BaseIconLoaded(std::string const& base_icon_string,
- int max_width, int max_height,
+ int base_max_width, int base_max_height,
glib::Object<GdkPixbuf> const& base_pixbuf,
glib::Object<UnityProtocolAnnotatedIcon> const& anno_icon)
{
@@ -529,16 +541,32 @@ private:
"' size: " << gdk_pixbuf_get_width(base_pixbuf) << 'x' <<
gdk_pixbuf_get_height(base_pixbuf);
+ int result_width, result_height, dest_x, dest_y;
+ if (unity_protocol_annotated_icon_get_use_small_icon(anno_icon))
+ {
+ result_width = max_width > 0 ? max_width : MAX(max_height, gdk_pixbuf_get_width(base_pixbuf));
+ result_height = max_height > 0 ? max_height : MAX(max_width, gdk_pixbuf_get_height(base_pixbuf));
+
+ dest_x = (result_width - gdk_pixbuf_get_width(base_pixbuf)) / 2;
+ dest_y = (result_height - gdk_pixbuf_get_height(base_pixbuf)) / 2;
+ }
+ else
+ {
+ result_width = gdk_pixbuf_get_width(base_pixbuf) + RIBBON_PADDING * 2;
+ result_height = gdk_pixbuf_get_height(base_pixbuf);
+
+ dest_x = RIBBON_PADDING;
+ dest_y = 0;
+ }
// we need extra space for the ribbon
- result = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
- gdk_pixbuf_get_width(base_pixbuf) + RIBBON_PADDING * 2,
- gdk_pixbuf_get_height(base_pixbuf));
+ result = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+ result_width, result_height);
gdk_pixbuf_fill(result, 0x0);
gdk_pixbuf_copy_area(base_pixbuf, 0, 0,
gdk_pixbuf_get_width(base_pixbuf),
gdk_pixbuf_get_height(base_pixbuf),
result,
- RIBBON_PADDING, 0);
+ dest_x, dest_y);
// FIXME: can we composite the pixbuf in helper thread?
UnityProtocolCategoryType category = unity_protocol_annotated_icon_get_category(anno_icon);
auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::CategoryIconLoaded), anno_icon);
diff --git a/unity-shared/SearchBar.cpp b/unity-shared/SearchBar.cpp
index 8d63f20da..3e61f074d 100644
--- a/unity-shared/SearchBar.cpp
+++ b/unity-shared/SearchBar.cpp
@@ -363,6 +363,17 @@ void SearchBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
graphics_engine.PushClippingRectangle(base);
+ if (RedirectedAncestor())
+ {
+ unsigned int alpha = 0, src = 0, dest = 0;
+ graphics_engine.GetRenderStates().GetBlend(alpha, src, dest);
+ // This is necessary when doing redirected rendering.
+ // Clean the area below this view before drawing anything.
+ graphics_engine.GetRenderStates().SetBlend(false);
+ graphics_engine.QRP_Color(base.x, base.y, base.width, base.height, nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
+ graphics_engine.GetRenderStates().SetBlend(alpha, src, dest);
+ }
+
bg_layer_->SetGeometry(nux::Geometry(base.x, base.y, last_width_, last_height_));
nux::GetPainter().RenderSinglePaintLayer(graphics_engine,
bg_layer_->GetGeometry(),
@@ -380,38 +391,10 @@ void SearchBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
if (!highlight_layer_)
highlight_layer_.reset(style.FocusOverlay(geo.width, geo.height));
- if (RedirectedAncestor())
- {
- unsigned int alpha = 0, src = 0, dest = 0;
- graphics_engine.GetRenderStates().GetBlend(alpha, src, dest);
- // This is necessary when doing redirected rendering.
- // Clean the area below this view before drawing anything.
- graphics_engine.GetRenderStates().SetBlend(false);
- graphics_engine.QRP_Color(geo.x, geo.y, geo.width, geo.height, nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
- graphics_engine.GetRenderStates().SetBlend(alpha, src, dest);
- }
-
highlight_layer_->SetGeometry(geo);
highlight_layer_->Renderlayer(graphics_engine);
}
- else if (expander_view_ && expander_view_->IsVisible())
- {
- nux::Geometry geo(expander_view_->GetGeometry());
-
- geo.y -= (HIGHLIGHT_HEIGHT- geo.height) / 2;
- geo.height = HIGHLIGHT_HEIGHT;
- if (RedirectedAncestor())
- {
- unsigned int alpha = 0, src = 0, dest = 0;
- graphics_engine.GetRenderStates().GetBlend(alpha, src, dest);
- // This is necessary when doing redirected rendering.
- // Clean the area below this view before drawing anything.
- graphics_engine.GetRenderStates().SetBlend(false);
- graphics_engine.QRP_Color(geo.x, geo.y, geo.width, geo.height, nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
- graphics_engine.GetRenderStates().SetBlend(alpha, src, dest);
- }
- }
graphics_engine.PopClippingRectangle();
}