summaryrefslogtreecommitdiff
diff options
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2014-03-12 23:45:48 +0000
committerCI bot <ps-jenkins@lists.canonical.com>2014-03-12 23:45:48 +0000
commiteef3eee05300887aef18082b702b8a18668333de (patch)
tree731ee54ac2a75b8563c07ac0a065057c26d4c68e
parenta769b6d9a38392f9432ab0b288552048cdf99c25 (diff)
parent47e7b65200bf9964a119803ce2f437de0b01b5d5 (diff)
Decorations and Menus: a bunch of various fixes... Fixes: 1283156, 1283238, 1283786, 1287464, 1287747, 1288166, 1291137, 1291622, 1291650
(bzr r3715)
-rw-r--r--decorations/DecoratedWindow.cpp29
-rw-r--r--decorations/DecoratedWindow.h1
-rw-r--r--decorations/DecorationsManager.cpp1
-rw-r--r--decorations/DecorationsPriv.h1
-rw-r--r--decorations/DecorationsTitle.cpp6
-rw-r--r--launcher/SwitcherController.cpp54
-rw-r--r--launcher/SwitcherController.h6
-rw-r--r--launcher/SwitcherControllerImpl.h5
-rw-r--r--launcher/SwitcherView.cpp8
-rw-r--r--launcher/SwitcherView.h2
-rw-r--r--panel/PanelMenuView.cpp43
-rw-r--r--plugins/unityshell/src/unityshell.cpp79
-rw-r--r--plugins/unityshell/src/unityshell.h4
-rw-r--r--services/panel-service.c54
-rw-r--r--tests/MockSwitcherController.h4
-rw-r--r--tests/test_switcher_controller.cpp16
-rw-r--r--tests/test_switcher_controller_slow.cpp4
-rw-r--r--unity-shared/CompizUtils.cpp8
-rw-r--r--unity-shared/PluginAdapter.cpp19
19 files changed, 218 insertions, 126 deletions
diff --git a/decorations/DecoratedWindow.cpp b/decorations/DecoratedWindow.cpp
index d32583eaa..5909b06e0 100644
--- a/decorations/DecoratedWindow.cpp
+++ b/decorations/DecoratedWindow.cpp
@@ -415,6 +415,9 @@ unsigned Window::Impl::ShadowRadius() const
void Window::Impl::RenderDecorationTexture(Side s, nux::Geometry const& geo)
{
+ if (geo.width <= 0 || geo.height <= 0)
+ return;
+
auto& deco_tex = bg_textures_[unsigned(s)];
if (deco_tex.quad.box.width() != geo.width || deco_tex.quad.box.height() != geo.height)
@@ -461,7 +464,7 @@ void Window::Impl::UpdateDecorationTextures()
void Window::Impl::ComputeShadowQuads()
{
- if (!ShadowDecorated())
+ if (last_shadow_rect_.isEmpty() && !ShadowDecorated())
return;
const auto* texture = ShadowTexture();
@@ -555,19 +558,24 @@ void Window::Impl::ComputeShadowQuads()
}
}
+void Window::Impl::Paint(GLMatrix const& transformation,
+ GLWindowPaintAttrib const& attrib,
+ CompRegion const& region, unsigned mask)
+{
+ if (dirty_geo_)
+ parent_->UpdateDecorationPosition();
+}
+
void Window::Impl::Draw(GLMatrix const& transformation,
GLWindowPaintAttrib const& attrib,
CompRegion const& region, unsigned mask)
{
- if (!ShadowDecorated())
+ if (last_shadow_rect_.isEmpty())
return;
auto const& clip_region = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region;
mask |= PAINT_WINDOW_BLEND_MASK;
- if (dirty_geo_)
- parent_->UpdateDecorationPosition();
-
glwin_->vertexBuffer()->begin();
for (unsigned i = 0; i < shadow_quads_.size(); ++i)
@@ -581,6 +589,9 @@ void Window::Impl::Draw(GLMatrix const& transformation,
for (auto const& dtex : bg_textures_)
{
+ if (!dtex)
+ continue;
+
glwin_->vertexBuffer()->begin();
glwin_->glAddGeometry({dtex.quad.matrix}, dtex.quad.box, clip_region);
@@ -613,7 +624,7 @@ void Window::Impl::SetupAppMenu()
sliding_layout->SetInputItem(nullptr);
sliding_layout->mouse_owner = false;
- if (!menu_manager->HasAppMenu())
+ if (!menu_manager->HasAppMenu() || !Style::Get()->integrated_menus())
return;
auto visibility_cb = sigc::hide(sigc::mem_fun(this, &Impl::UpdateAppMenuVisibility));
@@ -738,6 +749,12 @@ void Window::Draw(GLMatrix const& matrix, GLWindowPaintAttrib const& attrib,
impl_->Draw(matrix, attrib, region, mask);
}
+void Window::Paint(GLMatrix const& matrix, GLWindowPaintAttrib const& attrib,
+ CompRegion const& region, unsigned mask)
+{
+ impl_->Paint(matrix, attrib, region, mask);
+}
+
void Window::Undecorate()
{
impl_->Undecorate();
diff --git a/decorations/DecoratedWindow.h b/decorations/DecoratedWindow.h
index a0739f4df..be49be600 100644
--- a/decorations/DecoratedWindow.h
+++ b/decorations/DecoratedWindow.h
@@ -51,6 +51,7 @@ public:
void UpdateDecorationPositionDelayed();
void UpdateFrameRegion(CompRegion&);
void UpdateOutputExtents(compiz::window::extents::Extents&);
+ void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
protected:
diff --git a/decorations/DecorationsManager.cpp b/decorations/DecorationsManager.cpp
index d94d727f0..48f5cf006 100644
--- a/decorations/DecorationsManager.cpp
+++ b/decorations/DecorationsManager.cpp
@@ -209,6 +209,7 @@ Window::Ptr Manager::Impl::GetWindowByFrame(::Window xid) const
bool Manager::Impl::HandleEventBefore(XEvent* event)
{
active_window_ = screen->activeWindow();
+
switch (event->type)
{
case ClientMessage:
diff --git a/decorations/DecorationsPriv.h b/decorations/DecorationsPriv.h
index 69fe448ce..01f51f893 100644
--- a/decorations/DecorationsPriv.h
+++ b/decorations/DecorationsPriv.h
@@ -108,6 +108,7 @@ private:
void ComputeShadowQuads();
void UpdateDecorationTextures();
void RenderDecorationTexture(Side, nux::Geometry const&);
+ void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
friend class Window;
diff --git a/decorations/DecorationsTitle.cpp b/decorations/DecorationsTitle.cpp
index bc9eeff2a..454715af5 100644
--- a/decorations/DecorationsTitle.cpp
+++ b/decorations/DecorationsTitle.cpp
@@ -61,6 +61,12 @@ void Title::OnFontChanged(std::string const&)
void Title::RenderTexture()
{
+ if (!texture_size_.width || !texture_size_.height)
+ {
+ SetTexture(nullptr);
+ return;
+ }
+
auto state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP;
cu::CairoContext text_ctx(texture_size_.width, texture_size_.height, scale());
Style::Get()->DrawTitle(text(), state, text_ctx, texture_size_.width / scale(), texture_size_.height / scale());
diff --git a/launcher/SwitcherController.cpp b/launcher/SwitcherController.cpp
index e1470d4ec..8420f1dfa 100644
--- a/launcher/SwitcherController.cpp
+++ b/launcher/SwitcherController.cpp
@@ -69,7 +69,9 @@ namespace switcher
{
Controller::Controller(WindowCreator const& create_window)
- : detail_mode([this] { return detail_mode_; })
+ : detail([this] { return impl_->model_ && impl_->model_->detail_selection(); },
+ [this] (bool d) { if (impl_->model_) { impl_->model_->detail_selection = d; } return false; })
+ , detail_mode([this] { return detail_mode_; })
, timeout_length(0)
, detail_on_timeout(true)
, detail_timeout_length(500)
@@ -133,8 +135,7 @@ void Controller::Impl::StartDetailMode()
{
if (obj_->visible_)
{
- if (IsDetailViewShown() &&
- HasNextDetailRow())
+ if (obj_->detail() && HasNextDetailRow())
{
NextDetailRow();
}
@@ -149,8 +150,7 @@ void Controller::Impl::StopDetailMode()
{
if (obj_->visible_)
{
- if (IsDetailViewShown() &&
- HasPrevDetailRow())
+ if (obj_->detail() && HasPrevDetailRow())
{
PrevDetailRow();
}
@@ -176,11 +176,6 @@ SwitcherView::Ptr Controller::GetView() const
return impl_->GetView();
}
-bool Controller::IsDetailViewShown()
-{
- return impl_->IsDetailViewShown();
-}
-
void Controller::SetDetail(bool value, unsigned int min_windows)
{
impl_->SetDetail(value, min_windows);
@@ -201,16 +196,11 @@ void Controller::PrevDetail()
impl_->PrevDetail();
}
-LayoutWindow::Vector Controller::ExternalRenderTargets()
+LayoutWindow::Vector const& Controller::ExternalRenderTargets() const
{
return impl_->ExternalRenderTargets();
}
-guint Controller::GetSwitcherInputWindowId() const
-{
- return impl_->GetSwitcherInputWindowId();
-}
-
bool Controller::IsShowDesktopDisabled() const
{
return show_desktop_disabled_;
@@ -251,11 +241,6 @@ sigc::connection Controller::ConnectToViewBuilt(const sigc::slot<void> &f)
return impl_->view_built.connect(f);
}
-void Controller::SetDetailOnTimeout(bool timeout)
-{
- detail_on_timeout = timeout;
-}
-
double Controller::Opacity() const
{
if (!impl_->view_window_)
@@ -512,12 +497,16 @@ void Controller::Impl::DetailHide()
{
// FIXME We need to refactor SwitcherModel so we can add/remove icons without causing
// a crash. If you remove the last application in the list it crashes.
+ obj_->detail.changed.emit(false);
model_->detail_selection = false;
Hide(false);
}
void Controller::Impl::HideWindow()
{
+ if (model_->detail_selection())
+ obj_->detail.changed.emit(false);
+
main_layout_->RemoveChildObject(view_.GetPointer());
view_window_->SetOpacity(0.0f);
@@ -591,20 +580,17 @@ SwitcherView::Ptr Controller::Impl::GetView() const
return view_;
}
-bool Controller::Impl::IsDetailViewShown()
-{
- return model_ && model_->detail_selection();
-}
-
void Controller::Impl::SetDetail(bool value, unsigned int min_windows)
{
if (value && model_->Selection()->AllowDetailViewInSwitcher() && model_->DetailXids().size() >= min_windows)
{
model_->detail_selection = true;
obj_->detail_mode_ = DetailMode::TAB_NEXT_WINDOW;
+ obj_->detail.changed.emit(true);
}
else
{
+ obj_->detail.changed.emit(false);
model_->detail_selection = false;
}
}
@@ -673,22 +659,17 @@ bool Controller::Impl::HasPrevDetailRow() const
return model_->HasPrevDetailRow();
}
-LayoutWindow::Vector Controller::Impl::ExternalRenderTargets()
+LayoutWindow::Vector const& Controller::Impl::ExternalRenderTargets() const
{
if (!view_)
{
- LayoutWindow::Vector result;
- return result;
+ static LayoutWindow::Vector empty_list;
+ return empty_list;
}
- return view_->ExternalTargets();
-}
-guint Controller::Impl::GetSwitcherInputWindowId() const
-{
- return view_window_->GetInputWindowId();
+ return view_->ExternalTargets();
}
-
Selection Controller::Impl::GetCurrentSelection() const
{
AbstractLauncherIcon::Ptr application;
@@ -712,7 +693,6 @@ Selection Controller::Impl::GetCurrentSelection() const
return {application, window};
}
-
void Controller::Impl::SelectFirstItem()
{
if (!model_)
@@ -743,7 +723,7 @@ void Controller::Impl::SelectFirstItem()
for (auto& window : first->Windows())
{
Window xid = window->window_id();
-
+
if (model_->only_detail_on_viewport && !wm.IsWindowOnCurrentDesktop(xid))
continue;
diff --git a/launcher/SwitcherController.h b/launcher/SwitcherController.h
index 6ad903914..94396072e 100644
--- a/launcher/SwitcherController.h
+++ b/launcher/SwitcherController.h
@@ -107,9 +107,7 @@ public:
nux::ObjectPtr<SwitcherView> GetView() const;
- ui::LayoutWindow::Vector ExternalRenderTargets();
-
- guint GetSwitcherInputWindowId() const;
+ ui::LayoutWindow::Vector const& ExternalRenderTargets() const;
bool IsShowDesktopDisabled() const;
void SetShowDesktopDisabled(bool disabled);
@@ -123,12 +121,12 @@ public:
Selection GetCurrentSelection() const;
sigc::connection ConnectToViewBuilt(sigc::slot<void> const&);
- void SetDetailOnTimeout(bool timeout);
// Introspectable methods
std::string GetName() const;
void AddProperties(debug::IntrospectionData&);
+ nux::RWProperty<bool> detail;
nux::ROProperty<DetailMode> detail_mode;
nux::Property<int> timeout_length;
nux::Property<bool> detail_on_timeout;
diff --git a/launcher/SwitcherControllerImpl.h b/launcher/SwitcherControllerImpl.h
index 2bba90e99..783257a2a 100644
--- a/launcher/SwitcherControllerImpl.h
+++ b/launcher/SwitcherControllerImpl.h
@@ -71,10 +71,7 @@ struct Controller::Impl : public sigc::trackable
void SelectFirstItem();
virtual SwitcherView::Ptr GetView() const;
-
- ui::LayoutWindow::Vector ExternalRenderTargets();
-
- guint GetSwitcherInputWindowId() const;
+ ui::LayoutWindow::Vector const& ExternalRenderTargets() const;
int StartIndex() const;
Selection GetCurrentSelection() const;
diff --git a/launcher/SwitcherView.cpp b/launcher/SwitcherView.cpp
index 7245bbf82..b0049f4fc 100644
--- a/launcher/SwitcherView.cpp
+++ b/launcher/SwitcherView.cpp
@@ -141,7 +141,7 @@ debug::Introspectable::IntrospectableList SwitcherView::GetIntrospectableChildre
return introspection_results;
}
-LayoutWindow::Vector SwitcherView::ExternalTargets ()
+LayoutWindow::Vector const& SwitcherView::ExternalTargets() const
{
return render_targets_;
}
@@ -588,8 +588,8 @@ void SwitcherView::ResizeRenderTargets(nux::Geometry const& layout_geo, float pr
for (LayoutWindow::Ptr const& win : render_targets_)
{
- auto final_geo = win->result;
- win->result = final_geo * progress;
+ win->scale *= progress;
+ win->result = win->result * progress;
win->result.x += layout_abs_center.x;
win->result.y += layout_abs_center.y;
}
@@ -934,7 +934,7 @@ void SwitcherView::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw,
if (render_boxes)
{
float val = 0.1f;
- for (LayoutWindow::Ptr const& layout : ExternalTargets())
+ for (LayoutWindow::Ptr const& layout : render_targets_)
{
gPainter.Paint2DQuadColor(GfxContext, layout->result, nux::Color(val, val, val ,val));
val += 0.1f;
diff --git a/launcher/SwitcherView.h b/launcher/SwitcherView.h
index 2d09e01c3..3e72ccffe 100644
--- a/launcher/SwitcherView.h
+++ b/launcher/SwitcherView.h
@@ -51,7 +51,7 @@ public:
SwitcherView();
- ui::LayoutWindow::Vector ExternalTargets();
+ ui::LayoutWindow::Vector const& ExternalTargets() const;
void SetModel(SwitcherModel::Ptr model);
SwitcherModel::Ptr GetModel();
diff --git a/panel/PanelMenuView.cpp b/panel/PanelMenuView.cpp
index 94ccf68fd..130e60434 100644
--- a/panel/PanelMenuView.cpp
+++ b/panel/PanelMenuView.cpp
@@ -131,6 +131,7 @@ void PanelMenuView::SetupPanelMenuViewSignals()
auto const& deco_style = decoration::Style::Get();
lim_changed_connection_ = deco_style->integrated_menus.changed.connect([this] (bool lim) {
integrated_menus_ = lim;
+ new_application_ = nullptr;
if (!integrated_menus_)
{
auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
@@ -928,11 +929,16 @@ void PanelMenuView::NotifyAllMenusClosed()
{
last_active_view_ = nullptr;
- if (integrated_menus_ && is_maximized_)
+ if (!integrated_menus_ || is_maximized_)
{
auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
- FullRedraw();
+ bool inside = GetAbsoluteGeometry().IsInside(mouse);
+
+ if (is_inside_ != inside)
+ {
+ is_inside_ = inside;
+ QueueDraw();
+ }
}
}
@@ -981,7 +987,7 @@ void PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
void PanelMenuView::OnApplicationClosed(BamfApplication* app)
{
- if (BAMF_IS_APPLICATION(app))
+ if (BAMF_IS_APPLICATION(app) && !integrated_menus_)
{
if (std::find(new_apps_.begin(), new_apps_.end(), app) != new_apps_.end())
{
@@ -1029,10 +1035,12 @@ void PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,
{
if (BAMF_IS_APPLICATION(new_app))
{
- app_name_changed_signal_.Disconnect();
app_name_changed_signal_.Connect(BAMF_VIEW(new_app), "name-changed",
sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
+ if (integrated_menus_)
+ return;
+
if (std::find(new_apps_.begin(), new_apps_.end(), new_app) != new_apps_.end())
{
if (new_application_ != new_app)
@@ -1152,6 +1160,11 @@ void PanelMenuView::OnWindowMinimized(Window xid)
if (Refresh())
QueueDraw();
}
+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
+ {
+ if (Refresh())
+ QueueDraw();
+ }
}
void PanelMenuView::OnWindowUnminimized(Window xid)
@@ -1164,6 +1177,11 @@ void PanelMenuView::OnWindowUnminimized(Window xid)
if (Refresh())
QueueDraw();
}
+ else if (integrated_menus_ && IsWindowUnderOurControl(xid))
+ {
+ if (Refresh())
+ QueueDraw();
+ }
}
void PanelMenuView::OnWindowUnmapped(Window xid)
@@ -1177,6 +1195,11 @@ void PanelMenuView::OnWindowUnmapped(Window xid)
if (Refresh())
QueueDraw();
}
+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
+ {
+ if (Refresh())
+ QueueDraw();
+ }
}
void PanelMenuView::OnWindowMapped(Window xid)
@@ -1207,6 +1230,11 @@ void PanelMenuView::OnWindowMaximized(Window xid)
if (Refresh())
FullRedraw();
}
+ else if (integrated_menus_ && IsWindowUnderOurControl(xid))
+ {
+ if (Refresh())
+ QueueDraw();
+ }
}
void PanelMenuView::OnWindowRestored(Window xid)
@@ -1221,6 +1249,11 @@ void PanelMenuView::OnWindowRestored(Window xid)
if (Refresh())
FullRedraw();
}
+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
+ {
+ if (Refresh())
+ QueueDraw();
+ }
}
bool PanelMenuView::UpdateActiveWindowPosition()
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 93bd78fdc..087ec5441 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -393,9 +393,6 @@ UnityScreen::UnityScreen(CompScreen* screen)
ubus_manager_.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWITCHER,
sigc::mem_fun(this, &UnityScreen::OnLauncherEndKeyNav));
- ubus_manager_.RegisterInterest(UBUS_SWITCHER_END,
- sigc::mem_fun(this, &UnityScreen::OnSwitcherEnd));
-
auto init_plugins_cb = sigc::mem_fun(this, &UnityScreen::initPluginActions);
sources_.Add(std::make_shared<glib::Idle>(init_plugins_cb, glib::Source::Priority::DEFAULT));
@@ -533,7 +530,11 @@ void UnityScreen::OnInitiateSpread()
});
for (auto const& swin : sScreen->getWindows())
- UnityWindow::get(swin->window)->OnInitiateSpread();
+ {
+ auto* uwin = UnityWindow::get(swin->window);
+ fake_decorated_windows_.insert(uwin);
+ uwin->OnInitiateSpread();
+ }
}
void UnityScreen::OnTerminateSpread()
@@ -542,6 +543,8 @@ void UnityScreen::OnTerminateSpread()
for (auto const& swin : sScreen->getWindows())
UnityWindow::get(swin->window)->OnTerminateSpread();
+
+ fake_decorated_windows_.clear();
}
void UnityScreen::DamagePanelShadow()
@@ -876,9 +879,9 @@ void UnityScreen::paintDisplay()
}
}
- if (switcher_controller_->Opacity() > 0.0f)
+ if (switcher_controller_->detail())
{
- LayoutWindow::Vector const& targets = switcher_controller_->ExternalRenderTargets();
+ auto const& targets = switcher_controller_->ExternalRenderTargets();
for (LayoutWindow::Ptr const& target : targets)
{
@@ -1709,7 +1712,7 @@ void UnityScreen::handleEvent(XEvent* event)
if (CompWindow *w = screen->findWindow(sScreen->getSelectedWindow()))
skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
}
- else if (switcher_controller_->IsDetailViewShown())
+ else if (switcher_controller_->detail())
{
Window win = switcher_controller_->GetCurrentSelection().window_;
CompWindow* w = screen->findWindow(win);
@@ -1740,7 +1743,7 @@ void UnityScreen::handleEvent(XEvent* event)
skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
}
}
- else if (switcher_controller_->IsDetailViewShown())
+ else if (switcher_controller_->detail())
{
Window win = switcher_controller_->GetCurrentSelection().window_;
CompWindow* w = screen->findWindow(win);
@@ -1805,7 +1808,7 @@ void UnityScreen::handleEvent(XEvent* event)
break;
case ButtonRelease:
- if (switcher_controller_->IsDetailViewShown())
+ if (switcher_controller_->detail())
{
Window win = switcher_controller_->GetCurrentSelection().window_;
CompWindow* w = screen->findWindow(win);
@@ -2312,13 +2315,13 @@ bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State
switcher_controller_->Select((switcher_controller_->StartIndex())); // always select the current application
switcher_controller_->InitiateDetail();
}
- else if (switcher_controller_->IsDetailViewShown())
+ else if (switcher_controller_->detail())
{
switcher_controller_->NextDetail();
}
else
{
- switcher_controller_->SetDetail(true);
+ switcher_controller_->detail = true;
}
action->setState(action->state() | CompAction::StateTermKey);
@@ -2413,13 +2416,27 @@ void UnityScreen::OnLauncherEndKeyNav(GVariant* data)
PluginAdapter::Default().RestoreInputFocus();
}
-void UnityScreen::OnSwitcherEnd(GVariant* data)
+void UnityScreen::OnSwitcherDetailChanged(bool detail)
{
- for (UnityWindow* uwin : fake_decorated_windows_)
+ if (detail)
{
- uwin->close_icon_state_ = decoration::WidgetState::NORMAL;
- uwin->middle_clicked_ = false;
- uwin->CleanupCachedTextures();
+ for (LayoutWindow::Ptr const& target : switcher_controller_->ExternalRenderTargets())
+ {
+ if (CompWindow* window = screen->findWindow(target->xid))
+ {
+ auto* uwin = UnityWindow::get(window);
+ uwin->close_icon_state_ = decoration::WidgetState::NORMAL;
+ uwin->middle_clicked_ = false;
+ fake_decorated_windows_.insert(uwin);
+ }
+ }
+ }
+ else
+ {
+ for (UnityWindow* uwin : fake_decorated_windows_)
+ uwin->CleanupCachedTextures();
+
+ fake_decorated_windows_.clear();
}
}
@@ -2881,7 +2898,9 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
wAttrib.brightness *= 0.75f;
}
- return gWindow->glPaint(wAttrib, matrix, region, mask);
+ bool ret = gWindow->glPaint(wAttrib, matrix, region, mask);
+ deco_win_->Paint(matrix, wAttrib, region, mask);
+ return ret;
}
/* handle window painting in an opengl context
@@ -3494,7 +3513,7 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
launcher_options->super_tap_duration = optionGetDashTapDuration();
break;
case UnityshellOptions::AltTabTimeout:
- switcher_controller_->SetDetailOnTimeout(optionGetAltTabTimeout());
+ switcher_controller_->detail_on_timeout = optionGetAltTabTimeout();
case UnityshellOptions::AltTabBiasViewport:
PluginAdapter::Default().bias_active_to_viewport = optionGetAltTabBiasViewport();
break;
@@ -3715,6 +3734,7 @@ void UnityScreen::initLauncher()
AddChild(launcher_controller_.get());
switcher_controller_ = std::make_shared<switcher::Controller>();
+ switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));
AddChild(switcher_controller_.get());
LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
@@ -3890,6 +3910,7 @@ UnityWindow::UnityWindow(CompWindow* window)
, gWindow(GLWindow::get(window))
, close_icon_state_(decoration::WidgetState::NORMAL)
, deco_win_(uScreen->deco_manager_->HandleWindow(window))
+ , need_fake_deco_redraw_(false)
, is_nux_window_(isNuxWindow(window))
{
WindowInterface::setHandler(window);
@@ -4063,14 +4084,11 @@ void UnityWindow::paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAtt
{
mask |= PAINT_WINDOW_BLEND_MASK;
+ if (!decoration_tex_ && compiz_utils::IsWindowFullyDecorable(window))
+ BuildDecorationTexture();
+
if (!highlighted)
{
- if (!compiz_utils::IsWindowFullyDecorable(window))
- return;
-
- if (!decoration_tex_)
- BuildDecorationTexture();
-
if (decoration_tex_)
DrawTexture(*decoration_tex_, attrib, transform, mask, geo.x, geo.y, scale);
@@ -4113,7 +4131,14 @@ void UnityWindow::paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAtt
int text_x = padding.left + (close_texture ? close_texture->width() : 0) / dpi_scale;
RenderTitle(context, text_x, padding.top, (width - padding.right) / dpi_scale, height / dpi_scale, scale);
decoration_selected_tex_ = context;
+ decoration_title_ = deco_win_->title();
uScreen->damageRegion(CompRegionFromNuxGeo(geo));
+ need_fake_deco_redraw_ = true;
+
+ if (decoration_tex_)
+ DrawTexture(*decoration_tex_, attrib, transform, mask, geo.x, geo.y, scale);
+
+ return; // Let's draw this at next repaint cycle
}
else
{
@@ -4121,6 +4146,10 @@ void UnityWindow::paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAtt
redraw_decoration = false;
}
}
+ else
+ {
+ need_fake_deco_redraw_ = false;
+ }
if (decoration_selected_tex_)
DrawTexture(*decoration_selected_tex_, attrib, transform, mask, geo.x, geo.y);
@@ -4157,7 +4186,7 @@ void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
auto state = uScreen->sScreen->getState();
- if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
+ if (state != ScaleScreen::Wait && state != ScaleScreen::Out && !need_fake_deco_redraw_)
return;
nux::Geometry const& scale_geo = GetScaledGeometry();
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index a572ae50d..a9bf144d7 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -278,8 +278,7 @@ private:
void OnLauncherStartKeyNav(GVariant* data);
void OnLauncherEndKeyNav(GVariant* data);
-
- void OnSwitcherEnd(GVariant* data);
+ void OnSwitcherDetailChanged(bool detail);
void OnInitiateSpread();
void OnTerminateSpread();
@@ -558,6 +557,7 @@ private:
nux::Geometry close_button_geo_;
std::shared_ptr<decoration::Window> deco_win_;
bool middle_clicked_;
+ bool need_fake_deco_redraw_;
bool is_nux_window_;
glib::Source::UniquePtr focus_desktop_timeout_;
diff --git a/services/panel-service.c b/services/panel-service.c
index 17789027b..e75fe4d96 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -277,7 +277,7 @@ panel_service_class_init (PanelServiceClass *klass)
g_type_class_add_private (obj_class, sizeof (PanelServicePrivate));
}
-static IndicatorObjectEntry *
+IndicatorObjectEntry *
get_entry_at (PanelService *self, gint x, gint y)
{
GHashTableIter panel_iter, entries_iter;
@@ -305,6 +305,37 @@ get_entry_at (PanelService *self, gint x, gint y)
return NULL;
}
+static IndicatorObjectEntry *
+get_entry_at_panel (PanelService *self, const gchar *panel, gint x, gint y)
+{
+ GHashTable *entry2geometry_hash;
+ GHashTableIter entries_iter;
+ gpointer key, value;
+
+ if (!panel)
+ return NULL;
+
+ entry2geometry_hash = g_hash_table_lookup (self->priv->panel2entries_hash, panel);
+
+ if (!entry2geometry_hash)
+ return NULL;
+
+ g_hash_table_iter_init (&entries_iter, entry2geometry_hash);
+ while (g_hash_table_iter_next (&entries_iter, &key, &value))
+ {
+ IndicatorObjectEntry *entry = key;
+ GdkRectangle *geo = value;
+
+ if (x >= geo->x && x <= (geo->x + geo->width) &&
+ y >= geo->y && y <= (geo->y + geo->height))
+ {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
static const gchar*
get_panel_at (PanelService *self, gint x, gint y)
{
@@ -493,7 +524,7 @@ event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self)
case XI_ButtonPress:
{
- priv->pressed_entry = get_entry_at (self, event->root_x, event->root_y);
+ priv->pressed_entry = get_entry_at_panel (self, priv->last_panel, event->root_x, event->root_y);
priv->use_event = (priv->pressed_entry == NULL);
if (priv->pressed_entry)
@@ -504,9 +535,9 @@ event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self)
case XI_ButtonRelease:
{
- IndicatorObjectEntry *entry;
+ IndicatorObjectEntry *entry = NULL;
gboolean event_is_a_click = FALSE;
- entry = get_entry_at (self, event->root_x, event->root_y);
+ entry = get_entry_at_panel (self, priv->last_panel, event->root_x, event->root_y);
if (event->detail == 1 || event->detail == 3)
{
@@ -1414,6 +1445,9 @@ sort_indicators (PanelService *self)
static gchar *
gtk_image_to_data (GtkImage *image, guint32 *storage_type)
{
+ if (!GTK_IS_IMAGE (image))
+ return NULL;
+
*storage_type = gtk_image_get_storage_type (image);
gchar *ret = NULL;
@@ -1453,8 +1487,6 @@ gtk_image_to_data (GtkImage *image, guint32 *storage_type)
g_warning ("Unable to convert pixbuf to png data: '%s'", error ? error->message : "unknown");
if (error)
g_error_free (error);
-
- ret = g_strdup ("");
}
break;
@@ -1480,12 +1512,10 @@ gtk_image_to_data (GtkImage *image, guint32 *storage_type)
}
case GTK_IMAGE_EMPTY:
{
- ret = g_strdup ("");
break;
}
default:
{
- ret = g_strdup ("");
g_warning ("Unable to support GtkImageType: %u", *storage_type);
}
}
@@ -1513,7 +1543,7 @@ indicator_entry_to_variant (IndicatorObjectEntry *entry,
is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,
is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,
is_image ? image_type : 0,
- is_image ? image_data : "",
+ image_data ? image_data : "",
is_image ? gtk_widget_get_sensitive (GTK_WIDGET (entry->image)) : FALSE,
is_image ? gtk_widget_get_visible (GTK_WIDGET (entry->image)) : FALSE,
prio);
@@ -1612,7 +1642,11 @@ positon_menu (GtkMenu *menu,
PanelService *self = PANEL_SERVICE (user_data);
PanelServicePrivate *priv = self->priv;
- gint scale = get_monitor_scale_at (priv->last_x, priv->last_y);
+ GdkScreen *screen = gdk_screen_get_default ();
+ gint monitor = gdk_screen_get_monitor_at_point (screen, priv->last_x, priv->last_y);
+ gtk_menu_set_monitor (menu, monitor);
+
+ gint scale = gdk_screen_get_monitor_scale_factor (screen, monitor);
*x = priv->last_x / scale;
*y = priv->last_y / scale;
*push = TRUE;
diff --git a/tests/MockSwitcherController.h b/tests/MockSwitcherController.h
index 4425fc486..a4afeb9be 100644
--- a/tests/MockSwitcherController.h
+++ b/tests/MockSwitcherController.h
@@ -49,11 +49,9 @@ public:
MOCK_CONST_METHOD1(CanShowSwitcher, bool(const std::vector<launcher::AbstractLauncherIcon::Ptr> &));
MOCK_METHOD0(NextDetail, void());
MOCK_METHOD0(PrevDetail, void());
- MOCK_METHOD2(SetDetail, void(bool, unsigned int));
MOCK_METHOD0(SelectFirstItem, void());
MOCK_METHOD2(SetWorkspace, void(nux::Geometry, int));
- MOCK_METHOD0(ExternalRenderTargets, unity::ui::LayoutWindow::Vector ());
- MOCK_CONST_METHOD0(GetSwitcherInputWindowId, guint());
+ MOCK_CONST_METHOD0(ExternalRenderTargets, unity::ui::LayoutWindow::Vector const&());
MOCK_CONST_METHOD0(IsShowDesktopDisabled, bool());
MOCK_METHOD1(SetShowDesktopDisabled, void(bool));
MOCK_CONST_METHOD0(StartIndex, int());
diff --git a/tests/test_switcher_controller.cpp b/tests/test_switcher_controller.cpp
index 5029dbe6f..87e29fb37 100644
--- a/tests/test_switcher_controller.cpp
+++ b/tests/test_switcher_controller.cpp
@@ -83,27 +83,27 @@ TEST_F(TestSwitcherController, StartDetailMode)
{
controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
controller_->InitiateDetail();
- EXPECT_TRUE(controller_->IsDetailViewShown());
+ EXPECT_TRUE(controller_->detail());
auto const& view = controller_->GetView();
view->switcher_stop_detail.emit();
- EXPECT_FALSE(controller_->IsDetailViewShown());
+ EXPECT_FALSE(controller_->detail());
view->switcher_start_detail.emit();
- EXPECT_TRUE(controller_->IsDetailViewShown());
+ EXPECT_TRUE(controller_->detail());
}
TEST_F(TestSwitcherController, StopDetailMode)
{
controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
controller_->InitiateDetail();
- EXPECT_TRUE(controller_->IsDetailViewShown());
+ EXPECT_TRUE(controller_->detail());
auto const& view = controller_->GetView();
view->switcher_stop_detail.emit();
- EXPECT_FALSE(controller_->IsDetailViewShown());
+ EXPECT_FALSE(controller_->detail());
}
TEST_F(TestSwitcherController, StartDetailModeMovesNextRows)
@@ -117,7 +117,7 @@ TEST_F(TestSwitcherController, StartDetailModeMovesNextRows)
model->SetRowSizes({2,2});
view->switcher_start_detail.emit();
- EXPECT_TRUE(controller_->IsDetailViewShown());
+ EXPECT_TRUE(controller_->detail());
view->switcher_start_detail.emit();
@@ -137,7 +137,7 @@ TEST_F(TestSwitcherController, StopDetailModeMovesPrevRows)
auto const& view = controller_->GetView();
view->switcher_start_detail.emit();
- EXPECT_TRUE(controller_->IsDetailViewShown());
+ EXPECT_TRUE(controller_->detail());
auto model = view->GetModel();
model->SetRowSizes({2,2});
@@ -153,7 +153,7 @@ TEST_F(TestSwitcherController, StopDetailModeMovesPrevRows)
// Now we are in index 0, stoping detail mode must exit detail mode
view->switcher_stop_detail.emit();
- EXPECT_FALSE(controller_->IsDetailViewShown());
+ EXPECT_FALSE(controller_->detail());
}
TEST_F(TestSwitcherController, ShowSwitcher)
diff --git a/tests/test_switcher_controller_slow.cpp b/tests/test_switcher_controller_slow.cpp
index 1b1e8b113..58deb59c9 100644
--- a/tests/test_switcher_controller_slow.cpp
+++ b/tests/test_switcher_controller_slow.cpp
@@ -107,8 +107,8 @@ TEST_F(TestSwitcherController, DetailTimeoutOnDetailActivate)
EXPECT_EQ(controller_->GetCurrentSelection().window_, 0);
// Manually open-close the detail mode before that the timeout has occurred
- controller_->SetDetail(true);
- controller_->SetDetail(false);
+ controller_->detail = true;
+ controller_->detail = false;
Utils::WaitForTimeoutMSec(initial_details_timeout * 1.1);
EXPECT_EQ(controller_->GetCurrentSelection().window_, 0);
diff --git a/unity-shared/CompizUtils.cpp b/unity-shared/CompizUtils.cpp
index 018ed2150..6084386f8 100644
--- a/unity-shared/CompizUtils.cpp
+++ b/unity-shared/CompizUtils.cpp
@@ -110,9 +110,13 @@ bool SimpleTextureQuad::SetY(int y)
//
PixmapTexture::PixmapTexture(int w, int h)
- : pixmap_(XCreatePixmap(screen->dpy(), screen->root(), w, h, PIXMAP_DEPTH))
+ : pixmap_(0)
{
- texture_ = GLTexture::bindPixmapToTexture(pixmap_, w, h, PIXMAP_DEPTH);
+ if (w > 0 && h > 0)
+ {
+ pixmap_ = XCreatePixmap(screen->dpy(), screen->root(), w, h, PIXMAP_DEPTH);
+ texture_ = GLTexture::bindPixmapToTexture(pixmap_, w, h, PIXMAP_DEPTH);
+ }
}
PixmapTexture::~PixmapTexture()
diff --git a/unity-shared/PluginAdapter.cpp b/unity-shared/PluginAdapter.cpp
index c2ea69dd2..5db3f5ecb 100644
--- a/unity-shared/PluginAdapter.cpp
+++ b/unity-shared/PluginAdapter.cpp
@@ -699,21 +699,14 @@ void PluginAdapter::RestoreAt(Window window_id, int x, int y)
if (window && (window->state() & MAXIMIZE_STATE))
{
nux::Geometry new_geo(GetWindowSavedGeometry(window_id));
- decoration::Border border;
- double scale = 1.0f;
-
- if (compiz_utils::IsWindowFullyDecorable(window))
- {
- auto& settings = Settings::Instance();
- border = decoration::Style::Get()->Border();
- scale = settings.em(MonitorGeometryIn(new_geo))->DPIScale();
- }
+ window->maximize(0);
+ auto const& border = window->border();
new_geo.x = x;
- new_geo.y = y;
- new_geo.width -= (border.left - border.right) * scale;
- new_geo.height -= (border.top - border.bottom) * scale;
- window->maximize(0);
+ new_geo.y = y + border.top;
+ new_geo.width -= (border.left + border.right);
+ new_geo.height -= (border.top + border.bottom);
+
MoveResizeWindow(window_id, new_geo);
}
}