summaryrefslogtreecommitdiff
path: root/plugins/unityshell
diff options
Diffstat (limited to 'plugins/unityshell')
-rw-r--r--plugins/unityshell/src/unityshell.cpp226
-rw-r--r--plugins/unityshell/src/unityshell.h5
2 files changed, 135 insertions, 96 deletions
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 9686c0046..0df14c2c4 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -106,7 +106,7 @@ const unsigned int SCROLL_UP_BUTTON = 7;
const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
} // namespace local
-namespace scale
+namespace win
{
namespace decoration
{
@@ -116,7 +116,7 @@ const unsigned RADIUS = 8;
const unsigned GLOW = 5;
const nux::Color GLOW_COLOR(221, 72, 20);
} // decoration namespace
-} // scale namespace
+} // win namespace
} // anon namespace
@@ -699,12 +699,12 @@ void UnityScreen::OnPanelStyleChanged()
// Reload the windows themed textures
UnityWindow::CleanupSharedTextures();
- if (WindowManager::Default().IsScaleActive())
+ if (!fake_decorated_windows_.empty())
{
UnityWindow::SetupSharedTextures();
- for (auto const& swin : ScaleScreen::get(screen)->getWindows())
- UnityWindow::get(swin->window)->CleanupCachedTextures();
+ for (UnityWindow* uwin : fake_decorated_windows_)
+ uwin->CleanupCachedTextures();
}
}
@@ -777,7 +777,7 @@ void UnityScreen::paintDisplay()
}
}
- if (switcher_controller_->Visible())
+ if (switcher_controller_->Visible())
{
LayoutWindowList const& targets = switcher_controller_->ExternalRenderTargets();
@@ -785,8 +785,10 @@ void UnityScreen::paintDisplay()
{
if (CompWindow* window = screen->findWindow(target->xid))
{
- UnityWindow *unity_window = UnityWindow::get (window);
- unity_window->paintThumbnail(target->result, target->alpha);
+ UnityWindow *unity_window = UnityWindow::get(window);
+ double scale = target->result.width / static_cast<double>(target->geo.width);
+ unity_window->paintThumbnail(target->result, target->alpha, scale,
+ target->decoration_height, target->selected);
}
}
}
@@ -1147,7 +1149,10 @@ bool UnityWindow::handleEvent(XEvent *event)
}
if (old_state != close_icon_state_)
- DoAddDamage();
+ {
+ auto const& g = close_button_geo_;
+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
+ }
}
break;
@@ -1156,7 +1161,8 @@ bool UnityWindow::handleEvent(XEvent *event)
close_button_geo_.IsPointInside(event->xbutton.x_root, event->xbutton.y_root))
{
close_icon_state_ = panel::WindowState::PRESSED;
- DoAddDamage();
+ auto const& g = close_button_geo_;
+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
handled = true;
}
else if (event->xbutton.button == Button2 &&
@@ -1174,7 +1180,8 @@ bool UnityWindow::handleEvent(XEvent *event)
if (close_icon_state_ != panel::WindowState::NORMAL)
{
close_icon_state_ = panel::WindowState::NORMAL;
- DoAddDamage();
+ auto const& g = close_button_geo_;
+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
}
if (was_pressed)
@@ -1432,6 +1439,7 @@ void UnityScreen::compizDamageNux(CompRegion const& damage)
if (qm)
{
QuicklistView* view = qm->Current();
+
if (view)
{
nux::Geometry const& geo = view->GetAbsoluteGeometry();
@@ -1441,6 +1449,20 @@ void UnityScreen::compizDamageNux(CompRegion const& damage)
view->QueueDraw();
}
}
+
+ if (switcher_controller_ && switcher_controller_->Visible())
+ {
+ unity::switcher::SwitcherView* view = switcher_controller_->GetView();
+
+ if (G_LIKELY(view))
+ {
+ nux::Geometry const& geo = view->GetAbsoluteGeometry();
+ CompRegion switcher_region(geo.x, geo.y, geo.width, geo.height);
+
+ if (damage.intersects(switcher_region))
+ view->QueueDraw();
+ }
+ }
}
/* Grab changed nux regions and add damage rects for them */
@@ -2119,27 +2141,29 @@ void UnityScreen::OnLauncherEndKeyNav(GVariant* data)
void UnityScreen::OnSwitcherStart(GVariant* data)
{
if (switcher_controller_->Visible())
+ {
SaveInputThenFocus(switcher_controller_->GetSwitcherInputWindowId());
+ UnityWindow::SetupSharedTextures();
+ }
}
void UnityScreen::OnSwitcherEnd(GVariant* data)
{
RestoreWindow(data);
+ UnityWindow::CleanupSharedTextures();
+
+ for (UnityWindow* uwin : fake_decorated_windows_)
+ uwin->CleanupCachedTextures();
}
void UnityScreen::RestoreWindow(GVariant* data)
{
- bool preserve_focus = false;
-
- if (data)
- {
- preserve_focus = g_variant_get_boolean(data);
- }
+ bool preserve_focus = data ? g_variant_get_boolean(data) : false;
// Return input-focus to previously focused window (before key-nav-mode was
// entered)
if (preserve_focus)
- PluginAdapter::Default().RestoreInputFocus ();
+ PluginAdapter::Default().RestoreInputFocus();
}
bool UnityScreen::SaveInputThenFocus(const guint xid)
@@ -2760,8 +2784,8 @@ CompPoint UnityWindow::tryNotIntersectUI(CompPoint& pos)
nux::Point result(pos.x(), pos.y());
// seriously why does compiz not track monitors XRandR style???
- auto monitors = UScreen::GetDefault()->GetMonitors();
- for (auto monitor : monitors)
+ auto const& monitors = UScreen::GetDefault()->GetMonitors();
+ for (auto const& monitor : monitors)
{
if (monitor.IsInside(result))
{
@@ -2770,12 +2794,14 @@ CompPoint UnityWindow::tryNotIntersectUI(CompPoint& pos)
}
}
- auto launchers = us->launcher_controller_->launchers();
- for (auto launcher : launchers)
+ auto const& launchers = us->launcher_controller_->launchers();
+
+ for (auto const& launcher : launchers)
{
nux::Geometry geo = launcher->GetAbsoluteGeometry();
+ auto const& launcher_hide_mode = launcher->options()->hide_mode;
- if (launcher->Hidden() || launcher->options()->hide_mode == LAUNCHER_HIDE_NEVER || launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE)
+ if (launcher->Hidden() || launcher_hide_mode == LAUNCHER_HIDE_NEVER || launcher_hide_mode == LAUNCHER_HIDE_AUTOHIDE)
continue;
if (geo.IsInside(result))
@@ -3561,6 +3587,7 @@ void UnityWindow::AddProperties(GVariantBuilder* builder)
.add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))
.add("xid", xid)
.add("title", wm.GetWindowName(xid))
+ .add("fake_decorated", uScreen->fake_decorated_windows_.find(this) != uScreen->fake_decorated_windows_.end())
.add("scaled", scaled)
.add("scaled_close_x", close_button_geo_.x)
.add("scaled_close_y", close_button_geo_.y)
@@ -3619,7 +3646,7 @@ void UnityWindow::RenderDecoration(CairoContext const& context, double aspect)
cairo_pop_group_to_source(context.cr_);
// Round window decoration top border
- const double radius = scale::decoration::RADIUS * aspect;
+ const double radius = win::decoration::RADIUS * aspect;
cairo_new_sub_path(context.cr_);
cairo_line_to(context.cr_, 0, context.h_);
@@ -3654,6 +3681,7 @@ void UnityWindow::RenderText(CairoContext const& context, int x, int y, int widt
pango_layout_context_changed(layout);
decoration_title_ = WindowManager::Default().GetWindowName(window->id());
+
pango_layout_set_height(layout, height);
pango_layout_set_width(layout, -1); //avoid wrap lines
pango_layout_set_auto_dir(layout, false);
@@ -3664,13 +3692,6 @@ void UnityWindow::RenderText(CairoContext const& context, int x, int y, int widt
GtkStyleContext* style_context = style.GetStyleContext();
gtk_style_context_save(style_context);
-
- std::shared_ptr<GtkWidgetPath> widget_path(gtk_widget_path_new(), gtk_widget_path_free);
- gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_BAR);
- gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_ITEM);
- gtk_widget_path_iter_set_name(widget_path.get(), -1 , "UnityPanelWidget");
-
- gtk_style_context_set_path(style_context, widget_path.get());
gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
@@ -3681,7 +3702,6 @@ void UnityWindow::RenderText(CairoContext const& context, int x, int y, int widt
int text_height = lRect.height / PANGO_SCALE;
int text_space = width - x;
y += (height - text_height) / 2.0f;
-
if (text_width > text_space)
{
// Cut the text with fade
@@ -3712,11 +3732,12 @@ void UnityWindow::BuildDecorationTexture()
if (decoration_tex_)
return;
- auto const& border_extents = window->border();
+ auto& wm = WindowManager::Default();
+ auto const& deco_size = wm.GetWindowDecorationSize(window->id(), WindowManager::Edge::TOP);
- if (WindowManager::Default().IsWindowDecorated(window->id()) && border_extents.top > 0)
+ if (deco_size.height)
{
- CairoContext context(window->borderRect().width(), window->border().top);
+ CairoContext context(deco_size.width, deco_size.height);
RenderDecoration(context);
decoration_tex_ = context.pixmap_texture_;
}
@@ -3734,7 +3755,7 @@ void UnityWindow::LoadCloseIcon(panel::WindowState state, GLTexture::List& textu
for (std::string const& file : files)
{
CompString file_name = file;
- CompSize size(scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
+ CompSize size(win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
texture = GLTexture::readImageToTexture(file_name, plugin, size);
if (!texture.empty())
break;
@@ -3749,7 +3770,7 @@ void UnityWindow::LoadCloseIcon(panel::WindowState state, GLTexture::List& textu
suffix = "_pressed";
CompString file_name(PKGDATADIR"/close_dash" + suffix + ".png");
- CompSize size(scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
+ CompSize size(win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
texture = GLTexture::readImageToTexture(file_name, plugin, size);
}
}
@@ -3782,30 +3803,8 @@ void UnityWindow::CleanupCachedTextures()
decoration_title_.clear();
}
-void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
- GLMatrix const& transform,
- CompRegion const& region,
- unsigned int mask)
+void UnityWindow::paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAttrib const& attrib, GLMatrix const& transform, unsigned int mask, bool highlighted, double scale)
{
- ScaleWindow* scale_win = ScaleWindow::get(window);
- scale_win->scalePaintDecoration(attrib, transform, region, mask);
-
- if (!scale_win->hasSlot()) // animation not finished
- return;
-
- ScaleScreen* ss = ScaleScreen::get(screen);
- auto state = ss->getState();
-
- if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
- return;
-
- auto const& scaled_geo = GetScaledGeometry();
- auto const& pos = scale_win->getCurrentPosition();
-
- const bool highlighted = (ss->getSelectedWindow() == window->id());
- int x = scaled_geo.x;
- int y = scaled_geo.y;
-
mask |= PAINT_WINDOW_BLEND_MASK;
if (!highlighted)
@@ -3813,22 +3812,24 @@ void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
BuildDecorationTexture();
if (decoration_tex_)
- DrawTexture(decoration_tex_->texture_, attrib, transform, mask, x, y, pos.scale);
+ DrawTexture(decoration_tex_->texture_, attrib, transform, mask, geo.x, geo.y, scale);
close_button_geo_.Set(0, 0, 0, 0);
}
else
{
- auto const& decoration_extents = window->border();
- unsigned width = scaled_geo.width;
- unsigned height = decoration_extents.top;
+ Window xid = window->id();
+ auto& wm = WindowManager::Default();
+ auto const& deco_top = wm.GetWindowDecorationSize(xid, WindowManager::Edge::TOP);
+ unsigned width = geo.width;
+ unsigned height = deco_top.height;
bool redraw_decoration = true;
if (decoration_selected_tex_)
{
if (decoration_selected_tex_->w_ == width && decoration_selected_tex_->h_ == height)
{
- if (decoration_title_ == WindowManager::Default().GetWindowName(window->id()))
+ if (decoration_title_ == wm.GetWindowName(xid))
redraw_decoration = false;
}
}
@@ -3838,24 +3839,28 @@ void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
if (width != 0 && height != 0)
{
CairoContext context(width, height);
- RenderDecoration(context, pos.scale);
+ RenderDecoration(context, scale);
// Draw window title
- int text_x = scale::decoration::ITEMS_PADDING * 2 + scale::decoration::CLOSE_SIZE;
- RenderText(context, text_x, 0.0, width - scale::decoration::ITEMS_PADDING, height);
+ int text_x = win::decoration::ITEMS_PADDING * 2 + win::decoration::CLOSE_SIZE;
+ RenderText(context, text_x, 0.0, width - win::decoration::ITEMS_PADDING, height);
decoration_selected_tex_ = context.pixmap_texture_;
}
else
{
decoration_selected_tex_.reset();
+ redraw_decoration = false;
}
}
if (decoration_selected_tex_)
- DrawTexture(decoration_selected_tex_->texture_, attrib, transform, mask, x, y);
+ DrawTexture(decoration_selected_tex_->texture_, attrib, transform, mask, geo.x, geo.y);
- x += scale::decoration::ITEMS_PADDING;
- y += (height - scale::decoration::CLOSE_SIZE) / 2.0f;
+ if (redraw_decoration)
+ uScreen->damageRegion(CompRegion(geo.x, geo.y, width, height));
+
+ int x = geo.x + win::decoration::ITEMS_PADDING;
+ int y = geo.y + (height - win::decoration::CLOSE_SIZE) / 2.0f;
switch (close_icon_state_)
{
@@ -3873,8 +3878,34 @@ void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
break;
}
- close_button_geo_.Set(x, y, scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
+ close_button_geo_.Set(x, y, win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
}
+
+ uScreen->fake_decorated_windows_.insert(this);
+}
+
+void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
+ GLMatrix const& transform,
+ CompRegion const& region,
+ unsigned int mask)
+{
+ ScaleWindow* scale_win = ScaleWindow::get(window);
+ scale_win->scalePaintDecoration(attrib, transform, region, mask);
+
+ if (!scale_win->hasSlot()) // animation not finished
+ return;
+
+ ScaleScreen* ss = ScaleScreen::get(screen);
+ auto state = ss->getState();
+
+ if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
+ return;
+
+ auto const& scaled_geo = GetScaledGeometry();
+ auto const& pos = scale_win->getCurrentPosition();
+
+ bool highlighted = (ss->getSelectedWindow() == window->id());
+ paintFakeDecoration(scaled_geo, attrib, transform, mask, highlighted, pos.scale);
}
nux::Geometry UnityWindow::GetScaledGeometry()
@@ -3885,8 +3916,8 @@ nux::Geometry UnityWindow::GetScaledGeometry()
auto const& border_rect = window->borderRect();
auto const& deco_ext = window->border();
- const unsigned width = std::floor(border_rect.width() * pos.scale);
- const unsigned height = std::floor(border_rect.height() * pos.scale);
+ const unsigned width = std::round(border_rect.width() * pos.scale);
+ const unsigned height = std::round(border_rect.height() * pos.scale);
const int x = pos.x() + window->x() - std::round(deco_ext.left * pos.scale);
const int y = pos.y() + window->y() - std::round(deco_ext.top * pos.scale);
@@ -3902,7 +3933,7 @@ void UnityWindow::OnInitiateSpread()
WindowManager& wm = WindowManager::Default();
Window xid = window->id();
- if (wm.IsWindowDecorated(xid))
+ if (wm.HasWindowDecorations(xid))
wm.Decorate(xid);
}
@@ -3911,7 +3942,7 @@ void UnityWindow::OnTerminateSpread()
WindowManager& wm = WindowManager::Default();
Window xid = window->id();
- if (wm.IsWindowDecorated(xid) && wm.IsWindowMaximized(xid))
+ if (wm.IsWindowMaximized(xid))
wm.Undecorate(xid);
CleanupCachedTextures();
@@ -3919,49 +3950,53 @@ void UnityWindow::OnTerminateSpread()
void UnityWindow::paintInnerGlow(nux::Geometry glow_geo, GLMatrix const& matrix, GLWindowPaintAttrib const& attrib, unsigned mask)
{
- unsigned glow_size = scale::decoration::GLOW;
+ unsigned glow_size = win::decoration::GLOW;
if (!glow_size)
return;
- if (scale::decoration::RADIUS > 0)
+ if (win::decoration::RADIUS > 0)
{
// We paint the glow below the window edges to correctly
// render the rounded corners
- glow_size += scale::decoration::RADIUS;
- int inside_glow = scale::decoration::RADIUS / 4;
+ glow_size += win::decoration::RADIUS;
+ int inside_glow = win::decoration::RADIUS / 4;
glow_geo.Expand(-inside_glow, -inside_glow);
}
glow::Quads const& quads = computeGlowQuads(glow_geo, glow_texture_, glow_size);
- paintGlow(matrix, attrib, quads, glow_texture_, scale::decoration::GLOW_COLOR, mask);
+ paintGlow(matrix, attrib, quads, glow_texture_, win::decoration::GLOW_COLOR, mask);
}
-void UnityWindow::paintThumbnail(nux::Geometry const& bounding, float alpha)
+void UnityWindow::paintThumbnail(nux::Geometry const& geo, float alpha, float scale_ratio, unsigned deco_height, bool selected)
{
GLMatrix matrix;
matrix.toScreenSpace(UnityScreen::get(screen)->_last_output, -DEFAULT_Z_CAMERA);
- last_bound = bounding;
+ last_bound = geo;
GLWindowPaintAttrib attrib = gWindow->lastPaintAttrib();
- attrib.opacity = (GLushort) (alpha * G_MAXUSHORT);
+ attrib.opacity = (alpha * G_MAXUSHORT);
unsigned mask = 0;
+ nux::Geometry thumb_geo = geo;
- if (alpha >= 1.0f)
- {
- // The fully opaque window, is the selected one by contract.
- paintInnerGlow(bounding, matrix, attrib, mask);
- }
+ if (selected)
+ paintInnerGlow(thumb_geo, matrix, attrib, mask);
+
+ thumb_geo.y += std::round(deco_height * 0.5f * scale_ratio);
+ nux::Geometry const& g = thumb_geo;
- nux::Geometry const& g = bounding;
paintThumb(attrib, matrix, mask, g.x, g.y, g.width, g.height, g.width, g.height);
+
+ mask |= PAINT_WINDOW_BLEND_MASK;
+ attrib.opacity = OPAQUE;
+
+ paintFakeDecoration(geo, attrib, matrix, mask, selected, scale_ratio);
}
UnityWindow::~UnityWindow()
{
- UnityScreen* us = UnityScreen::get(screen);
- if (us->newFocusedWindow && (UnityWindow::get(us->newFocusedWindow) == this))
- us->newFocusedWindow = NULL;
+ if (uScreen->newFocusedWindow && UnityWindow::get(uScreen->newFocusedWindow) == this)
+ uScreen->newFocusedWindow = NULL;
if (!window->destroyed ())
{
@@ -3978,8 +4013,9 @@ UnityWindow::~UnityWindow()
ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));
if (window->state () & CompWindowStateFullscreenMask)
- UnityScreen::get (screen)->fullscreen_windows_.remove(window);
+ uScreen->fullscreen_windows_.remove(window);
+ uScreen->fake_decorated_windows_.erase(this);
PluginAdapter::Default().OnWindowClosed(window);
}
@@ -4086,7 +4122,7 @@ gfloat get_opengl_version_f32(const gchar* version_string)
gfloat version = 0.0f;
gint32 i;
- for (i = 0; isdigit(version_string[i]); i++)
+ for (i = 0; isdigit(version_string[i]); ++i)
version = version * 10.0f + (version_string[i] - 48);
if ((version_string[i] == '.' || version_string[i] == ',') &&
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index e44201d10..1264e961b 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -68,6 +68,7 @@
namespace unity
{
+class UnityWindow;
/* base screen class */
class UnityScreen :
@@ -329,6 +330,7 @@ private:
bool panel_texture_has_changed_;
bool paint_panel_;
nux::ObjectPtr<nux::IOpenGLBaseTexture> panel_texture_;
+ std::set<UnityWindow*> fake_decorated_windows_;
bool scale_just_activated_;
WindowMinimizeSpeedController minimize_speed_controller_;
@@ -388,7 +390,7 @@ public:
CompPoint tryNotIntersectUI(CompPoint& pos);
nux::Geometry GetScaledGeometry();
- void paintThumbnail(nux::Geometry const& bounding, float alpha);
+ void paintThumbnail(nux::Geometry const& bounding, float alpha, float scale_ratio, unsigned deco_height, bool selected);
void enterShowDesktop();
void leaveShowDesktop();
@@ -450,6 +452,7 @@ private:
void DrawTexture(GLTexture::List const& textures, GLWindowPaintAttrib const&,
GLMatrix const&, unsigned mask, int x, int y, double aspect = 1.0f);
+ void paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAttrib const& attrib, GLMatrix const& transform, unsigned int mask, bool highlighted, double scale);
void paintInnerGlow(nux::Geometry glow_geo, GLMatrix const&, GLWindowPaintAttrib const&, unsigned mask);
glow::Quads computeGlowQuads(nux::Geometry const& geo, GLTexture::List const& texture, int glow_size);
void paintGlow(GLMatrix const&, GLWindowPaintAttrib const&, glow::Quads const&,