From e1284e95ee78401b24abc6aa64e17a25ff8ac633 Mon Sep 17 00:00:00 2001 From: Andrea Azzarone Date: Mon, 24 Sep 2012 18:00:13 +0200 Subject: Create dash::StyleInterface class. (bzr r2729.2.3) --- unity-shared/DashStyle.h | 4 ++- unity-shared/DashStyleInterface.h | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 unity-shared/DashStyleInterface.h (limited to 'unity-shared') diff --git a/unity-shared/DashStyle.h b/unity-shared/DashStyle.h index e1f0f667c..b54c93135 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 #include #include @@ -83,7 +85,7 @@ enum class Arrow { }; -class Style +class Style : public StyleInterface { public: Style (); 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 . + * + * Authored by: Andrea Azzarone + */ + +#ifndef UNITYSHELL_DASH_STYLE_INTERFACE_H +#define UNITYSHELL_DASH_STYLE_INTERFACE_H + +#include + +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 -- cgit v1.2.3 From c6adb8a4971be25b70226fecc5f1c6718dcb328e Mon Sep 17 00:00:00 2001 From: Nicolas d'Offay Date: Tue, 2 Oct 2012 16:34:02 +0100 Subject: Removed all PostDraws from Unity. (bzr r2783.3.1) --- unity-shared/StaticCairoText.cpp | 5 ----- unity-shared/StaticCairoText.h | 3 --- unity-shared/UnityWindowView.cpp | 2 -- unity-shared/UnityWindowView.h | 1 - 4 files changed, 11 deletions(-) (limited to 'unity-shared') diff --git a/unity-shared/StaticCairoText.cpp b/unity-shared/StaticCairoText.cpp index 33cea145c..ca6599aba 100644 --- a/unity-shared/StaticCairoText.cpp +++ b/unity-shared/StaticCairoText.cpp @@ -303,11 +303,6 @@ void StaticCairoText::DrawContent(GraphicsEngine& gfxContext, bool forceDraw) // intentionally left empty } -void StaticCairoText::PostDraw(GraphicsEngine& gfxContext, bool forceDraw) -{ - // intentionally left empty -} - void StaticCairoText::SetText(std::string const& text, bool escape_text) { std::string tmp_text = escape_text ? GetEscapedText(text) : text; diff --git a/unity-shared/StaticCairoText.h b/unity-shared/StaticCairoText.h index cf6bed37c..683afac77 100644 --- a/unity-shared/StaticCairoText.h +++ b/unity-shared/StaticCairoText.h @@ -65,9 +65,6 @@ public: void DrawContent(GraphicsEngine& gfxContext, bool forceDraw); - void PostDraw(GraphicsEngine& gfxContext, - bool forceDraw); - // public API void SetText(std::string const& text, bool escape_text = false); void SetTextColor(Color const& textColor); diff --git a/unity-shared/UnityWindowView.cpp b/unity-shared/UnityWindowView.cpp index 99b2c28a9..6b6a8a920 100644 --- a/unity-shared/UnityWindowView.cpp +++ b/unity-shared/UnityWindowView.cpp @@ -148,8 +148,6 @@ void UnityWindowView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_dr GfxContext.PopClippingRectangle(); DrawBackground(GfxContext, background_geo); - - PostDraw(GfxContext, force_draw); } void UnityWindowView::DrawBackground(nux::GraphicsEngine& GfxContext, nux::Geometry const& geo) diff --git a/unity-shared/UnityWindowView.h b/unity-shared/UnityWindowView.h index 439c022f4..a5c08c626 100644 --- a/unity-shared/UnityWindowView.h +++ b/unity-shared/UnityWindowView.h @@ -51,7 +51,6 @@ protected: virtual void PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw) {}; virtual void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry clip) = 0; - virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw) {}; virtual nux::Geometry GetBackgroundGeometry() = 0; // Introspectable methods -- cgit v1.2.3 From 6634b2393981c503954f6b0d82c19a93aa1dd89e Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Wed, 3 Oct 2012 12:09:27 +0100 Subject: Update result geometry in ResultViewGrid introspection on child request. (bzr r2783.2.1) --- unity-shared/IntrospectableWrappers.cpp | 41 +++++++++++++++++++-------------- unity-shared/IntrospectableWrappers.h | 3 +++ 2 files changed, 27 insertions(+), 17 deletions(-) (limited to 'unity-shared') diff --git a/unity-shared/IntrospectableWrappers.cpp b/unity-shared/IntrospectableWrappers.cpp index 910628df4..5f152aca1 100644 --- a/unity-shared/IntrospectableWrappers.cpp +++ b/unity-shared/IntrospectableWrappers.cpp @@ -25,28 +25,35 @@ namespace unity { namespace debug { - ResultWrapper::ResultWrapper(dash::Result const& result, nux::Geometry const& geo) - : uri_(result.uri), + +ResultWrapper::ResultWrapper(dash::Result const& result, nux::Geometry const& geo) +: uri_(result.uri), name_(result.name), icon_hint_(result.icon_hint), mime_type_(result.mimetype), geo_(geo) - { - } +{ +} + +std::string ResultWrapper::GetName() const +{ + return "Result"; +} - std::string ResultWrapper::GetName() const - { - return "Result"; - } +void ResultWrapper::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper(builder) + .add("uri", uri_) + .add("name", name_) + .add("icon_hint", icon_hint_) + .add("mimetype", mime_type_) + .add(geo_); +} + +void ResultWrapper::UpdateGeometry(nux::Geometry const& geo) +{ + geo_ = geo; +} - void ResultWrapper::AddProperties(GVariantBuilder* builder) - { - unity::variant::BuilderWrapper(builder) - .add("uri", uri_) - .add("name", name_) - .add("icon_hint", icon_hint_) - .add("mimetype", mime_type_) - .add(geo_); - } } } diff --git a/unity-shared/IntrospectableWrappers.h b/unity-shared/IntrospectableWrappers.h index 5fae901ef..8f11e3700 100644 --- a/unity-shared/IntrospectableWrappers.h +++ b/unity-shared/IntrospectableWrappers.h @@ -39,6 +39,9 @@ public: ResultWrapper(const dash::Result& result, nux::Geometry const& geo = nux::Geometry()); std::string GetName() const; void AddProperties(GVariantBuilder* builder); + + void UpdateGeometry(nux::Geometry const& geo); + private: std::string uri_; std::string name_; -- cgit v1.2.3 From afd5b3d8ecd337a4ecd9166d775d1dc8fef160c2 Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Thu, 4 Oct 2012 20:10:39 +1300 Subject: Initial pull from next pipe. (bzr r2791.4.1) --- unity-shared/BackgroundEffectHelper.cpp | 1 - unity-shared/CMakeLists.txt | 5 +- unity-shared/PluginAdapter.cpp | 1304 +++++++++++++++++++++++++++ unity-shared/PluginAdapter.h | 98 +- unity-shared/PluginAdapterCompiz.cpp | 1423 ------------------------------ unity-shared/PluginAdapterStandalone.cpp | 491 ----------- unity-shared/StandaloneWindowManager.cpp | 274 ++++++ unity-shared/StandaloneWindowManager.h | 108 +++ unity-shared/StaticCairoText.cpp | 4 - unity-shared/WindowManager.cpp | 271 +----- unity-shared/WindowManager.h | 137 +-- 11 files changed, 1764 insertions(+), 2352 deletions(-) create mode 100644 unity-shared/PluginAdapter.cpp delete mode 100644 unity-shared/PluginAdapterCompiz.cpp delete mode 100644 unity-shared/PluginAdapterStandalone.cpp create mode 100644 unity-shared/StandaloneWindowManager.cpp create mode 100644 unity-shared/StandaloneWindowManager.h (limited to 'unity-shared') diff --git a/unity-shared/BackgroundEffectHelper.cpp b/unity-shared/BackgroundEffectHelper.cpp index 2d3be7ef4..f9078b801 100644 --- a/unity-shared/BackgroundEffectHelper.cpp +++ b/unity-shared/BackgroundEffectHelper.cpp @@ -29,7 +29,6 @@ #undef FALSE #endif -#include #include #include "UnitySettings.h" diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt index c2c5b9562..dbb4b28a8 100644 --- a/unity-shared/CMakeLists.txt +++ b/unity-shared/CMakeLists.txt @@ -64,6 +64,7 @@ set (UNITY_SHARED_SOURCES UnityWindowView.cpp UserThumbnailProvider.cpp WindowManager.cpp + XWindowManager.cpp ubus-server.cpp ) @@ -77,7 +78,7 @@ add_dependencies (unity-shared unity-core-${UNITY_API_VERSION}) # compiz set (UNITY_SHARED_COMPIZ_SOURCES - PluginAdapterCompiz.cpp + PluginAdapter.cpp ) add_library (unity-shared-compiz STATIC ${UNITY_SHARED_COMPIZ_SOURCES}) target_link_libraries (unity-shared-compiz ${LIBS}) @@ -86,7 +87,7 @@ add_dependencies (unity-shared-compiz unity-shared) # standalone set (UNITY_SHARED_STANDALONE_SOURCES - PluginAdapterStandalone.cpp + StandaloneWindowManager.cpp ) add_library (unity-shared-standalone STATIC ${UNITY_SHARED_STANDALONE_SOURCES}) target_link_libraries (unity-shared-standalone ${LIBS}) diff --git a/unity-shared/PluginAdapter.cpp b/unity-shared/PluginAdapter.cpp new file mode 100644 index 000000000..8aa4c3723 --- /dev/null +++ b/unity-shared/PluginAdapter.cpp @@ -0,0 +1,1304 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010-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 . + * + * Authored by: Jason Smith + */ + +#include +#include +#include "PluginAdapter.h" +#include "UScreen.h" + +#include +#include + +namespace unity +{ +namespace +{ + +nux::logging::Logger logger("unity.plugin"); + +const int THRESHOLD_HEIGHT = 600; +const int THRESHOLD_WIDTH = 1024; + +std::shared_ptr global_instance; +} + +#define MAXIMIZABLE (CompWindowActionMaximizeHorzMask & CompWindowActionMaximizeVertMask & CompWindowActionResizeMask) + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_UNDECORATED_UNITY 0x80 +#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" + + +WindowManagerPtr create_window_manager() +{ + return global_instance; +} + +/* static */ +PluginAdapter& PluginAdapter::Default() +{ + // Better hope that initialize has been called first. + return *global_instance; +} + +/* static */ +void PluginAdapter::Initialize(CompScreen* screen) +{ + global_instance.reset(new PluginAdapter(screen)); +} + +PluginAdapter::PluginAdapter(CompScreen* screen) : + m_Screen(screen), + _in_show_desktop (false), + _last_focused_window(nullptr) +{ + _spread_state = false; + _spread_windows_state = false; + _expo_state = false; + _vp_switch_started = false; + + _grab_show_action = 0; + _grab_hide_action = 0; + _grab_toggle_action = 0; + _coverage_area_before_automaximize = 0.75; + bias_active_to_viewport = false; +} + +PluginAdapter::~PluginAdapter() +{ +} + +/* A No-op for now, but could be useful later */ +void PluginAdapter::OnScreenGrabbed() +{ + screen_grabbed.emit(); + + if (!_spread_state && screen->grabExist("scale")) + { + _spread_state = true; + initiate_spread.emit(); + } + + if (!_expo_state && screen->grabExist("expo")) + { + _expo_state = true; + initiate_expo.emit(); + } +} + +void PluginAdapter::OnScreenUngrabbed() +{ + if (_spread_state && !screen->grabExist("scale")) + { + _spread_state = false; + _spread_windows_state = false; + terminate_spread.emit(); + } + + if (_expo_state && !screen->grabExist("expo")) + { + _expo_state = false; + terminate_expo.emit(); + } + + screen_ungrabbed.emit(); +} + +void PluginAdapter::NotifyResized(CompWindow* window, int x, int y, int w, int h) +{ + window_resized.emit(window->id()); +} + +void PluginAdapter::NotifyMoved(CompWindow* window, int x, int y) +{ + window_moved.emit(window->id()); +} + +void PluginAdapter::NotifyStateChange(CompWindow* window, unsigned int state, unsigned int last_state) +{ + if (!((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) + && ((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) + { + window_maximized.emit(window->id()); + } + else if (((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) + && !((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) + { + window_restored.emit(window->id()); + } +} + +void PluginAdapter::NotifyNewDecorationState(Window xid) +{ + bool wasTracked = (_window_decoration_state.find(xid) != _window_decoration_state.end()); + bool wasDecorated = false; + + if (wasTracked) + wasDecorated = _window_decoration_state[xid]; + + bool decorated = IsWindowDecorated(xid); + + if (decorated == wasDecorated) + return; + + if (decorated && (!wasDecorated || !wasTracked)) + window_decorated.emit(xid); + else if (wasDecorated || !wasTracked) + window_undecorated.emit(xid); +} + +void PluginAdapter::Notify(CompWindow* window, CompWindowNotify notify) +{ + switch (notify) + { + case CompWindowNotifyMinimize: + window_minimized.emit(window->id()); + break; + case CompWindowNotifyUnminimize: + window_unminimized.emit(window->id()); + break; + case CompWindowNotifyShade: + window_shaded.emit(window->id()); + break; + case CompWindowNotifyUnshade: + window_unshaded.emit(window->id()); + break; + case CompWindowNotifyHide: + window_hidden.emit(window->id()); + break; + case CompWindowNotifyShow: + window_shown.emit(window->id()); + break; + case CompWindowNotifyMap: + window_mapped.emit(window->id()); + break; + case CompWindowNotifyUnmap: + window_unmapped.emit(window->id()); + break; + case CompWindowNotifyFocusChange: + window_focus_changed.emit(window->id()); + break; + default: + break; + } +} + +void PluginAdapter::NotifyCompizEvent(const char* plugin, + const char* event, + CompOption::Vector& option) +{ + if (g_strcmp0(event, "start_viewport_switch") == 0) + { + _vp_switch_started = true; + screen_viewport_switch_started.emit(); + } + else if (g_strcmp0(event, "end_viewport_switch") == 0) + { + _vp_switch_started = false; + screen_viewport_switch_ended.emit(); + } +} + +void MultiActionList::AddNewAction(std::string const& name, CompAction* a, bool primary) +{ + actions_[name] = a; + + if (primary) + primary_action_ = a; +} + +void MultiActionList::RemoveAction(std::string const& name) +{ + actions_.erase(name); +} + +CompAction* MultiActionList::GetAction(std::string const& name) const +{ + auto it = actions_.find(name); + + if (it == actions_.end()) + return nullptr; + + return it->second; +} + +bool MultiActionList::HasPrimary() const +{ + return bool(primary_action_); +} + +void MultiActionList::Initiate(std::string const& name, CompOption::Vector const& extra_args, int state) const +{ + if (name.empty()) + return; + + CompAction* action = GetAction(name); + + if (!action) + return; + + CompOption::Vector argument(1); + argument[0].setName("root", CompOption::TypeInt); + argument[0].value().set((int) screen->root()); + + for (CompOption const& arg : extra_args) + argument.push_back(arg); + + /* Initiate the selected action with the arguments */ + action->initiate()(action, state, argument); +} + +void MultiActionList::InitiateAll(CompOption::Vector const& extra_args, int state) const +{ + if (actions_.empty()) + return; + + std::string action_name; + + if (primary_action_) + { + for (auto const& it : actions_) + { + if (it.second == primary_action_) + { + action_name = it.first; + break; + } + } + } + else + { + action_name = actions_.begin()->first; + } + + Initiate(action_name, extra_args, state); +} + +void MultiActionList::TerminateAll(CompOption::Vector const& extra_args) const +{ + if (actions_.empty()) + return; + + CompOption::Vector argument(1); + argument[0].setName("root", CompOption::TypeInt); + argument[0].value().set((int) screen->root()); + + for (CompOption const& a : extra_args) + argument.push_back(a); + + if (primary_action_) + { + primary_action_->terminate()(primary_action_, 0, argument); + return; + } + + for (auto const& it : actions_) + { + CompAction* action = it.second; + + if (action->state() & (CompAction::StateTermKey | + CompAction::StateTermButton | + CompAction::StateTermEdge | + CompAction::StateTermEdgeDnd)) + { + action->terminate()(action, 0, argument); + } + } +} + +unsigned long long PluginAdapter::GetWindowActiveNumber(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + + if (window) + { + // result is actually an unsigned int (32 bits) + unsigned long long result = window->activeNum (); + if (bias_active_to_viewport() && window->defaultViewport() == m_Screen->vp()) + result = result << 32; + + return result; + } + + return 0; +} + +void PluginAdapter::SetExpoAction(MultiActionList& expo) +{ + m_ExpoActionList = expo; +} + +void PluginAdapter::SetScaleAction(MultiActionList& scale) +{ + m_ScaleActionList = scale; +} + +std::string PluginAdapter::MatchStringForXids(std::vector const& windows) +{ + std::ostringstream sout; + + sout << "any & ("; + + for (auto const& window : windows) + { + sout << "| xid=" << window << " "; + } + sout << ")"; + + return sout.str(); +} + +void PluginAdapter::InitiateScale(std::string const& match, int state) +{ + CompOption::Vector argument(1); + argument[0].setName("match", CompOption::TypeMatch); + argument[0].value().set(CompMatch(match)); + + m_ScaleActionList.InitiateAll(argument, state); +} + +void PluginAdapter::TerminateScale() +{ + m_ScaleActionList.TerminateAll(); +} + +bool PluginAdapter::IsScaleActive() const +{ + return m_Screen->grabExist("scale"); +} + +bool PluginAdapter::IsScaleActiveForGroup() const +{ + return _spread_windows_state && m_Screen->grabExist("scale"); +} + +bool PluginAdapter::IsExpoActive() const +{ + return m_Screen->grabExist("expo"); +} + +bool PluginAdapter::IsWallActive() const +{ + return m_Screen->grabExist("wall"); +} + +void PluginAdapter::InitiateExpo() +{ + m_ExpoActionList.InitiateAll(); +} + +void PluginAdapter::TerminateExpo() +{ + m_ExpoActionList.Initiate("exit_button"); +} + +// WindowManager implementation +Window PluginAdapter::GetActiveWindow() const +{ + return m_Screen->activeWindow(); +} + +bool PluginAdapter::IsWindowMaximized(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + { + return ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE); + } + + return false; +} + +bool PluginAdapter::IsWindowDecorated(Window window_id) const +{ + Display* display = m_Screen->dpy(); + MotifWmHints* hints = NULL; + Atom type = None; + gint format; + gulong nitems; + gulong bytes_after; + bool ret = true; + + Atom hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false); + + if (XGetWindowProperty(display, window_id, hints_atom, 0, + sizeof(MotifWmHints) / sizeof(long), False, + hints_atom, &type, &format, &nitems, &bytes_after, + (guchar**)&hints) != Success) + return false; + + if (!hints) + return ret; + + /* Check for the presence of the high bit + * if present, it means that we undecorated + * this window, so don't mark it as undecorated */ + if (type == hints_atom && format != 0 && + hints->flags & MWM_HINTS_DECORATIONS) + { + /* Must have both bits set */ + ret = (hints->decorations & (MwmDecorAll | MwmDecorTitle)) || + (hints->decorations & MWM_HINTS_UNDECORATED_UNITY); + // This is mildly evil and we should look for another solution. + PluginAdapter* non_const_this = const_cast(this); + non_const_this->_window_decoration_state[window_id] = ret; + } + + XFree(hints); + return ret; +} + +bool PluginAdapter::IsWindowOnCurrentDesktop(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + { + // we aren't checking window->onCurrentDesktop (), as the name implies, because that is broken + return (window->defaultViewport() == m_Screen->vp()); + } + + return false; +} + +bool PluginAdapter::IsWindowObscured(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + + if (window) + { + if (window->inShowDesktopMode()) + return true; + + CompPoint window_vp = window->defaultViewport(); + nux::Geometry const& win_geo = GetWindowGeometry(window->id()); + // Check if any windows above this one are blocking it + for (CompWindow* sibling = window->next; sibling != NULL; sibling = sibling->next) + { + if (sibling->defaultViewport() == window_vp + && !sibling->minimized() + && sibling->isMapped() + && sibling->isViewable() + && (sibling->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE + && !GetWindowGeometry(sibling->id()).Intersect(win_geo).IsNull()) + { + return true; + } + } + } + + return false; +} + +bool PluginAdapter::IsWindowMapped(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + return window->mapNum () > 0; + return true; +} + +bool PluginAdapter::IsWindowVisible(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + return !(window->state() & CompWindowStateHiddenMask) && !window->inShowDesktopMode(); + + return false; +} + +bool PluginAdapter::IsWindowOnTop(Window window_id) const +{ + if (window_id == GetTopMostValidWindowInViewport()) + return true; + + return false; +} + +Window PluginAdapter::GetTopMostValidWindowInViewport() const +{ + CompWindow* window; + CompPoint screen_vp = m_Screen->vp(); + std::vector const& our_xids = nux::XInputWindow::NativeHandleList(); + + auto const& windows = m_Screen->windows(); + for (auto it = windows.rbegin(); it != windows.rend(); ++it) + { + window = *it; + if (window->defaultViewport() == screen_vp && + window->isViewable() && window->isMapped() && + !window->minimized() && !window->inShowDesktopMode() && + !(window->state() & CompWindowStateAboveMask) && + !(window->type() & CompWindowTypeSplashMask) && + !(window->type() & CompWindowTypeDockMask) && + !window->overrideRedirect() && + std::find(our_xids.begin(), our_xids.end(), window->id()) == our_xids.end()) + { + return window->id(); + } + } + return 0; +} + +bool PluginAdapter::IsWindowClosable(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + return (window->actions() & CompWindowActionCloseMask); + + return false; +} + +bool PluginAdapter::IsWindowMinimizable(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + return (window->actions() & CompWindowActionMinimizeMask); + + return false; +} + +bool PluginAdapter::IsWindowMaximizable(Window window_id) const +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + return (window->actions() & MAXIMIZABLE); + + return false; +} + +void PluginAdapter::Restore(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + window->maximize(0); +} + +void PluginAdapter::RestoreAt(Window window_id, int x, int y) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window && (window->state() & MAXIMIZE_STATE)) + { + nux::Geometry new_geo(GetWindowSavedGeometry(window_id)); + new_geo.x = x; + new_geo.y = y; + window->maximize(0); + MoveResizeWindow(window_id, new_geo); + } +} + +void PluginAdapter::Minimize(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window && (window->actions() & CompWindowActionMinimizeMask)) + window->minimize(); +} + +void PluginAdapter::Close(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + window->close(CurrentTime); +} + +void PluginAdapter::Activate(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + window->activate(); +} + +void PluginAdapter::Raise(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + window->raise(); +} + +void PluginAdapter::Lower(Window window_id) +{ + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + window->lower(); +} + +void PluginAdapter::FocusWindowGroup(std::vector const& window_ids, + FocusVisibility focus_visibility, + int monitor, bool only_top_win) +{ + CompPoint target_vp = m_Screen->vp(); + CompWindow* top_window = nullptr; + CompWindow* top_monitor_win = nullptr; + + bool any_on_current = false; + bool any_mapped = false; + bool any_mapped_on_current = false; + bool forced_unminimize = false; + + /* sort the list */ + CompWindowList windows; + for (auto win : m_Screen->clientList()) + { + Window id = win->id(); + if (std::find(window_ids.begin(), window_ids.end(), id) != window_ids.end()) + windows.push_back(win); + } + + /* filter based on workspace */ + for (CompWindow* &win : windows) + { + if (win->defaultViewport() == m_Screen->vp()) + { + any_on_current = true; + + if (!win->minimized()) + { + any_mapped_on_current = true; + } + } + + if (!win->minimized()) + { + any_mapped = true; + } + + if (any_on_current && any_mapped) + break; + } + + if (!any_on_current) + { + for (auto it = windows.rbegin(); it != windows.rend(); ++it) + { + CompWindow* win = *it; + if ((any_mapped && !win->minimized()) || !any_mapped) + { + target_vp = win->defaultViewport(); + break; + } + } + } + + for (CompWindow* &win : windows) + { + if (win->defaultViewport() == target_vp) + { + int win_monitor = GetWindowMonitor(win->id()); + + /* Any window which is actually unmapped is + * not going to be accessible by either switcher + * or scale, so unconditionally unminimize those + * windows when the launcher icon is activated */ + if ((focus_visibility == WindowManager::FocusVisibility::ForceUnminimizeOnCurrentDesktop && + target_vp == m_Screen->vp()) || + (focus_visibility == WindowManager::FocusVisibility::ForceUnminimizeInvisible && + win->mapNum() == 0)) + { + top_window = win; + forced_unminimize = true; + + if (monitor >= 0 && win_monitor == monitor) + top_monitor_win = win; + + if (!only_top_win) + { + bool is_mapped = (win->mapNum() != 0); + win->unminimize(); + + /* Initially minimized windows dont get raised */ + if (!is_mapped) + win->raise(); + } + } + else if ((any_mapped_on_current && !win->minimized()) || !any_mapped_on_current) + { + if (!forced_unminimize || target_vp == m_Screen->vp()) + { + top_window = win; + + if (monitor >= 0 && win_monitor == monitor) + top_monitor_win = win; + + if (!only_top_win) + win->raise(); + } + } + } + } + + if (monitor >= 0 && top_monitor_win) + top_window = top_monitor_win; + + if (top_window) + { + if (only_top_win) + { + if (forced_unminimize) + { + top_window->unminimize(); + } + + top_window->raise(); + } + + top_window->activate(); + } +} + +bool PluginAdapter::ScaleWindowGroup(std::vector const& windows, int state, bool force) +{ + std::size_t num_windows = windows.size(); + if (num_windows > 1 || (force && num_windows)) + { + std::string const& match = MatchStringForXids(windows); + InitiateScale(match, state); + _spread_windows_state = true; + return true; + } + return false; +} + +void PluginAdapter::SetWindowIconGeometry(Window window, nux::Geometry const& geo) +{ + long data[4]; + + data[0] = geo.x; + data[1] = geo.y; + data[2] = geo.width; + data[3] = geo.height; + + XChangeProperty(m_Screen->dpy(), window, Atoms::wmIconGeometry, + XA_CARDINAL, 32, PropModeReplace, + (unsigned char*) data, 4); +} + +void PluginAdapter::ShowDesktop() +{ + if (_in_show_desktop) + { + LOG_INFO(logger) << "Leaving show-desktop mode."; + m_Screen->leaveShowDesktopMode(NULL); + } + else + { + LOG_INFO(logger) << "Entering show-desktop mode."; + m_Screen->enterShowDesktopMode(); + } +} + +bool PluginAdapter::InShowDesktop() const +{ + return _in_show_desktop; +} + +void PluginAdapter::OnShowDesktop() +{ + LOG_DEBUG(logger) << "Now in show desktop mode."; + _in_show_desktop = true; +} + +void PluginAdapter::OnLeaveDesktop() +{ + LOG_DEBUG(logger) << "No longer in show desktop mode."; + _in_show_desktop = false; +} + +int PluginAdapter::GetWindowMonitor(Window window_id) const +{ + // FIXME, we should use window->outputDevice() but this is not UScreen friendly + nux::Geometry const& geo = GetWindowGeometry(window_id); + + if (!geo.IsNull()) + { + int x = geo.x + geo.width/2; + int y = geo.y + geo.height/2; + + return unity::UScreen::GetDefault()->GetMonitorAtPosition(x, y); + } + + return -1; +} + +nux::Geometry PluginAdapter::GetWindowGeometry(Window window_id) const +{ + nux::Geometry geo; + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + { + geo.x = window->borderRect().x(); + geo.y = window->borderRect().y(); + geo.width = window->borderRect().width(); + geo.height = window->borderRect().height(); + } + return geo; +} + +nux::Geometry PluginAdapter::GetWindowSavedGeometry(Window window_id) const +{ + nux::Geometry geo(0, 0, 1, 1); + CompWindow* window = m_Screen->findWindow(window_id); + if (window) + { + XWindowChanges &wc = window->saveWc(); + geo.x = wc.x; + geo.y = wc.y; + geo.width = wc.width; + geo.height = wc.height; + } + + return geo; +} + +nux::Geometry PluginAdapter::GetScreenGeometry() const +{ + nux::Geometry geo(0, 0, m_Screen->width(), m_Screen->height()); + return geo; +} + +nux::Geometry PluginAdapter::GetWorkAreaGeometry(Window window_id) const +{ + CompWindow* window = nullptr; + unsigned int output = 0; + + if (window_id) + { + window = m_Screen->findWindow(window_id); + if (window) + { + output = window->outputDevice(); + } + } + + if (window_id == 0 || !window) + { + output = m_Screen->currentOutputDev().id(); + } + + CompRect workarea = m_Screen->getWorkareaForOutput(output); + + return nux::Geometry(workarea.x(), workarea.y(), workarea.width(), workarea.height()); +} + +bool PluginAdapter::CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) const +{ + int intersect_types = CompWindowTypeNormalMask | CompWindowTypeDialogMask | + CompWindowTypeModalDialogMask | CompWindowTypeUtilMask; + + if (!window || + !(window->type() & intersect_types) || + !window->isMapped() || + !window->isViewable() || + window->state() & CompWindowStateHiddenMask) + return false; + + if (CompRegion(window->borderRect()).intersects(CompRect(region.x, region.y, region.width, region.height))) + return true; + + return false; +} + +void PluginAdapter::CheckWindowIntersections(nux::Geometry const& region, bool &active, bool &any) +{ + // prime to false so we can assume values later one + active = false; + any = false; + + CompWindowList window_list = m_Screen->windows(); + CompWindowList::iterator it; + CompWindow* window = NULL; + CompWindow* parent = NULL; + int type_dialogs = CompWindowTypeDialogMask | CompWindowTypeModalDialogMask + | CompWindowTypeUtilMask; + + + window = m_Screen->findWindow(m_Screen->activeWindow()); + + if (window && (window->type() & type_dialogs)) + parent = m_Screen->findWindow(window->transientFor()); + + if (CheckWindowIntersection(region, window) || CheckWindowIntersection(region, parent)) + { + any = true; + active = true; + } + else + { + for (it = window_list.begin(); it != window_list.end(); ++it) + { + if (CheckWindowIntersection(region, *it)) + { + any = true; + break; + } + } + } +} + +int PluginAdapter::WorkspaceCount() const +{ + return m_Screen->vpSize().width() * m_Screen->vpSize().height(); +} + +void PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) +{ + Display* display = m_Screen->dpy(); + Atom hints_atom = None; + MotifWmHints* data = NULL; + MotifWmHints* hints = NULL; + Atom type = None; + gint format; + gulong nitems; + gulong bytes_after; + + hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false); + + if (XGetWindowProperty(display, + xid, + hints_atom, 0, sizeof(MotifWmHints) / sizeof(long), + False, AnyPropertyType, &type, &format, &nitems, + &bytes_after, (guchar**)&data) != Success) + { + return; + } + + if (type != hints_atom || !data) + { + hints = new_hints; + } + else + { + hints = data; + + if (new_hints->flags & MWM_HINTS_FUNCTIONS) + { + hints->flags |= MWM_HINTS_FUNCTIONS; + hints->functions = new_hints->functions; + } + if (new_hints->flags & MWM_HINTS_DECORATIONS) + { + hints->flags |= MWM_HINTS_DECORATIONS; + hints->decorations = new_hints->decorations; + } + } + + XChangeProperty(display, + xid, + hints_atom, hints_atom, 32, PropModeReplace, + (guchar*)hints, sizeof(MotifWmHints) / sizeof(long)); + + if (data) + XFree(data); +} + +void PluginAdapter::Decorate(Window window_id) +{ + MotifWmHints hints = { 0 }; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = GDK_DECOR_ALL & ~(MWM_HINTS_UNDECORATED_UNITY); + + SetMwmWindowHints(window_id, &hints); +} + +void PluginAdapter::Undecorate(Window window_id) +{ + MotifWmHints hints = { 0 }; + + /* Set the high bit to indicate that we undecorated this + * window, when an application attempts to "undecorate" + * the window again, this bit will be cleared */ + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = MWM_HINTS_UNDECORATED_UNITY; + + SetMwmWindowHints(window_id, &hints); +} + +bool PluginAdapter::IsScreenGrabbed() const +{ + return m_Screen->grabbed(); +} + +bool PluginAdapter::IsViewPortSwitchStarted() const +{ + return _vp_switch_started; +} + +/* Returns true if the window was maximized */ +bool PluginAdapter::MaximizeIfBigEnough(CompWindow* window) const +{ + XClassHint classHint; + Status status; + std::string win_wmclass; + int num_monitor; + + int screen_width; + int screen_height; + float covering_part; + + if (!window) + return false; + + if ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE) + return false; + + if (window->type() != CompWindowTypeNormalMask + || (window->actions() & MAXIMIZABLE) != MAXIMIZABLE) + return false; + + status = XGetClassHint(m_Screen->dpy(), window->id(), &classHint); + if (status && classHint.res_class) + { + win_wmclass = classHint.res_class; + XFree(classHint.res_class); + + if (classHint.res_name) + XFree(classHint.res_name); + } + else + return false; + + num_monitor = window->outputDevice(); + CompOutput &o = m_Screen->outputDevs().at(num_monitor); + + screen_height = o.workArea().height(); + screen_width = o.workArea().width(); + + // See bug https://bugs.launchpad.net/unity/+bug/797808 + if (screen_height * screen_width > THRESHOLD_HEIGHT * THRESHOLD_WIDTH) + return false; + + // use server because the window won't show the real parameter as + // not mapped yet + const XSizeHints& hints = window->sizeHints(); + covering_part = (float)(window->serverWidth() * window->serverHeight()) / (float)(screen_width * screen_height); + if ((covering_part < _coverage_area_before_automaximize) || (covering_part > 1.0) || + (hints.flags & PMaxSize && (screen_width > hints.max_width || screen_height > hints.max_height))) + { + LOG_DEBUG(logger) << win_wmclass << " window size doesn't fit"; + return false; + } + + window->maximize(MAXIMIZE_STATE); + + return true; +} + +void PluginAdapter::ShowGrabHandles(CompWindow* window, bool use_timer) +{ + if (!_grab_show_action || !window) + return; + + CompOption::Vector argument(3); + argument[0].setName("root", CompOption::TypeInt); + argument[0].value().set((int) screen->root()); + argument[1].setName("window", CompOption::TypeInt); + argument[1].value().set((int) window->id()); + argument[2].setName("use-timer", CompOption::TypeBool); + argument[2].value().set(use_timer); + + /* Initiate the first available action with the arguments */ + _grab_show_action->initiate()(_grab_show_action, 0, argument); +} + +void PluginAdapter::HideGrabHandles(CompWindow* window) +{ + if (!_grab_hide_action || !window) + return; + + CompOption::Vector argument(2); + argument[0].setName("root", CompOption::TypeInt); + argument[0].value().set((int) screen->root()); + argument[1].setName("window", CompOption::TypeInt); + argument[1].value().set((int) window->id()); + + /* Initiate the first available action with the arguments */ + _grab_hide_action->initiate()(_grab_hide_action, 0, argument); +} + +void PluginAdapter::ToggleGrabHandles(CompWindow* window) +{ + if (!_grab_toggle_action || !window) + return; + + CompOption::Vector argument(2); + argument[0].setName("root", CompOption::TypeInt); + argument[0].value().set((int) screen->root()); + argument[1].setName("window", CompOption::TypeInt); + argument[1].value().set((int) window->id()); + + /* Initiate the first available action with the arguments */ + _grab_toggle_action->initiate()(_grab_toggle_action, 0, argument); +} + +void PluginAdapter::SetCoverageAreaBeforeAutomaximize(float area) +{ + _coverage_area_before_automaximize = area; +} + +bool PluginAdapter::SaveInputFocus() +{ + Window active = m_Screen->activeWindow (); + CompWindow* cw = m_Screen->findWindow (active); + + if (cw) + { + _last_focused_window = cw; + return true; + } + + return false; +} + +bool PluginAdapter::RestoreInputFocus() +{ + if (_last_focused_window) + { + _last_focused_window->moveInputFocusTo (); + _last_focused_window = NULL; + return true; + } + else + { + m_Screen->focusDefaultWindow (); + return false; + } + + return false; +} + +void PluginAdapter::MoveResizeWindow(Window window_id, nux::Geometry geometry) +{ + int w, h; + CompWindow* window = m_Screen->findWindow(window_id); + + if (!window) + return; + + if (window->constrainNewWindowSize(geometry.width, geometry.height, &w, &h)) + { + CompRect workarea = m_Screen->getWorkareaForOutput(window->outputDevice()); + int dx = geometry.x + w - workarea.right() + window->border().right; + int dy = geometry.y + h - workarea.bottom() + window->border().bottom; + + if (dx > 0) + geometry.x -= dx; + if (dy > 0) + geometry.y -= dy; + + geometry.SetWidth(w); + geometry.SetHeight(h); + } + + XWindowChanges xwc; + xwc.x = geometry.x; + xwc.y = geometry.y; + xwc.width = geometry.width; + xwc.height = geometry.height; + + if (window->mapNum()) + window->sendSyncRequest(); + + window->configureXWindow(CWX | CWY | CWWidth | CWHeight, &xwc); +} + +void PluginAdapter::OnWindowClosed(CompWindow *w) +{ + if (_last_focused_window == w) + _last_focused_window = NULL; +} + +void PluginAdapter::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper wrapper(builder); + wrapper.add(GetScreenGeometry()) + .add("workspace_count", WorkspaceCount()) + .add("active_window", GetActiveWindow()) + .add("screen_grabbed", IsScreenGrabbed()) + .add("scale_active", IsScaleActive()) + .add("scale_active_for_group", IsScaleActiveForGroup()) + .add("expo_active", IsExpoActive()) + .add("viewport_switch_running", IsViewPortSwitchStarted()) + .add("showdesktop_active", _in_show_desktop); +} + +std::string PluginAdapter::GetWindowName(Window window_id) const +{ + std::string name; + Atom visibleNameAtom; + + visibleNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_VISIBLE_NAME", 0); + name = GetUtf8Property(window_id, visibleNameAtom); + if (name.empty()) + { + Atom wmNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_NAME", 0); + name = GetUtf8Property(window_id, wmNameAtom); + } + + if (name.empty()) + name = GetTextProperty(window_id, XA_WM_NAME); + + return name; +} + +std::string PluginAdapter::GetUtf8Property(Window window_id, Atom atom) const +{ + Atom type; + int result, format; + unsigned long nItems, bytesAfter; + char *val; + std::string retval; + Atom utf8StringAtom; + + utf8StringAtom = XInternAtom(m_Screen->dpy(), "UTF8_STRING", 0); + result = XGetWindowProperty(m_Screen->dpy(), window_id, atom, 0L, 65536, False, + utf8StringAtom, &type, &format, &nItems, + &bytesAfter, reinterpret_cast(&val)); + + if (result != Success) + return retval; + + if (type == utf8StringAtom && format == 8 && val && nItems > 0) + { + retval = std::string(val, nItems); + } + if (val) + XFree(val); + + return retval; +} + +std::string PluginAdapter::GetTextProperty(Window window_id, Atom atom) const +{ + XTextProperty text; + std::string retval; + + text.nitems = 0; + if (XGetTextProperty(m_Screen->dpy(), window_id, &text, atom)) + { + if (text.value) + { + retval = std::string(reinterpret_cast(text.value), text.nitems); + XFree(text.value); + } + } + + return retval; +} + +} diff --git a/unity-shared/PluginAdapter.h b/unity-shared/PluginAdapter.h index 06ce7ef33..8f09bf3f7 100644 --- a/unity-shared/PluginAdapter.h +++ b/unity-shared/PluginAdapter.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2010 Canonical Ltd + * Copyright (C) 2010-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 @@ -17,16 +17,19 @@ * Authored by: Jason Smith */ -#ifndef PLUGINADAPTER_H -#define PLUGINADAPTER_H +#ifndef UNITYSHARED_PLUGINADAPTER_H +#define UNITYSHARED_PLUGINADAPTER_H /* Compiz */ #include #include -#include +#include -#include "WindowManager.h" +#include "XWindowManager.h" + +namespace unity +{ typedef struct { @@ -60,11 +63,12 @@ private: }; -class PluginAdapter : public sigc::trackable, public WindowManager +class PluginAdapter : public sigc::trackable, public XWindowManager { public: - static PluginAdapter* Default(); - + // You shouldn't get the PluginAdapter if you really want a WindowManager. + // The PluginAdapter::Default should really only be called from within unityshell plugin. + static PluginAdapter& Default(); static void Initialize(CompScreen* screen); nux::Property bias_active_to_viewport; @@ -113,54 +117,56 @@ public: void NotifyResized(CompWindow* window, int x, int y, int w, int h); void NotifyStateChange(CompWindow* window, unsigned int state, unsigned int last_state); void NotifyCompizEvent(const char* plugin, const char* event, CompOption::Vector& option); - void NotifyNewDecorationState(guint32 xid); + void NotifyNewDecorationState(Window xid); - guint32 GetActiveWindow() const; + Window GetActiveWindow() const; - void Decorate(guint32 xid); - void Undecorate(guint32 xid); + void Decorate(Window xid); + void Undecorate(Window xid); // WindowManager implementation - bool IsWindowMaximized(guint xid) const; - bool IsWindowDecorated(guint xid); - bool IsWindowOnCurrentDesktop(guint xid) const; - bool IsWindowObscured(guint xid) const; - bool IsWindowMapped(guint xid) const; - bool IsWindowVisible(guint32 xid) const; - bool IsWindowOnTop(guint32 xid) const; - bool IsWindowClosable(guint32 xid) const; - bool IsWindowMinimizable(guint32 xid) const; - bool IsWindowMaximizable(guint32 xid) const; - - void Restore(guint32 xid); - void RestoreAt(guint32 xid, int x, int y); - void Minimize(guint32 xid); - void Close(guint32 xid); - void Activate(guint32 xid); - void Raise(guint32 xid); - void Lower(guint32 xid); + bool IsWindowMaximized(Window window_id) const; + bool IsWindowDecorated(Window window_id) const; + bool IsWindowOnCurrentDesktop(Window window_id) const; + bool IsWindowObscured(Window window_id) const; + bool IsWindowMapped(Window window_id) const; + bool IsWindowVisible(Window window_id) const; + bool IsWindowOnTop(Window window_id) const; + bool IsWindowClosable(Window window_id) const; + bool IsWindowMinimizable(Window window_id) const; + bool IsWindowMaximizable(Window window_id) const; + + void Restore(Window window_id); + void RestoreAt(Window window_id, int x, int y); + void Minimize(Window window_id); + void Close(Window window_id); + void Activate(Window window_id); + void Raise(Window window_id); + void Lower(Window window_id); void ShowDesktop(); bool InShowDesktop() const; void SetWindowIconGeometry(Window window, nux::Geometry const& geo); - void FocusWindowGroup(std::vector windows, FocusVisibility, int monitor = -1, bool only_top_win = true); - bool ScaleWindowGroup(std::vector windows, int state, bool force); + void FocusWindowGroup(std::vector const& windows, + FocusVisibility, int monitor = -1, bool only_top_win = true); + bool ScaleWindowGroup(std::vector const& windows, + int state, bool force); bool IsScreenGrabbed() const; bool IsViewPortSwitchStarted() const; - unsigned long long GetWindowActiveNumber (guint32 xid) const; + unsigned long long GetWindowActiveNumber(Window window_id) const; bool MaximizeIfBigEnough(CompWindow* window) const; - int GetWindowMonitor(guint32 xid) const; - nux::Geometry GetWindowGeometry(guint32 xid) const; - nux::Geometry GetWindowSavedGeometry(guint32 xid) const; + int GetWindowMonitor(Window window_id) const; + nux::Geometry GetWindowGeometry(Window window_id) const; + nux::Geometry GetWindowSavedGeometry(Window window_id) const; nux::Geometry GetScreenGeometry() const; - nux::Geometry GetWorkAreaGeometry(guint32 xid = 0) const; - std::string GetWindowName(guint32 xid) const; + nux::Geometry GetWorkAreaGeometry(Window window_id = 0) const; + std::string GetWindowName(Window window_id) const; void CheckWindowIntersections(nux::Geometry const& region, bool &active, bool &any); @@ -168,10 +174,10 @@ public: void SetCoverageAreaBeforeAutomaximize(float area); - bool saveInputFocus (); - bool restoreInputFocus (); + bool SaveInputFocus(); + bool RestoreInputFocus(); - void MoveResizeWindow(guint32 xid, nux::Geometry geometry); + void MoveResizeWindow(Window window_id, nux::Geometry geometry); protected: PluginAdapter(CompScreen* screen); @@ -186,8 +192,8 @@ private: Window GetTopMostValidWindowInViewport() const; - std::string GetTextProperty(guint32 xid, Atom atom) const; - std::string GetUtf8Property(guint32 xid, Atom atom) const; + std::string GetTextProperty(Window xid, Atom atom) const; + std::string GetUtf8Property(Window xid, Atom atom) const; CompScreen* m_Screen; MultiActionList m_ExpoActionList; @@ -207,9 +213,9 @@ private: bool _in_show_desktop; CompWindow* _last_focused_window; - std::map _window_decoration_state; - - static PluginAdapter* _default; + std::map _window_decoration_state; }; +} + #endif diff --git a/unity-shared/PluginAdapterCompiz.cpp b/unity-shared/PluginAdapterCompiz.cpp deleted file mode 100644 index 23702bf7f..000000000 --- a/unity-shared/PluginAdapterCompiz.cpp +++ /dev/null @@ -1,1423 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2010 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 . - * - * Authored by: Jason Smith - */ - -#include -#include -#include "PluginAdapter.h" -#include "UScreen.h" - -#include -#include - -namespace -{ - -nux::logging::Logger logger("unity.plugin"); - -const int THRESHOLD_HEIGHT = 600; -const int THRESHOLD_WIDTH = 1024; - -} - -PluginAdapter* PluginAdapter::_default = 0; - -#define MAXIMIZABLE (CompWindowActionMaximizeHorzMask & CompWindowActionMaximizeVertMask & CompWindowActionResizeMask) - -#define MWM_HINTS_FUNCTIONS (1L << 0) -#define MWM_HINTS_DECORATIONS (1L << 1) -#define MWM_HINTS_UNDECORATED_UNITY 0x80 -#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" - -/* static */ -PluginAdapter* -PluginAdapter::Default() -{ - if (!_default) - return 0; - return _default; -} - -/* static */ -void -PluginAdapter::Initialize(CompScreen* screen) -{ - _default = new PluginAdapter(screen); -} - -PluginAdapter::PluginAdapter(CompScreen* screen) : - m_Screen(screen), - _in_show_desktop (false), - _last_focused_window(nullptr) -{ - _spread_state = false; - _spread_windows_state = false; - _expo_state = false; - _vp_switch_started = false; - - _grab_show_action = 0; - _grab_hide_action = 0; - _grab_toggle_action = 0; - _coverage_area_before_automaximize = 0.75; - bias_active_to_viewport = false; -} - -PluginAdapter::~PluginAdapter() -{ -} - -/* A No-op for now, but could be useful later */ -void -PluginAdapter::OnScreenGrabbed() -{ - compiz_screen_grabbed.emit(); - - if (!_spread_state && screen->grabExist("scale")) - { - _spread_state = true; - initiate_spread.emit(); - } - - if (!_expo_state && screen->grabExist("expo")) - { - _expo_state = true; - initiate_expo.emit(); - } -} - -void -PluginAdapter::OnScreenUngrabbed() -{ - if (_spread_state && !screen->grabExist("scale")) - { - _spread_state = false; - _spread_windows_state = false; - terminate_spread.emit(); - } - - if (_expo_state && !screen->grabExist("expo")) - { - _expo_state = false; - terminate_expo.emit(); - } - - compiz_screen_ungrabbed.emit(); -} - -void -PluginAdapter::NotifyResized(CompWindow* window, int x, int y, int w, int h) -{ - window_resized.emit(window->id()); -} - -void -PluginAdapter::NotifyMoved(CompWindow* window, int x, int y) -{ - window_moved.emit(window->id()); -} - -void -PluginAdapter::NotifyStateChange(CompWindow* window, unsigned int state, unsigned int last_state) -{ - if (!((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) - && ((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) - { - WindowManager::window_maximized.emit(window->id()); - } - else if (((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) - && !((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) - { - WindowManager::window_restored.emit(window->id()); - } -} - -void -PluginAdapter::NotifyNewDecorationState(guint32 xid) -{ - bool wasTracked = (_window_decoration_state.find (xid) != _window_decoration_state.end ()); - bool wasDecorated = false; - - if (wasTracked) - wasDecorated = _window_decoration_state[xid]; - - bool decorated = IsWindowDecorated (xid); - - if (decorated == wasDecorated) - return; - - if (decorated && (!wasDecorated || !wasTracked)) - WindowManager::window_decorated.emit(xid); - else if (wasDecorated || !wasTracked) - WindowManager::window_undecorated.emit(xid); -} - -void -PluginAdapter::Notify(CompWindow* window, CompWindowNotify notify) -{ - switch (notify) - { - case CompWindowNotifyMinimize: - window_minimized.emit(window->id()); - break; - case CompWindowNotifyUnminimize: - window_unminimized.emit(window->id()); - break; - case CompWindowNotifyShade: - window_shaded.emit(window->id()); - break; - case CompWindowNotifyUnshade: - window_unshaded.emit(window->id()); - break; - case CompWindowNotifyHide: - window_hidden.emit(window->id()); - break; - case CompWindowNotifyShow: - window_shown.emit(window->id()); - break; - case CompWindowNotifyMap: - WindowManager::window_mapped.emit(window->id()); - break; - case CompWindowNotifyUnmap: - WindowManager::window_unmapped.emit(window->id()); - break; - case CompWindowNotifyFocusChange: - WindowManager::window_focus_changed.emit(window->id()); - break; - default: - break; - } -} - -void -PluginAdapter::NotifyCompizEvent(const char* plugin, const char* event, CompOption::Vector& option) -{ - if (g_strcmp0(event, "start_viewport_switch") == 0) - { - _vp_switch_started = true; - compiz_screen_viewport_switch_started.emit(); - } - else if (g_strcmp0(event, "end_viewport_switch") == 0) - { - _vp_switch_started = false; - compiz_screen_viewport_switch_ended.emit(); - } - - compiz_event.emit(plugin, event, option); -} - -void -MultiActionList::AddNewAction(std::string const& name, CompAction* a, bool primary) -{ - actions_[name] = a; - - if (primary) - primary_action_ = a; -} - -void MultiActionList::RemoveAction(std::string const& name) -{ - actions_.erase(name); -} - -CompAction* MultiActionList::GetAction(std::string const& name) const -{ - auto it = actions_.find(name); - - if (it == actions_.end()) - return nullptr; - - return it->second; -} - -bool MultiActionList::HasPrimary() const -{ - return bool(primary_action_); -} - -void MultiActionList::Initiate(std::string const& name, CompOption::Vector const& extra_args, int state) const -{ - if (name.empty()) - return; - - CompAction* action = GetAction(name); - - if (!action) - return; - - CompOption::Vector argument(1); - argument[0].setName("root", CompOption::TypeInt); - argument[0].value().set((int) screen->root()); - - for (CompOption const& arg : extra_args) - argument.push_back(arg); - - /* Initiate the selected action with the arguments */ - action->initiate()(action, state, argument); -} - -void MultiActionList::InitiateAll(CompOption::Vector const& extra_args, int state) const -{ - if (actions_.empty()) - return; - - std::string action_name; - - if (primary_action_) - { - for (auto const& it : actions_) - { - if (it.second == primary_action_) - { - action_name = it.first; - break; - } - } - } - else - { - action_name = actions_.begin()->first; - } - - Initiate(action_name, extra_args, state); -} - -void MultiActionList::TerminateAll(CompOption::Vector const& extra_args) const -{ - if (actions_.empty()) - return; - - CompOption::Vector argument(1); - argument[0].setName("root", CompOption::TypeInt); - argument[0].value().set((int) screen->root()); - - for (CompOption const& a : extra_args) - argument.push_back(a); - - if (primary_action_) - { - primary_action_->terminate()(primary_action_, 0, argument); - return; - } - - for (auto const& it : actions_) - { - CompAction* action = it.second; - - if (action->state() & (CompAction::StateTermKey | - CompAction::StateTermButton | - CompAction::StateTermEdge | - CompAction::StateTermEdgeDnd)) - { - action->terminate()(action, 0, argument); - } - } -} - -unsigned long long -PluginAdapter::GetWindowActiveNumber (guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - - if (window) - { - // result is actually an unsigned int (32 bits) - unsigned long long result = window->activeNum (); - if (bias_active_to_viewport() && window->defaultViewport() == m_Screen->vp()) - result = result << 32; - - return result; - } - - return 0; -} - -void -PluginAdapter::SetExpoAction(MultiActionList& expo) -{ - m_ExpoActionList = expo; -} - -void -PluginAdapter::SetScaleAction(MultiActionList& scale) -{ - m_ScaleActionList = scale; -} - -std::string -PluginAdapter::MatchStringForXids(std::vector const& windows) -{ - std::string out_string = "any & ("; - - for (auto const& xid : windows) - out_string += "| xid=" + std::to_string(xid) + " "; - - out_string += ")"; - - return out_string; -} - -void -PluginAdapter::InitiateScale(std::string const& match, int state) -{ - CompOption::Vector argument(1); - argument[0].setName("match", CompOption::TypeMatch); - argument[0].value().set(CompMatch(match)); - - m_ScaleActionList.InitiateAll(argument, state); -} - -void -PluginAdapter::TerminateScale() -{ - m_ScaleActionList.TerminateAll(); -} - -bool -PluginAdapter::IsScaleActive() const -{ - return m_Screen->grabExist("scale"); -} - -bool -PluginAdapter::IsScaleActiveForGroup() const -{ - return _spread_windows_state && m_Screen->grabExist("scale"); -} - -bool -PluginAdapter::IsExpoActive() const -{ - return m_Screen->grabExist("expo"); -} - -bool -PluginAdapter::IsWallActive() const -{ - return m_Screen->grabExist("wall"); -} - -void PluginAdapter::InitiateExpo() -{ - m_ExpoActionList.InitiateAll(); -} - -void PluginAdapter::TerminateExpo() -{ - m_ExpoActionList.Initiate("exit_button"); -} - -// WindowManager implementation -guint32 -PluginAdapter::GetActiveWindow() const -{ - return m_Screen->activeWindow(); -} - -bool -PluginAdapter::IsWindowMaximized(guint xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - { - return ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE); - } - - return false; -} - -bool -PluginAdapter::IsWindowDecorated(guint32 xid) -{ - Display* display = m_Screen->dpy(); - Window win = xid; - Atom hints_atom = None; - MotifWmHints* hints = NULL; - Atom type = None; - gint format; - gulong nitems; - gulong bytes_after; - bool ret = true; - - hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false); - - if (XGetWindowProperty(display, win, hints_atom, 0, - sizeof(MotifWmHints) / sizeof(long), False, - hints_atom, &type, &format, &nitems, &bytes_after, - (guchar**)&hints) != Success) - return false; - - if (!hints) - return ret; - - /* Check for the presence of the high bit - * if present, it means that we undecorated - * this window, so don't mark it as undecorated */ - if (type == hints_atom && format != 0 && - hints->flags & MWM_HINTS_DECORATIONS) - { - /* Must have both bits set */ - _window_decoration_state[xid] = ret = - (hints->decorations & (MwmDecorAll | MwmDecorTitle)) || - (hints->decorations & MWM_HINTS_UNDECORATED_UNITY); - } - - XFree(hints); - return ret; -} - -bool -PluginAdapter::IsWindowOnCurrentDesktop(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - { - // we aren't checking window->onCurrentDesktop (), as the name implies, because that is broken - return (window->defaultViewport() == m_Screen->vp()); - } - - return false; -} - -bool -PluginAdapter::IsWindowObscured(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - - if (window) - { - if (window->inShowDesktopMode()) - return true; - - CompPoint window_vp = window->defaultViewport(); - nux::Geometry const& win_geo = GetWindowGeometry(window->id()); - // Check if any windows above this one are blocking it - for (CompWindow* sibling = window->next; sibling != NULL; sibling = sibling->next) - { - if (sibling->defaultViewport() == window_vp - && !sibling->minimized() - && sibling->isMapped() - && sibling->isViewable() - && (sibling->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE - && !GetWindowGeometry(sibling->id()).Intersect(win_geo).IsNull()) - { - return true; - } - } - } - - return false; -} - -bool -PluginAdapter::IsWindowMapped(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - return window->mapNum () > 0; - return true; -} - -bool -PluginAdapter::IsWindowVisible(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - return !(window->state() & CompWindowStateHiddenMask) && !window->inShowDesktopMode(); - - return false; -} - -bool -PluginAdapter::IsWindowOnTop(guint32 xid) const -{ - if (xid == GetTopMostValidWindowInViewport()) - return true; - - return false; -} - -Window PluginAdapter::GetTopMostValidWindowInViewport() const -{ - CompWindow* window; - CompPoint screen_vp = m_Screen->vp(); - std::vector const& our_xids = nux::XInputWindow::NativeHandleList(); - - auto const& windows = m_Screen->windows(); - for (auto it = windows.rbegin(); it != windows.rend(); ++it) - { - window = *it; - if (window->defaultViewport() == screen_vp && - window->isViewable() && window->isMapped() && - !window->minimized() && !window->inShowDesktopMode() && - !(window->state() & CompWindowStateAboveMask) && - !(window->type() & CompWindowTypeSplashMask) && - !(window->type() & CompWindowTypeDockMask) && - !window->overrideRedirect() && - std::find(our_xids.begin(), our_xids.end(), window->id()) == our_xids.end()) - { - return window->id(); - } - } - return 0; -} - -bool -PluginAdapter::IsWindowClosable(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - return (window->actions() & CompWindowActionCloseMask); - - return false; -} - -bool -PluginAdapter::IsWindowMinimizable(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - return (window->actions() & CompWindowActionMinimizeMask); - - return false; -} - -bool -PluginAdapter::IsWindowMaximizable(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - return (window->actions() & MAXIMIZABLE); - - return false; -} - -void -PluginAdapter::Restore(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - window->maximize(0); -} - -void -PluginAdapter::RestoreAt(guint32 xid, int x, int y) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window && (window->state() & MAXIMIZE_STATE)) - { - nux::Geometry new_geo(GetWindowSavedGeometry(xid)); - new_geo.x = x; - new_geo.y = y; - window->maximize(0); - MoveResizeWindow(xid, new_geo); - } -} - -void -PluginAdapter::Minimize(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window && (window->actions() & CompWindowActionMinimizeMask)) - window->minimize(); -} - -void -PluginAdapter::Close(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - window->close(CurrentTime); -} - -void -PluginAdapter::Activate(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - window->activate(); -} - -void -PluginAdapter::Raise(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - window->raise(); -} - -void -PluginAdapter::Lower(guint32 xid) -{ - Window win = xid; - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - window->lower(); -} - -void -PluginAdapter::FocusWindowGroup(std::vector window_ids, FocusVisibility focus_visibility, int monitor, bool only_top_win) -{ - CompPoint target_vp = m_Screen->vp(); - CompWindow* top_window = nullptr; - CompWindow* top_monitor_win = nullptr; - - bool any_on_current = false; - bool any_mapped = false; - bool any_mapped_on_current = false; - bool forced_unminimize = false; - - /* sort the list */ - CompWindowList windows; - for (auto win : m_Screen->clientList()) - { - Window id = win->id(); - if (std::find(window_ids.begin(), window_ids.end(), id) != window_ids.end()) - windows.push_back(win); - } - - /* filter based on workspace */ - for (CompWindow* &win : windows) - { - if (win->defaultViewport() == m_Screen->vp()) - { - any_on_current = true; - - if (!win->minimized()) - { - any_mapped_on_current = true; - } - } - - if (!win->minimized()) - { - any_mapped = true; - } - - if (any_on_current && any_mapped) - break; - } - - if (!any_on_current) - { - for (auto it = windows.rbegin(); it != windows.rend(); ++it) - { - CompWindow* win = *it; - if ((any_mapped && !win->minimized()) || !any_mapped) - { - target_vp = win->defaultViewport(); - break; - } - } - } - - for (CompWindow* &win : windows) - { - if (win->defaultViewport() == target_vp) - { - int win_monitor = GetWindowMonitor(win->id()); - - /* Any window which is actually unmapped is - * not going to be accessible by either switcher - * or scale, so unconditionally unminimize those - * windows when the launcher icon is activated */ - if ((focus_visibility == WindowManager::FocusVisibility::ForceUnminimizeOnCurrentDesktop && - target_vp == m_Screen->vp()) || - (focus_visibility == WindowManager::FocusVisibility::ForceUnminimizeInvisible && - win->mapNum() == 0)) - { - top_window = win; - forced_unminimize = true; - - if (monitor >= 0 && win_monitor == monitor) - top_monitor_win = win; - - if (!only_top_win) - { - bool is_mapped = (win->mapNum() != 0); - win->unminimize(); - - /* Initially minimized windows dont get raised */ - if (!is_mapped) - win->raise(); - } - } - else if ((any_mapped_on_current && !win->minimized()) || !any_mapped_on_current) - { - if (!forced_unminimize || target_vp == m_Screen->vp()) - { - top_window = win; - - if (monitor >= 0 && win_monitor == monitor) - top_monitor_win = win; - - if (!only_top_win) - win->raise(); - } - } - } - } - - if (monitor >= 0 && top_monitor_win) - top_window = top_monitor_win; - - if (top_window) - { - if (only_top_win) - { - if (forced_unminimize) - { - top_window->unminimize(); - } - - top_window->raise(); - } - - top_window->activate(); - } -} - -bool -PluginAdapter::ScaleWindowGroup(std::vector windows, int state, bool force) -{ - std::size_t num_windows = windows.size(); - if (num_windows > 1 || (force && num_windows)) - { - std::string const& match = MatchStringForXids(windows); - InitiateScale(match, state); - _spread_windows_state = true; - return true; - } - return false; -} - -void -PluginAdapter::SetWindowIconGeometry(Window window, nux::Geometry const& geo) -{ - long data[4]; - - data[0] = geo.x; - data[1] = geo.y; - data[2] = geo.width; - data[3] = geo.height; - - XChangeProperty(m_Screen->dpy(), window, Atoms::wmIconGeometry, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char*) data, 4); -} - -void -PluginAdapter::ShowDesktop() -{ - if (_in_show_desktop) - { - LOG_INFO(logger) << "Leaving show-desktop mode."; - m_Screen->leaveShowDesktopMode(NULL); - } - else - { - LOG_INFO(logger) << "Entering show-desktop mode."; - m_Screen->enterShowDesktopMode(); - } -} - -bool PluginAdapter::InShowDesktop() const -{ - return _in_show_desktop; -} - -void -PluginAdapter::OnShowDesktop() -{ - LOG_DEBUG(logger) << "Now in show desktop mode."; - _in_show_desktop = true; -} - -void -PluginAdapter::OnLeaveDesktop() -{ - LOG_DEBUG(logger) << "No longer in show desktop mode."; - _in_show_desktop = false; -} - -int -PluginAdapter::GetWindowMonitor(guint32 xid) const -{ - // FIXME, we should use window->outputDevice() but this is not UScreen friendly - nux::Geometry const& geo = GetWindowGeometry(xid); - - if (!geo.IsNull()) - { - int x = geo.x + geo.width/2; - int y = geo.y + geo.height/2; - - return unity::UScreen::GetDefault()->GetMonitorAtPosition(x, y); - } - - return -1; -} - -nux::Geometry -PluginAdapter::GetWindowGeometry(guint32 xid) const -{ - Window win = xid; - CompWindow* window; - nux::Geometry geo; - - window = m_Screen->findWindow(win); - if (window) - { - geo.x = window->borderRect().x(); - geo.y = window->borderRect().y(); - geo.width = window->borderRect().width(); - geo.height = window->borderRect().height(); - } - return geo; -} - -nux::Geometry -PluginAdapter::GetWindowSavedGeometry(guint32 xid) const -{ - Window win = xid; - nux::Geometry geo(0, 0, 1, 1); - CompWindow* window; - - window = m_Screen->findWindow(win); - if (window) - { - XWindowChanges &wc = window->saveWc(); - geo.x = wc.x; - geo.y = wc.y; - geo.width = wc.width; - geo.height = wc.height; - } - - return geo; -} - -nux::Geometry -PluginAdapter::GetScreenGeometry() const -{ - nux::Geometry geo; - - geo.x = 0; - geo.y = 0; - geo.width = m_Screen->width(); - geo.height = m_Screen->height(); - - return geo; -} - -nux::Geometry -PluginAdapter::GetWorkAreaGeometry(guint32 xid) const -{ - CompWindow* window = nullptr; - unsigned int output = 0; - - if (xid != 0) - { - Window win = xid; - - window = m_Screen->findWindow(win); - if (window) - { - output = window->outputDevice(); - } - } - - if (xid == 0 || !window) - { - output = m_Screen->currentOutputDev().id(); - } - - CompRect workarea = m_Screen->getWorkareaForOutput(output); - - return nux::Geometry(workarea.x(), workarea.y(), workarea.width(), workarea.height()); -} - -bool -PluginAdapter::CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) const -{ - int intersect_types = CompWindowTypeNormalMask | CompWindowTypeDialogMask | - CompWindowTypeModalDialogMask | CompWindowTypeUtilMask; - - if (!window || - !(window->type() & intersect_types) || - !window->isMapped() || - !window->isViewable() || - window->state() & CompWindowStateHiddenMask) - return false; - - if (CompRegion(window->borderRect()).intersects(CompRect(region.x, region.y, region.width, region.height))) - return true; - - return false; -} - -void -PluginAdapter::CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any) -{ - // prime to false so we can assume values later one - active = false; - any = false; - - CompWindowList window_list = m_Screen->windows(); - CompWindowList::iterator it; - CompWindow* window = NULL; - CompWindow* parent = NULL; - int type_dialogs = CompWindowTypeDialogMask | CompWindowTypeModalDialogMask - | CompWindowTypeUtilMask; - - - window = m_Screen->findWindow(m_Screen->activeWindow()); - - if (window && (window->type() & type_dialogs)) - parent = m_Screen->findWindow(window->transientFor()); - - if (CheckWindowIntersection(region, window) || CheckWindowIntersection(region, parent)) - { - any = true; - active = true; - } - else - { - for (it = window_list.begin(); it != window_list.end(); ++it) - { - if (CheckWindowIntersection(region, *it)) - { - any = true; - break; - } - } - } -} - -int -PluginAdapter::WorkspaceCount() const -{ - return m_Screen->vpSize().width() * m_Screen->vpSize().height(); -} - -void -PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) -{ - Display* display = m_Screen->dpy(); - Atom hints_atom = None; - MotifWmHints* data = NULL; - MotifWmHints* hints = NULL; - Atom type = None; - gint format; - gulong nitems; - gulong bytes_after; - - hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false); - - if (XGetWindowProperty(display, - xid, - hints_atom, 0, sizeof(MotifWmHints) / sizeof(long), - False, AnyPropertyType, &type, &format, &nitems, - &bytes_after, (guchar**)&data) != Success) - { - return; - } - - if (type != hints_atom || !data) - { - hints = new_hints; - } - else - { - hints = data; - - if (new_hints->flags & MWM_HINTS_FUNCTIONS) - { - hints->flags |= MWM_HINTS_FUNCTIONS; - hints->functions = new_hints->functions; - } - if (new_hints->flags & MWM_HINTS_DECORATIONS) - { - hints->flags |= MWM_HINTS_DECORATIONS; - hints->decorations = new_hints->decorations; - } - } - - XChangeProperty(display, - xid, - hints_atom, hints_atom, 32, PropModeReplace, - (guchar*)hints, sizeof(MotifWmHints) / sizeof(long)); - - if (data) - XFree(data); -} - -void -PluginAdapter::Decorate(guint32 xid) -{ - MotifWmHints hints = { 0 }; - - hints.flags = MWM_HINTS_DECORATIONS; - hints.decorations = GDK_DECOR_ALL & ~(MWM_HINTS_UNDECORATED_UNITY); - - SetMwmWindowHints(xid, &hints); -} - -void -PluginAdapter::Undecorate(guint32 xid) -{ - MotifWmHints hints = { 0 }; - - /* Set the high bit to indicate that we undecorated this - * window, when an application attempts to "undecorate" - * the window again, this bit will be cleared */ - hints.flags = MWM_HINTS_DECORATIONS; - hints.decorations = MWM_HINTS_UNDECORATED_UNITY; - - SetMwmWindowHints(xid, &hints); -} - -bool -PluginAdapter::IsScreenGrabbed() const -{ - return m_Screen->grabbed(); -} - -bool -PluginAdapter::IsViewPortSwitchStarted() const -{ - return _vp_switch_started; -} - -/* Returns true if the window was maximized */ -bool PluginAdapter::MaximizeIfBigEnough(CompWindow* window) const -{ - XClassHint classHint; - Status status; - std::string win_wmclass; - int num_monitor; - - int screen_width; - int screen_height; - float covering_part; - - if (!window) - return false; - - if ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE) - return false; - - if (window->type() != CompWindowTypeNormalMask - || (window->actions() & MAXIMIZABLE) != MAXIMIZABLE) - return false; - - status = XGetClassHint(m_Screen->dpy(), window->id(), &classHint); - if (status && classHint.res_class) - { - win_wmclass = classHint.res_class; - XFree(classHint.res_class); - - if (classHint.res_name) - XFree(classHint.res_name); - } - else - return false; - - num_monitor = window->outputDevice(); - CompOutput &o = m_Screen->outputDevs().at(num_monitor); - - screen_height = o.workArea().height(); - screen_width = o.workArea().width(); - - // See bug https://bugs.launchpad.net/unity/+bug/797808 - if (screen_height * screen_width > THRESHOLD_HEIGHT * THRESHOLD_WIDTH) - return false; - - // use server because the window won't show the real parameter as - // not mapped yet - const XSizeHints& hints = window->sizeHints(); - covering_part = (float)(window->serverWidth() * window->serverHeight()) / (float)(screen_width * screen_height); - if ((covering_part < _coverage_area_before_automaximize) || (covering_part > 1.0) || - (hints.flags & PMaxSize && (screen_width > hints.max_width || screen_height > hints.max_height))) - { - LOG_DEBUG(logger) << win_wmclass << " window size doesn't fit"; - return false; - } - - window->maximize(MAXIMIZE_STATE); - - return true; -} - -void -PluginAdapter::ShowGrabHandles(CompWindow* window, bool use_timer) -{ - if (!_grab_show_action || !window) - return; - - CompOption::Vector argument(3); - argument[0].setName("root", CompOption::TypeInt); - argument[0].value().set((int) screen->root()); - argument[1].setName("window", CompOption::TypeInt); - argument[1].value().set((int) window->id()); - argument[2].setName("use-timer", CompOption::TypeBool); - argument[2].value().set(use_timer); - - /* Initiate the first available action with the arguments */ - _grab_show_action->initiate()(_grab_show_action, 0, argument); -} - -void -PluginAdapter::HideGrabHandles(CompWindow* window) -{ - if (!_grab_hide_action || !window) - return; - - CompOption::Vector argument(2); - argument[0].setName("root", CompOption::TypeInt); - argument[0].value().set((int) screen->root()); - argument[1].setName("window", CompOption::TypeInt); - argument[1].value().set((int) window->id()); - - /* Initiate the first available action with the arguments */ - _grab_hide_action->initiate()(_grab_hide_action, 0, argument); -} - -void -PluginAdapter::ToggleGrabHandles(CompWindow* window) -{ - if (!_grab_toggle_action || !window) - return; - - CompOption::Vector argument(2); - argument[0].setName("root", CompOption::TypeInt); - argument[0].value().set((int) screen->root()); - argument[1].setName("window", CompOption::TypeInt); - argument[1].value().set((int) window->id()); - - /* Initiate the first available action with the arguments */ - _grab_toggle_action->initiate()(_grab_toggle_action, 0, argument); -} - -void -PluginAdapter::SetCoverageAreaBeforeAutomaximize(float area) -{ - _coverage_area_before_automaximize = area; -} - -bool -PluginAdapter::saveInputFocus() -{ - Window active = m_Screen->activeWindow (); - CompWindow* cw = m_Screen->findWindow (active); - - if (cw) - { - _last_focused_window = cw; - return true; - } - - return false; -} - -bool -PluginAdapter::restoreInputFocus() -{ - if (_last_focused_window) - { - _last_focused_window->moveInputFocusTo (); - _last_focused_window = NULL; - return true; - } - else - { - m_Screen->focusDefaultWindow (); - return false; - } - - return false; -} - -void -PluginAdapter::MoveResizeWindow(guint32 xid, nux::Geometry geometry) -{ - int w, h; - CompWindow* window = m_Screen->findWindow(xid); - - if (!window) - return; - - if (window->constrainNewWindowSize(geometry.width, geometry.height, &w, &h)) - { - CompRect workarea = m_Screen->getWorkareaForOutput(window->outputDevice()); - int dx = geometry.x + w - workarea.right() + window->border().right; - int dy = geometry.y + h - workarea.bottom() + window->border().bottom; - - if (dx > 0) - geometry.x -= dx; - if (dy > 0) - geometry.y -= dy; - - geometry.SetWidth(w); - geometry.SetHeight(h); - } - - XWindowChanges xwc; - xwc.x = geometry.x; - xwc.y = geometry.y; - xwc.width = geometry.width; - xwc.height = geometry.height; - - if (window->mapNum()) - window->sendSyncRequest(); - - window->configureXWindow(CWX | CWY | CWWidth | CWHeight, &xwc); -} - -void -PluginAdapter::OnWindowClosed(CompWindow *w) -{ - if (_last_focused_window == w) - _last_focused_window = NULL; -} - -void -PluginAdapter::AddProperties(GVariantBuilder* builder) -{ - unity::variant::BuilderWrapper wrapper(builder); - wrapper.add(GetScreenGeometry()) - .add("workspace_count", WorkspaceCount()) - .add("active_window", GetActiveWindow()) - .add("screen_grabbed", IsScreenGrabbed()) - .add("scale_active", IsScaleActive()) - .add("scale_active_for_group", IsScaleActiveForGroup()) - .add("expo_active", IsExpoActive()) - .add("viewport_switch_running", IsViewPortSwitchStarted()) - .add("showdesktop_active", _in_show_desktop); -} - -std::string -PluginAdapter::GetWindowName(guint32 xid) const -{ - std::string name; - Atom visibleNameAtom; - - visibleNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_VISIBLE_NAME", 0); - name = GetUtf8Property(xid, visibleNameAtom); - if (name.empty()) - { - Atom wmNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_NAME", 0); - name = GetUtf8Property(xid, wmNameAtom); - } - - if (name.empty()) - name = GetTextProperty(xid, XA_WM_NAME); - - return name; -} - -std::string -PluginAdapter::GetUtf8Property(guint32 xid, Atom atom) const -{ - Atom type; - int result, format; - unsigned long nItems, bytesAfter; - char *val; - std::string retval; - Atom utf8StringAtom; - - utf8StringAtom = XInternAtom(m_Screen->dpy(), "UTF8_STRING", 0); - result = XGetWindowProperty(m_Screen->dpy(), xid, atom, 0L, 65536, False, - utf8StringAtom, &type, &format, &nItems, - &bytesAfter, reinterpret_cast(&val)); - - if (result != Success) - return retval; - - if (type == utf8StringAtom && format == 8 && val && nItems > 0) - { - retval = std::string(val, nItems); - } - if (val) - XFree(val); - - return retval; -} - -std::string -PluginAdapter::GetTextProperty(guint32 id, Atom atom) const -{ - XTextProperty text; - std::string retval; - - text.nitems = 0; - if (XGetTextProperty(m_Screen->dpy(), id, &text, atom)) - { - if (text.value) - { - retval = std::string(reinterpret_cast(text.value), text.nitems); - XFree (text.value); - } - } - - return retval; -} diff --git a/unity-shared/PluginAdapterStandalone.cpp b/unity-shared/PluginAdapterStandalone.cpp deleted file mode 100644 index b457c57d6..000000000 --- a/unity-shared/PluginAdapterStandalone.cpp +++ /dev/null @@ -1,491 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2010 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 . - * - * Authored by: Jason Smith - */ - -#include -#include -#include "PluginAdapter.h" -#include "UScreen.h" - -#include -#include - -//FIXME!! Entirely stubs for now, unless we need this functionality at some point - -namespace -{ -nux::logging::Logger logger("unity.plugin"); -} - -PluginAdapter* PluginAdapter::_default = 0; - -/* static */ -PluginAdapter* -PluginAdapter::Default() -{ - if (!_default) - return 0; - return _default; -} - -/* static */ -void -PluginAdapter::Initialize(CompScreen* screen) -{ - _default = new PluginAdapter(screen); -} - -PluginAdapter::PluginAdapter(CompScreen* screen) - : m_Screen(screen) - , _expo_state(false) - , _in_show_desktop(false) - , _last_focused_window(nullptr) -{ -} - -PluginAdapter::~PluginAdapter() -{ -} - -/* A No-op for now, but could be useful later */ -void -PluginAdapter::OnScreenGrabbed() -{ -} - -void -PluginAdapter::OnScreenUngrabbed() -{ -} - -void -PluginAdapter::NotifyResized(CompWindow* window, int x, int y, int w, int h) -{ -} - -void -PluginAdapter::NotifyMoved(CompWindow* window, int x, int y) -{ -} - -void -PluginAdapter::NotifyStateChange(CompWindow* window, unsigned int state, unsigned int last_state) -{ -} - -void -PluginAdapter::NotifyNewDecorationState(guint32 xid) -{ -} - -void -PluginAdapter::Notify(CompWindow* window, CompWindowNotify notify) -{ -} - -void -PluginAdapter::NotifyCompizEvent(const char* plugin, const char* event, CompOption::Vector& option) -{ -} - -void -MultiActionList::AddNewAction(std::string const& n, CompAction* a, bool primary) -{ -} - -void -MultiActionList::RemoveAction(std::string const& n) -{ -} - -void -MultiActionList::InitiateAll(CompOption::Vector const& extraArgs, int state) const -{ -} - -void -MultiActionList::TerminateAll(CompOption::Vector const& extraArgs) const -{ -} - -bool -MultiActionList::HasPrimary() const -{ - return false; -} - -CompAction* -MultiActionList::GetAction(std::string const& name) const -{ - return nullptr; -} - - -unsigned long long -PluginAdapter::GetWindowActiveNumber (guint32 xid) const -{ - return 0; -} - -void -PluginAdapter::SetExpoAction(MultiActionList& expo) -{ -} - -void -PluginAdapter::SetScaleAction(MultiActionList& scale) -{ -} - -std::string -PluginAdapter::MatchStringForXids(std::vector const& windows) -{ - return ""; -} - -void -PluginAdapter::InitiateScale(std::string const& match, int state) -{ -} - -void -PluginAdapter::TerminateScale() -{ -} - -bool -PluginAdapter::IsScaleActive() const -{ - return false; -} - -bool -PluginAdapter::IsScaleActiveForGroup() const -{ - return false; -} - -bool -PluginAdapter::IsExpoActive() const -{ - return _expo_state; -} - -void -PluginAdapter::InitiateExpo() -{ - _expo_state = true; -} - -void -PluginAdapter::TerminateExpo() -{ - _expo_state = false; -} - -bool -PluginAdapter::IsWallActive() const -{ - return false; -} - -// WindowManager implementation -guint32 -PluginAdapter::GetActiveWindow() const -{ - return 0; -} - -bool -PluginAdapter::IsWindowMaximized(guint xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowDecorated(guint32 xid) -{ - return false; -} - -bool -PluginAdapter::IsWindowOnCurrentDesktop(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowObscured(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowMapped(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowVisible(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowOnTop(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowClosable(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowMinimizable(guint32 xid) const -{ - return false; -} - -bool -PluginAdapter::IsWindowMaximizable(guint32 xid) const -{ - return false; -} - -void -PluginAdapter::Restore(guint32 xid) -{ -} - -void -PluginAdapter::RestoreAt(guint32 xid, int x, int y) -{ -} - -void -PluginAdapter::Minimize(guint32 xid) -{ -} - -void -PluginAdapter::Close(guint32 xid) -{ -} - -void -PluginAdapter::Activate(guint32 xid) -{ -} - -void -PluginAdapter::Raise(guint32 xid) -{ -} - -void -PluginAdapter::Lower(guint32 xid) -{ -} - -void -PluginAdapter::FocusWindowGroup(std::vector window_ids, FocusVisibility focus_visibility, int monitor, bool only_top_win) -{ -} - -bool -PluginAdapter::ScaleWindowGroup(std::vector windows, int state, bool force) -{ - return false; -} - -void -PluginAdapter::SetWindowIconGeometry(Window window, nux::Geometry const& geo) -{ -} - -void -PluginAdapter::ShowDesktop() -{ - _in_show_desktop = !_in_show_desktop; -} - -bool PluginAdapter::InShowDesktop() const -{ - return _in_show_desktop; -} - -void -PluginAdapter::OnShowDesktop() -{ -} - -void -PluginAdapter::OnLeaveDesktop() -{ -} - -int -PluginAdapter::GetWindowMonitor(guint32 xid) const -{ - return -1; -} - -nux::Geometry -PluginAdapter::GetWindowGeometry(guint32 xid) const -{ - nux::Geometry geo(0, 0, 1, 1); - return geo; -} - -nux::Geometry -PluginAdapter::GetWindowSavedGeometry(guint32 xid) const -{ - nux::Geometry geo(0, 0, 1, 1); - return geo; -} - -nux::Geometry -PluginAdapter::GetScreenGeometry() const -{ - nux::Geometry geo(0, 0, 1, 1); - return geo; -} - -nux::Geometry -PluginAdapter::GetWorkAreaGeometry(guint32 xid) const -{ - nux::Geometry geo(0, 0, 1, 1); - return geo; -} - -bool -PluginAdapter::CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) const -{ - return false; -} - -void -PluginAdapter::CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any) -{ -} - -int -PluginAdapter::WorkspaceCount() const -{ - return 4; -} - -void -PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) -{ -} - -void -PluginAdapter::Decorate(guint32 xid) -{ -} - -void -PluginAdapter::Undecorate(guint32 xid) -{ -} - -bool -PluginAdapter::IsScreenGrabbed() const -{ - return false; -} - -bool -PluginAdapter::IsViewPortSwitchStarted() const -{ - return false; -} - -/* Returns true if the window was maximized */ -bool PluginAdapter::MaximizeIfBigEnough(CompWindow* window) const -{ - return true; -} - -void -PluginAdapter::ShowGrabHandles(CompWindow* window, bool use_timer) -{ -} - -void -PluginAdapter::HideGrabHandles(CompWindow* window) -{ -} - -void -PluginAdapter::ToggleGrabHandles(CompWindow* window) -{ -} - -void -PluginAdapter::SetCoverageAreaBeforeAutomaximize(float area) -{ -} - -bool -PluginAdapter::saveInputFocus() -{ - return false; -} - -bool -PluginAdapter::restoreInputFocus() -{ - return false; -} - -void -PluginAdapter::MoveResizeWindow(guint32 xid, nux::Geometry geometry) -{ -} - -void -PluginAdapter::OnWindowClosed(CompWindow *w) -{ -} - -void -PluginAdapter::AddProperties(GVariantBuilder* builder) -{ - unity::variant::BuilderWrapper wrapper(builder); - wrapper.add(GetScreenGeometry()) - .add("workspace_count", WorkspaceCount()) - .add("active_window", GetActiveWindow()) - .add("screen_grabbed", IsScreenGrabbed()) - .add("scale_active", IsScaleActive()) - .add("scale_active_for_group", IsScaleActiveForGroup()) - .add("expo_active", IsExpoActive()) - .add("viewport_switch_running", IsViewPortSwitchStarted()) - .add("showdesktop_active", _in_show_desktop); -} - -std::string -PluginAdapter::GetWindowName(guint32 xid) const -{ - return ""; -} diff --git a/unity-shared/StandaloneWindowManager.cpp b/unity-shared/StandaloneWindowManager.cpp new file mode 100644 index 000000000..bc3902c25 --- /dev/null +++ b/unity-shared/StandaloneWindowManager.cpp @@ -0,0 +1,274 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010-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 . + * + * Authored by: Jason Smith + * Tim Penhey + */ + +#include +#include +#include "StandaloneWindowManager.h" +#include "UScreen.h" + +#include +#include + +// Entirely stubs for now, unless we need this functionality at some point + +namespace unity +{ + +namespace +{ +nux::logging::Logger logger("unity.wm"); +} + +WindowManagerPtr create_window_manager() +{ + return WindowManagerPtr(new StandaloneWindowManager); +} + +StandaloneWindowManager::StandaloneWindowManager() + : expo_state_(false) + , in_show_desktop_(false) +{ +} + +Window StandaloneWindowManager::GetActiveWindow() const +{ + return 0; +} + +bool StandaloneWindowManager::IsWindowMaximized(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowDecorated(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowOnCurrentDesktop(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowObscured(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowMapped(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowVisible(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowOnTop(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowClosable(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowMinimizable(Window window_id) const +{ + return false; +} + +bool StandaloneWindowManager::IsWindowMaximizable(Window window_id) const +{ + return false; +} + +void StandaloneWindowManager::ShowDesktop() +{ + in_show_desktop_ = !in_show_desktop_; +} + +bool StandaloneWindowManager::InShowDesktop() const +{ + return in_show_desktop_; +} + +void StandaloneWindowManager::Restore(Window window_id) +{} + +void StandaloneWindowManager::RestoreAt(Window window_id, int x, int y) +{} + +void StandaloneWindowManager::Minimize(Window window_id) +{} + +void StandaloneWindowManager::Close(Window window_id) +{} + +void StandaloneWindowManager::Activate(Window window_id) +{} + +void StandaloneWindowManager::Raise(Window window_id) +{} + +void StandaloneWindowManager::Lower(Window window_id) +{} + +void StandaloneWindowManager::TerminateScale() +{} + +bool StandaloneWindowManager::IsScaleActive() const +{ + return false; +} + +bool StandaloneWindowManager::IsScaleActiveForGroup() const +{ + return false; +} + +void StandaloneWindowManager::InitiateExpo() +{ + expo_state_ = !expo_state_; +} + +void StandaloneWindowManager::TerminateExpo() +{ + expo_state_ = false; +} + +bool StandaloneWindowManager::IsExpoActive() const +{ + return expo_state_; +} + +bool StandaloneWindowManager::IsWallActive() const +{ + return false; +} + +void StandaloneWindowManager::FocusWindowGroup(std::vector const& windows, + FocusVisibility, + int monitor, + bool only_top_win) +{} + +bool StandaloneWindowManager::ScaleWindowGroup(std::vector const& windows, + int state, bool force) +{ + return false; +} + +bool StandaloneWindowManager::IsScreenGrabbed() const +{ + return false; +} + +bool StandaloneWindowManager::IsViewPortSwitchStarted() const +{ + return false; +} + +void StandaloneWindowManager::MoveResizeWindow(Window window_id, nux::Geometry geometry) +{} + +void StandaloneWindowManager::StartMove(Window window_id, int x, int y) +{} + +int StandaloneWindowManager::GetWindowMonitor(Window window_id) const +{ + return -1; +} + +nux::Geometry StandaloneWindowManager::GetWindowGeometry(Window window_id) const +{ + nux::Geometry geo(0, 0, 1, 1); + return geo; +} + +nux::Geometry StandaloneWindowManager::GetWindowSavedGeometry(Window window_id) const +{ + nux::Geometry geo(0, 0, 1, 1); + return geo; +} + +nux::Geometry StandaloneWindowManager::GetScreenGeometry() const +{ + nux::Geometry geo(0, 0, 1, 1); + return geo; +} + +nux::Geometry StandaloneWindowManager::GetWorkAreaGeometry(Window window_id) const +{ + nux::Geometry geo(0, 0, 1, 1); + return geo; +} + +unsigned long long StandaloneWindowManager::GetWindowActiveNumber(Window window_id) const +{ + return 0; +} + +void StandaloneWindowManager::SetWindowIconGeometry(Window window, nux::Geometry const& geo) +{ +} + +void StandaloneWindowManager::CheckWindowIntersections(nux::Geometry const& region, + bool &active, bool &any) +{ +} + +int StandaloneWindowManager::WorkspaceCount() const +{ + return 4; +} + +bool StandaloneWindowManager::SaveInputFocus() +{ + return false; +} + +bool StandaloneWindowManager::RestoreInputFocus() +{ + return false; +} + +std::string StandaloneWindowManager::GetWindowName(Window window_id) const +{ + return ""; +} + +void StandaloneWindowManager::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper wrapper(builder); + wrapper.add(GetScreenGeometry()) + .add("workspace_count", WorkspaceCount()) + .add("active_window", GetActiveWindow()) + .add("screen_grabbed", IsScreenGrabbed()) + .add("scale_active", IsScaleActive()) + .add("scale_active_for_group", IsScaleActiveForGroup()) + .add("expo_active", IsExpoActive()) + .add("viewport_switch_running", IsViewPortSwitchStarted()) + .add("showdesktop_active", in_show_desktop_); +} + +} // namespace unity diff --git a/unity-shared/StandaloneWindowManager.h b/unity-shared/StandaloneWindowManager.h new file mode 100644 index 000000000..636e3c580 --- /dev/null +++ b/unity-shared/StandaloneWindowManager.h @@ -0,0 +1,108 @@ +// -*- 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 . + * + * Authored by: Tim Penhey + */ + +#ifndef UNITYSHARED_STANDALONE_WINDOW_MANAGER_H +#define UNITYSHARED_STANDALONE_WINDOW_MANAGER_H + +#include "unity-shared/WindowManager.h" + +namespace unity +{ + +class StandaloneWindowManager : public WindowManager +{ +public: + StandaloneWindowManager(); + + virtual Window GetActiveWindow() const; + + virtual bool IsWindowMaximized(Window window_id) const; + virtual bool IsWindowDecorated(Window window_id) const; + virtual bool IsWindowOnCurrentDesktop(Window window_id) const; + virtual bool IsWindowObscured(Window window_id) const; + virtual bool IsWindowMapped(Window window_id) const; + virtual bool IsWindowVisible(Window window_id) const; + virtual bool IsWindowOnTop(Window window_id) const; + virtual bool IsWindowClosable(Window window_id) const; + virtual bool IsWindowMinimizable(Window window_id) const; + virtual bool IsWindowMaximizable(Window window_id) const; + + virtual void ShowDesktop(); + virtual bool InShowDesktop() const; + + virtual void Restore(Window window_id); + virtual void RestoreAt(Window window_id, int x, int y); + virtual void Minimize(Window window_id); + virtual void Close(Window window_id); + + virtual void Activate(Window window_id); + virtual void Raise(Window window_id); + virtual void Lower(Window window_id); + + virtual void TerminateScale(); + virtual bool IsScaleActive() const; + virtual bool IsScaleActiveForGroup() const; + + virtual void InitiateExpo(); + virtual void TerminateExpo(); + virtual bool IsExpoActive() const; + + virtual bool IsWallActive() const; + + virtual void FocusWindowGroup(std::vector const& windows, + FocusVisibility, int monitor = -1, bool only_top_win = true); + virtual bool ScaleWindowGroup(std::vector const& windows, + int state, bool force); + + virtual bool IsScreenGrabbed() const; + virtual bool IsViewPortSwitchStarted() const; + + virtual void MoveResizeWindow(Window window_id, nux::Geometry geometry); + virtual void StartMove(Window window_id, int x, int y); + + virtual int GetWindowMonitor(Window window_id) const; + virtual nux::Geometry GetWindowGeometry(Window window_id) const; + virtual nux::Geometry GetWindowSavedGeometry(Window window_id) const; + virtual nux::Geometry GetScreenGeometry() const; + virtual nux::Geometry GetWorkAreaGeometry(Window window_id) const; + + virtual unsigned long long GetWindowActiveNumber(Window window_id) const; + + virtual void SetWindowIconGeometry(Window window, nux::Geometry const& geo); + + virtual void CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any); + + virtual int WorkspaceCount() const; + + virtual bool SaveInputFocus(); + virtual bool RestoreInputFocus(); + + virtual std::string GetWindowName(Window window_id) const; + +protected: + virtual void AddProperties(GVariantBuilder* builder); + +private: + bool expo_state_; + bool in_show_desktop_; +}; + +} + +#endif // UNITYSHARED_WINDOW_MANAGER_H diff --git a/unity-shared/StaticCairoText.cpp b/unity-shared/StaticCairoText.cpp index 33cea145c..6a036f65f 100644 --- a/unity-shared/StaticCairoText.cpp +++ b/unity-shared/StaticCairoText.cpp @@ -32,10 +32,6 @@ #include #include -#if defined(NUX_OS_LINUX) -#include -#endif - #include #include "CairoTexture.h" diff --git a/unity-shared/WindowManager.cpp b/unity-shared/WindowManager.cpp index dc09eeeff..a0bdc3f1a 100644 --- a/unity-shared/WindowManager.cpp +++ b/unity-shared/WindowManager.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2010 Canonical Ltd + * Copyright (C) 2010-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 @@ -17,269 +17,16 @@ * Authored by: Neil Jagdish Patel */ -#include "WindowManager.h" +#include "XWindowManager.h" -static WindowManager* window_manager = NULL; -class WindowManagerDummy : public WindowManager +unity::XWindowManager::XWindowManager() + : move_resize_atom_(XInternAtom(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + "_NET_WM_MOVERESIZE", FALSE)) { - guint32 GetActiveWindow() const - { - return 0; - } - - unsigned long long GetWindowActiveNumber (guint32 xid) const - { - return 0; - } - - bool IsScreenGrabbed() const - { - return false; - } - - bool IsViewPortSwitchStarted() const - { - return false; - } - - void ShowDesktop() - { - g_debug("%s", G_STRFUNC); - } - - bool InShowDesktop() const - { - return false; - } - - bool IsWindowMaximized(guint32 xid) const - { - return false; - } - - bool IsWindowDecorated(guint32 xid) - { - return true; - } - - bool IsWindowOnCurrentDesktop(guint32 xid) const - { - return true; - } - - bool IsWindowObscured(guint32 xid) const - { - return false; - } - - bool IsWindowMapped(guint32 xid) const - { - return true; - } - - bool IsWindowVisible(guint32 xid) const - { - return true; - } - - bool IsWindowOnTop(guint32 xid) const - { - return false; - } - - bool IsWindowClosable(guint32 xid) const - { - return true; - } - - bool IsWindowMinimizable(guint32 xid) const - { - return true; - } - - bool IsWindowMaximizable(guint32 xid) const - { - return true; - } - - void Restore(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void RestoreAt(guint32 xid, int x, int y) - { - g_debug("%s", G_STRFUNC); - } - - void Minimize(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void Close(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void Activate(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void Raise(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void Lower(guint32 xid) - { - g_debug("%s", G_STRFUNC); - } - - void FocusWindowGroup(std::vector windows, FocusVisibility, int monitor, bool only_top_win) - { - g_debug("%s", G_STRFUNC); - } - - bool ScaleWindowGroup(std::vector windows, int state, bool force) - { - g_debug("%s", G_STRFUNC); - return false; - } - - int GetWindowMonitor(guint32 xid) const - { - return -1; - } - - nux::Geometry GetWindowGeometry(guint xid) const - { - int width = (guint32)xid >> 16; - int height = (guint32)xid & 0x0000FFFF; - return nux::Geometry(0, 0, width, height); - } - - nux::Geometry GetWindowSavedGeometry(guint xid) const - { - return nux::Geometry(0, 0, 1, 1); - } - - nux::Geometry GetScreenGeometry() const - { - return nux::Geometry(0, 0, 1, 1); - } - - nux::Geometry GetWorkAreaGeometry(guint32 xid) const - { - return nux::Geometry(0, 0, 1, 1); - } - - void SetWindowIconGeometry(Window window, nux::Geometry const& geo) - { - g_debug("%s", G_STRFUNC); - } - - void CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any) - { - active = false; - any = false; - } - - int WorkspaceCount () const - { - return 1; - } - - void TerminateScale() - { - g_debug("%s", G_STRFUNC); - } - - bool IsScaleActive() const - { - g_debug("%s", G_STRFUNC); - return false; - } - - bool IsScaleActiveForGroup() const - { - g_debug("%s", G_STRFUNC); - return false; - } - - void InitiateExpo() - { - g_debug("%s", G_STRFUNC); - } - - void TerminateExpo() - { - g_debug("%s", G_STRFUNC); - } - - bool IsExpoActive() const - { - g_debug("%s", G_STRFUNC); - return false; - } - - bool IsWallActive() const - { - g_debug("%s", G_STRFUNC); - return false; - } - - void MoveResizeWindow(guint32 xid, nux::Geometry geometry) - { - g_debug("%s", G_STRFUNC); - } - - bool saveInputFocus() - { - return false; - } - - bool restoreInputFocus() - { - return false; - } - - - void AddProperties(GVariantBuilder* builder) - { - } - - std::string GetWindowName(guint32 xid) const - { - return "unknown"; - } -}; - -WindowManager* -WindowManager::Default() -{ - if (!window_manager) - window_manager = new WindowManagerDummy(); - - return window_manager; -} - -void -WindowManager::SetDefault(WindowManager* manager) -{ - window_manager = manager; -} - -std::string WindowManager::GetName() const -{ - return "WindowManager"; } -#define NET_WM_MOVERESIZE_MOVE 8 - -void WindowManager::StartMove(guint32 xid, int x, int y) +void unity::XWindowManager::StartMove(Window window_id, int x, int y) { if (x < 0 || y < 0) return; @@ -319,10 +66,12 @@ void WindowManager::StartMove(guint32 xid, int x, int y) ev.xclient.serial = 0; ev.xclient.send_event = true; - ev.xclient.window = xid; - ev.xclient.message_type = m_MoveResizeAtom; + ev.xclient.window = window_id; + ev.xclient.message_type = move_resize_atom_; ev.xclient.format = 32; + const long NET_WM_MOVERESIZE_MOVE = 8; + ev.xclient.data.l[0] = x; // x_root ev.xclient.data.l[1] = y; // y_root ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; //direction diff --git a/unity-shared/WindowManager.h b/unity-shared/WindowManager.h index f014cd19c..6c2f54bab 100644 --- a/unity-shared/WindowManager.h +++ b/unity-shared/WindowManager.h @@ -1,5 +1,6 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2010 Canonical Ltd + * Copyright (C) 2010-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 @@ -16,141 +17,29 @@ * Authored by: Neil Jagdish Patel */ -#ifndef WINDOW_MANAGER_H -#define WINDOW_MANAGER_H +#ifndef UNITYSHARED_XWINDOW_MANAGER_H +#define UNITYSHARED_XWINDOW_MANAGER_H #include #include #include -#include "unity-shared/Introspectable.h" +#include "unity-shared/WindowManager.h" -class WindowManager : public unity::debug::Introspectable +namespace unity { - // This is a glue interface that breaks the dependancy of Unity with Compiz - // Basically it has a default implementation that does nothing useful, but - // the idea is that unity.cpp uses SetDefault() early enough in it's - // initialization so the things that require it get a usable implementation +class XWindowManager : public WindowManager +{ public: - WindowManager() : - m_MoveResizeAtom(XInternAtom(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - "_NET_WM_MOVERESIZE", FALSE)) - { - }; - - enum class FocusVisibility - { - OnlyVisible, - ForceUnminimizeInvisible, - ForceUnminimizeOnCurrentDesktop - }; - - static WindowManager* Default(); - static void SetDefault(WindowManager* manager); - - virtual guint32 GetActiveWindow() const = 0; - - virtual bool IsWindowMaximized(guint32 xid) const = 0; - virtual bool IsWindowDecorated(guint32 xid) = 0; - virtual bool IsWindowOnCurrentDesktop(guint32 xid) const = 0; - virtual bool IsWindowObscured(guint32 xid) const = 0; - virtual bool IsWindowMapped(guint32 xid) const = 0; - virtual bool IsWindowVisible(guint32 xid) const = 0; - virtual bool IsWindowOnTop(guint32 xid) const = 0; - virtual bool IsWindowClosable(guint32 xid) const = 0; - virtual bool IsWindowMinimizable(guint32 xid) const = 0; - virtual bool IsWindowMaximizable(guint32 xid) const = 0; - - virtual void ShowDesktop() = 0; - virtual bool InShowDesktop() const = 0; - - virtual void Restore(guint32 xid) = 0; - virtual void RestoreAt(guint32 xid, int x, int y) = 0; - virtual void Minimize(guint32 xid) = 0; - virtual void Close(guint32 xid) = 0; - - virtual void Activate(guint32 xid) = 0; - virtual void Raise(guint32 xid) = 0; - virtual void Lower(guint32 xid) = 0; - - virtual void TerminateScale() = 0; - virtual bool IsScaleActive() const = 0; - virtual bool IsScaleActiveForGroup() const = 0; - - virtual void InitiateExpo() = 0; - virtual void TerminateExpo() = 0; - virtual bool IsExpoActive() const = 0; - - virtual bool IsWallActive() const = 0; - - virtual void FocusWindowGroup(std::vector windows, FocusVisibility, int monitor = -1, bool only_top_win = true) = 0; - virtual bool ScaleWindowGroup(std::vector windows, int state, bool force) = 0; - - virtual void Decorate(guint32 xid) {}; - virtual void Undecorate(guint32 xid) {}; - - virtual bool IsScreenGrabbed() const = 0; - virtual bool IsViewPortSwitchStarted() const = 0; + XWindowManager(); - virtual void MoveResizeWindow(guint32 xid, nux::Geometry geometry) = 0; - void StartMove(guint32 xid, int, int); - - virtual int GetWindowMonitor(guint32 xid) const = 0; - virtual nux::Geometry GetWindowGeometry(guint32 xid) const = 0; - virtual nux::Geometry GetWindowSavedGeometry(guint32 xid) const = 0; - virtual nux::Geometry GetScreenGeometry() const = 0; - virtual nux::Geometry GetWorkAreaGeometry(guint32 xid = 0) const = 0; - - virtual unsigned long long GetWindowActiveNumber(guint32 xid) const = 0; - - virtual void SetWindowIconGeometry(Window window, nux::Geometry const& geo) = 0; - - virtual void CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any) = 0; - - virtual int WorkspaceCount() const = 0; - - virtual bool saveInputFocus() = 0; - virtual bool restoreInputFocus() = 0; - - virtual std::string GetWindowName(guint32 xid) const = 0; - - // Signals - sigc::signal window_mapped; - sigc::signal window_unmapped; - sigc::signal window_maximized; - sigc::signal window_restored; - sigc::signal window_minimized; - sigc::signal window_unminimized; - sigc::signal window_shaded; - sigc::signal window_unshaded; - sigc::signal window_shown; - sigc::signal window_hidden; - sigc::signal window_resized; - sigc::signal window_moved; - sigc::signal window_focus_changed; - sigc::signal window_decorated; - sigc::signal window_undecorated; - - sigc::signal initiate_spread; - sigc::signal terminate_spread; - - sigc::signal initiate_expo; - sigc::signal terminate_expo; - - sigc::signal compiz_screen_grabbed; - sigc::signal compiz_screen_ungrabbed; - sigc::signal compiz_screen_viewport_switch_started; - sigc::signal compiz_screen_viewport_switch_ended; - - sigc::signal compiz_event; - -protected: - std::string GetName() const; - virtual void AddProperties(GVariantBuilder* builder) = 0; + virtual void StartMove(Window window_id, int x, int y); private: - Atom m_MoveResizeAtom; + Atom move_resize_atom_; }; +} + #endif // WINDOW_MANAGER_H -- cgit v1.2.3 From ded2645308b3720fe36f018f5b6c3dfbeff094aa Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Thu, 4 Oct 2012 20:18:20 +1300 Subject: name change (bzr r2791.4.2) --- unity-shared/WindowManager.cpp | 86 ----------------------------------------- unity-shared/WindowManager.h | 45 --------------------- unity-shared/XWindowManager.cpp | 86 +++++++++++++++++++++++++++++++++++++++++ unity-shared/XWindowManager.h | 45 +++++++++++++++++++++ 4 files changed, 131 insertions(+), 131 deletions(-) delete mode 100644 unity-shared/WindowManager.cpp delete mode 100644 unity-shared/WindowManager.h create mode 100644 unity-shared/XWindowManager.cpp create mode 100644 unity-shared/XWindowManager.h (limited to 'unity-shared') diff --git a/unity-shared/WindowManager.cpp b/unity-shared/WindowManager.cpp deleted file mode 100644 index a0bdc3f1a..000000000 --- a/unity-shared/WindowManager.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2010-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 . - * - * Authored by: Neil Jagdish Patel - */ - -#include "XWindowManager.h" - - -unity::XWindowManager::XWindowManager() - : move_resize_atom_(XInternAtom(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - "_NET_WM_MOVERESIZE", FALSE)) -{ -} - -void unity::XWindowManager::StartMove(Window window_id, int x, int y) -{ - if (x < 0 || y < 0) - return; - - XEvent ev; - Display* d = nux::GetGraphicsDisplay()->GetX11Display(); - - /* We first need to ungrab the pointer. FIXME: Evil */ - - XUngrabPointer(d, CurrentTime); - - // -------------------------------------------------------------------------- - // FIXME: This is a workaround until the non-paired events issue is fixed in - // nux - XButtonEvent bev = - { - ButtonRelease, - 0, - False, - d, - 0, - 0, - 0, - CurrentTime, - x, y, - x, y, - 0, - Button1, - True - }; - XEvent* e = (XEvent*)&bev; - nux::GetWindowThread()->ProcessForeignEvent(e, NULL); - - ev.xclient.type = ClientMessage; - ev.xclient.display = d; - - ev.xclient.serial = 0; - ev.xclient.send_event = true; - - ev.xclient.window = window_id; - ev.xclient.message_type = move_resize_atom_; - ev.xclient.format = 32; - - const long NET_WM_MOVERESIZE_MOVE = 8; - - ev.xclient.data.l[0] = x; // x_root - ev.xclient.data.l[1] = y; // y_root - ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; //direction - ev.xclient.data.l[3] = 1; // button - ev.xclient.data.l[4] = 2; // source - - XSendEvent(d, DefaultRootWindow(d), FALSE, - SubstructureRedirectMask | SubstructureNotifyMask, - &ev); - - XSync(d, FALSE); -} diff --git a/unity-shared/WindowManager.h b/unity-shared/WindowManager.h deleted file mode 100644 index 6c2f54bab..000000000 --- a/unity-shared/WindowManager.h +++ /dev/null @@ -1,45 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2010-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 . - * - * Authored by: Neil Jagdish Patel - */ - -#ifndef UNITYSHARED_XWINDOW_MANAGER_H -#define UNITYSHARED_XWINDOW_MANAGER_H - -#include -#include -#include - -#include "unity-shared/WindowManager.h" - -namespace unity -{ - -class XWindowManager : public WindowManager -{ -public: - XWindowManager(); - - virtual void StartMove(Window window_id, int x, int y); - -private: - Atom move_resize_atom_; -}; - -} - -#endif // WINDOW_MANAGER_H diff --git a/unity-shared/XWindowManager.cpp b/unity-shared/XWindowManager.cpp new file mode 100644 index 000000000..a0bdc3f1a --- /dev/null +++ b/unity-shared/XWindowManager.cpp @@ -0,0 +1,86 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010-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 . + * + * Authored by: Neil Jagdish Patel + */ + +#include "XWindowManager.h" + + +unity::XWindowManager::XWindowManager() + : move_resize_atom_(XInternAtom(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + "_NET_WM_MOVERESIZE", FALSE)) +{ +} + +void unity::XWindowManager::StartMove(Window window_id, int x, int y) +{ + if (x < 0 || y < 0) + return; + + XEvent ev; + Display* d = nux::GetGraphicsDisplay()->GetX11Display(); + + /* We first need to ungrab the pointer. FIXME: Evil */ + + XUngrabPointer(d, CurrentTime); + + // -------------------------------------------------------------------------- + // FIXME: This is a workaround until the non-paired events issue is fixed in + // nux + XButtonEvent bev = + { + ButtonRelease, + 0, + False, + d, + 0, + 0, + 0, + CurrentTime, + x, y, + x, y, + 0, + Button1, + True + }; + XEvent* e = (XEvent*)&bev; + nux::GetWindowThread()->ProcessForeignEvent(e, NULL); + + ev.xclient.type = ClientMessage; + ev.xclient.display = d; + + ev.xclient.serial = 0; + ev.xclient.send_event = true; + + ev.xclient.window = window_id; + ev.xclient.message_type = move_resize_atom_; + ev.xclient.format = 32; + + const long NET_WM_MOVERESIZE_MOVE = 8; + + ev.xclient.data.l[0] = x; // x_root + ev.xclient.data.l[1] = y; // y_root + ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; //direction + ev.xclient.data.l[3] = 1; // button + ev.xclient.data.l[4] = 2; // source + + XSendEvent(d, DefaultRootWindow(d), FALSE, + SubstructureRedirectMask | SubstructureNotifyMask, + &ev); + + XSync(d, FALSE); +} diff --git a/unity-shared/XWindowManager.h b/unity-shared/XWindowManager.h new file mode 100644 index 000000000..6c2f54bab --- /dev/null +++ b/unity-shared/XWindowManager.h @@ -0,0 +1,45 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010-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 . + * + * Authored by: Neil Jagdish Patel + */ + +#ifndef UNITYSHARED_XWINDOW_MANAGER_H +#define UNITYSHARED_XWINDOW_MANAGER_H + +#include +#include +#include + +#include "unity-shared/WindowManager.h" + +namespace unity +{ + +class XWindowManager : public WindowManager +{ +public: + XWindowManager(); + + virtual void StartMove(Window window_id, int x, int y); + +private: + Atom move_resize_atom_; +}; + +} + +#endif // WINDOW_MANAGER_H -- cgit v1.2.3 From 5dc4c5d2af7ad753d2569c2988d3a3fb9d89d40e Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Thu, 4 Oct 2012 20:19:08 +1300 Subject: New window manager files. (bzr r2791.4.3) --- unity-shared/WindowManager.cpp | 42 ++++++++++ unity-shared/WindowManager.h | 172 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 unity-shared/WindowManager.cpp create mode 100644 unity-shared/WindowManager.h (limited to 'unity-shared') diff --git a/unity-shared/WindowManager.cpp b/unity-shared/WindowManager.cpp new file mode 100644 index 000000000..4caa81406 --- /dev/null +++ b/unity-shared/WindowManager.cpp @@ -0,0 +1,42 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 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 . + * + * Authored by: Neil Jagdish Patel + */ + +#include "WindowManager.h" + +namespace unity +{ +namespace +{ +WindowManagerPtr window_manager; +} + +WindowManager& WindowManager::Default() +{ + if (!window_manager) + window_manager = create_window_manager(); + + return *window_manager; +} + +std::string WindowManager::GetName() const +{ + return "WindowManager"; +} + +} // namespace unity diff --git a/unity-shared/WindowManager.h b/unity-shared/WindowManager.h new file mode 100644 index 000000000..17186b424 --- /dev/null +++ b/unity-shared/WindowManager.h @@ -0,0 +1,172 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010-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 . + * + * Authored by: Neil Jagdish Patel + */ + +#ifndef UNITYSHARED_WINDOW_MANAGER_H +#define UNITYSHARED_WINDOW_MANAGER_H + +#include +#include +#include + +// To bring in nux::Geometry we first need the Rect header, then Utils. +#include +#include + +#ifdef UNITY_HAS_X_ORG_SUPPORT +#include +#else +typedef unsigned long Window; +#endif + +#include "unity-shared/Introspectable.h" + +namespace unity +{ +class WindowManager; +typedef std::shared_ptr WindowManagerPtr; + +// This function is used by the static Default method on the WindowManager +// class, and uses link time to make sure there is a function available. +WindowManagerPtr create_window_manager(); + +class WindowManager : public debug::Introspectable +{ + // This is a glue interface that breaks the dependancy of Unity with Compiz + // Basically it has a default implementation that does nothing useful, but + // the idea is that unity.cpp uses SetDefault() early enough in it's + // initialization so the things that require it get a usable implementation + +public: + virtual ~WindowManager() {} + + enum class FocusVisibility + { + OnlyVisible, + ForceUnminimizeInvisible, + ForceUnminimizeOnCurrentDesktop + }; + + static WindowManager& Default(); + + virtual Window GetActiveWindow() const = 0; + + virtual bool IsWindowMaximized(Window window_id) const = 0; + virtual bool IsWindowDecorated(Window window_id) const = 0; + virtual bool IsWindowOnCurrentDesktop(Window window_id) const = 0; + virtual bool IsWindowObscured(Window window_id) const = 0; + virtual bool IsWindowMapped(Window window_id) const = 0; + virtual bool IsWindowVisible(Window window_id) const = 0; + virtual bool IsWindowOnTop(Window window_id) const = 0; + virtual bool IsWindowClosable(Window window_id) const = 0; + virtual bool IsWindowMinimizable(Window window_id) const = 0; + virtual bool IsWindowMaximizable(Window window_id) const = 0; + + virtual void ShowDesktop() = 0; + virtual bool InShowDesktop() const = 0; + + virtual void Restore(Window window_id) = 0; + virtual void RestoreAt(Window window_id, int x, int y) = 0; + virtual void Minimize(Window window_id) = 0; + virtual void Close(Window window_id) = 0; + + virtual void Activate(Window window_id) = 0; + virtual void Raise(Window window_id) = 0; + virtual void Lower(Window window_id) = 0; + + virtual void TerminateScale() = 0; + virtual bool IsScaleActive() const = 0; + virtual bool IsScaleActiveForGroup() const = 0; + + virtual void InitiateExpo() = 0; + virtual void TerminateExpo() = 0; + virtual bool IsExpoActive() const = 0; + + virtual bool IsWallActive() const = 0; + + virtual void FocusWindowGroup(std::vector const& windows, + FocusVisibility, int monitor = -1, + bool only_top_win = true) = 0; + virtual bool ScaleWindowGroup(std::vector const& windows, + int state, bool force) = 0; + + virtual void Decorate(Window window_id) {}; + virtual void Undecorate(Window window_id) {}; + + virtual bool IsScreenGrabbed() const = 0; + virtual bool IsViewPortSwitchStarted() const = 0; + + virtual void MoveResizeWindow(Window window_id, nux::Geometry geometry) = 0; + virtual void StartMove(Window window_id, int x, int y) = 0; + + virtual int GetWindowMonitor(Window window_id) const = 0; + virtual nux::Geometry GetWindowGeometry(Window window_id) const = 0; + virtual nux::Geometry GetWindowSavedGeometry(Window window_id) const = 0; + virtual nux::Geometry GetScreenGeometry() const = 0; + virtual nux::Geometry GetWorkAreaGeometry(Window window_id = 0) const = 0; + + virtual unsigned long long GetWindowActiveNumber(Window window_id) const = 0; + + virtual void SetWindowIconGeometry(Window window, nux::Geometry const& geo) = 0; + + virtual void CheckWindowIntersections (nux::Geometry const& region, bool &active, bool &any) = 0; + + virtual int WorkspaceCount() const = 0; + + virtual bool SaveInputFocus() = 0; + virtual bool RestoreInputFocus() = 0; + + virtual std::string GetWindowName(Window window_id) const = 0; + + // Signals + sigc::signal window_mapped; + sigc::signal window_unmapped; + sigc::signal window_maximized; + sigc::signal window_restored; + sigc::signal window_minimized; + sigc::signal window_unminimized; + sigc::signal window_shaded; + sigc::signal window_unshaded; + sigc::signal window_shown; + sigc::signal window_hidden; + sigc::signal window_resized; + sigc::signal window_moved; + sigc::signal window_focus_changed; + sigc::signal window_decorated; + sigc::signal window_undecorated; + + sigc::signal initiate_spread; + sigc::signal terminate_spread; + + sigc::signal initiate_expo; + sigc::signal terminate_expo; + + sigc::signal screen_grabbed; + sigc::signal screen_ungrabbed; + sigc::signal screen_viewport_switch_started; + sigc::signal screen_viewport_switch_ended; + +protected: + std::string GetName() const; + virtual void AddProperties(GVariantBuilder* builder) = 0; + +}; + +} + +#endif // UNITYSHARED_WINDOW_MANAGER_H -- cgit v1.2.3 From 3ea9edabaaea62ecf009b215281b981f2b0f9553 Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Thu, 4 Oct 2012 20:36:35 +1300 Subject: Refactor the keyboard util functions. (bzr r2791.5.1) --- unity-shared/CMakeLists.txt | 2 +- unity-shared/KeyboardUtil.cpp | 249 ----------------------------------- unity-shared/KeyboardUtil.h | 62 --------- unity-shared/XKeyboardUtil.cpp | 288 +++++++++++++++++++++++++++++++++++++++++ unity-shared/XKeyboardUtil.h | 37 ++++++ 5 files changed, 326 insertions(+), 312 deletions(-) delete mode 100644 unity-shared/KeyboardUtil.cpp delete mode 100644 unity-shared/KeyboardUtil.h create mode 100644 unity-shared/XKeyboardUtil.cpp create mode 100644 unity-shared/XKeyboardUtil.h (limited to 'unity-shared') diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt index dbb4b28a8..6676fb759 100644 --- a/unity-shared/CMakeLists.txt +++ b/unity-shared/CMakeLists.txt @@ -35,7 +35,6 @@ set (UNITY_SHARED_SOURCES DashStyle.cpp DefaultThumbnailProvider.cpp FontSettings.cpp - KeyboardUtil.cpp IMTextEntry.cpp IconLoader.cpp IconRenderer.cpp @@ -64,6 +63,7 @@ set (UNITY_SHARED_SOURCES UnityWindowView.cpp UserThumbnailProvider.cpp WindowManager.cpp + XKeyboardUtil.cpp XWindowManager.cpp ubus-server.cpp ) diff --git a/unity-shared/KeyboardUtil.cpp b/unity-shared/KeyboardUtil.cpp deleted file mode 100644 index 90806d5e0..000000000 --- a/unity-shared/KeyboardUtil.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2011 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 . - * - * Authored by: Jason Smith - */ - -#include -#include -#include - -#include "KeyboardUtil.h" - -namespace unity { -namespace ui { -namespace { - const unsigned int FETCH_MASK = XkbGBN_KeyNamesMask | XkbGBN_ClientSymbolsMask | XkbGBN_GeometryMask; -} - -KeyboardUtil::KeyboardUtil(Display *display) - : display_(display) - , keyboard_(XkbGetKeyboard(display_, FETCH_MASK, XkbUseCoreKbd)) -{} - -KeyboardUtil::~KeyboardUtil() -{ - XkbFreeKeyboard(keyboard_, 0, True); -} - -bool KeyboardUtil::FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const -{ - // seems that Xkb does not give null terminated strings... was painful - int name_length = XkbKeyNameLength; - - int sections_in_geometry = geo->num_sections; - for (int i = 0; i < sections_in_geometry; i++) - { - XkbSectionPtr section = &geo->sections[i]; - - int rows_in_section = section->num_rows; - for (int j = 0; j < rows_in_section; j++) - { - XkbRowPtr row = §ion->rows[j]; - int keys_in_row = row->num_keys; - for (int k = 0; k < keys_in_row; k++) - { - XkbKeyPtr key = &row->keys[k]; - if (!strncmp (key->name.name, key_name, name_length)) - { - res_section = i; - res_bounds = GetAbsoluteKeyBounds(key, row, section, geo); - return true; - } - // end key - } - // end row - } - // end section - } - - return false; -} - -bool KeyboardUtil::CompareOffsets(int current_x, int current_y, int best_x, int best_y) const -{ - // never EVER prefer something higher on the keyboard than what we have - if (current_y > best_y) - return false; - - if (current_x < best_x || current_y < best_y) - return true; - - return false; -} - -guint KeyboardUtil::ConvertKeyToKeycode(XkbKeyPtr key) const -{ - if (!keyboard_) - return 0; - - int min_code = keyboard_->min_key_code; - int max_code = keyboard_->max_key_code; - - for (int i = min_code; i < max_code; i++) - { - if (!strncmp(key->name.name, keyboard_->names->keys[i].name, XkbKeyNameLength)) - return i; - } - - return 0; -} - -XkbBoundsRec KeyboardUtil::GetAbsoluteKeyBounds(XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const -{ - XkbShapePtr shape = XkbKeyShape(geo, key); - - XkbBoundsRec result; - result = shape->bounds; - - int x_offset = 0; - int y_offset = 0; - int i = 0; - while (&row->keys[i] != key) - { - XkbKeyPtr local_key = &row->keys[i]; - XkbShapePtr local_shape = XkbKeyShape(geo, local_key); - - if (row->vertical) - y_offset += local_shape->bounds.y2 - local_shape->bounds.y1; - else - x_offset += local_shape->bounds.x2 - local_shape->bounds.x1; - - i++; - } - - result.x1 += row->left + section->left + key->gap + x_offset; - result.x2 += row->left + section->left + key->gap + x_offset; - result.y1 += row->top + section->top + key->gap + y_offset; - result.y2 += row->top + section->top + key->gap + y_offset; - - return result; -} - -bool KeyboardUtil::FindKeyInSectionAboveBounds(XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, guint &keycode) const -{ - XkbKeyPtr best = NULL; - int best_x_offset = G_MAXINT; - int best_y_offset = G_MAXINT; - - int sections_in_geometry = geo->num_sections; - for (int k = 0; k < sections_in_geometry; k++) - { - - XkbSectionPtr section = &geo->sections[section_index]; - int rows_in_section = section->num_rows; - for (int i = 0; i < rows_in_section; i++) - { - XkbRowPtr row = §ion->rows[i]; - - int keys_in_row = row->num_keys; - for (int j = 0; j < keys_in_row; j++) - { - XkbKeyPtr key = &row->keys[j]; - XkbBoundsRec bounds = GetAbsoluteKeyBounds (key, row, section, geo); - - // make sure we are actually over the target bounds - int center = (bounds.x1 + bounds.x2) / 2; - if (center < target_bounds.x1 || center > target_bounds.x2) - continue; - - // make sure the key is actually above our target. - int current_y_offset = target_bounds.y1 - bounds.y2; - if (current_y_offset < 0) - continue; - - int current_x_offset = std::abs(center - (target_bounds.x1 + target_bounds.x2) / 2); - - if (CompareOffsets(current_x_offset, current_y_offset, best_x_offset, best_y_offset)) - { - best = key; - best_x_offset = current_x_offset; - best_y_offset = current_y_offset; - } - } - } - } - - if (best) - { - keycode = ConvertKeyToKeycode(best); - return true; - } - return false; -} - -guint KeyboardUtil::GetKeycodeAboveKeySymbol(KeySym key_symbol) const -{ - guint result = 0; - - int code = XKeysymToKeycode(display_, key_symbol); - - if (!code || !keyboard_) - return result; - - if (keyboard_->min_key_code > code || keyboard_->max_key_code < code) - return result; - - char* key_str = keyboard_->names->keys[code].name; - - - int key_section; - XkbBoundsRec key_bounds; - bool found_key = FindKeyInGeometry(keyboard_->geom, key_str, key_section, key_bounds); - - if (found_key) - { - guint maybe; - found_key = FindKeyInSectionAboveBounds(keyboard_->geom, key_section, key_bounds, maybe); - - if (found_key) - result = maybe; - } - - return result; -} - -bool KeyboardUtil::IsPrintableKeySymbol(KeySym sym) -{ - bool printable_key = false; - - if (sym == XK_Delete || sym == XK_BackSpace || sym == XK_Return) - { - printable_key = true; - } - else - { - unsigned int unicode = gdk_keyval_to_unicode(sym); - printable_key = g_unichar_isprint(unicode); - } - - return printable_key; -} - -bool KeyboardUtil::IsMoveKeySymbol(KeySym sym) -{ - bool move_key = false; - - if (sym >= XK_Home && sym <= XK_Begin) - { - move_key = true; - } - - return move_key; -} - -} -} \ No newline at end of file diff --git a/unity-shared/KeyboardUtil.h b/unity-shared/KeyboardUtil.h deleted file mode 100644 index b5ee98146..000000000 --- a/unity-shared/KeyboardUtil.h +++ /dev/null @@ -1,62 +0,0 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- -/* - * Copyright (C) 2011 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 . - * - * Authored by: Jason Smith - */ - -#ifndef KEYBOARDUTIL_H -#define KEYBOARDUTIL_H - -#include - -#include -#include -#include - -namespace unity -{ -namespace ui -{ - -class KeyboardUtil -{ -public: - KeyboardUtil(Display *display); - ~KeyboardUtil(); - - guint GetKeycodeAboveKeySymbol(KeySym key_symbol) const; - - static bool IsPrintableKeySymbol(KeySym key_symbol); - static bool IsMoveKeySymbol(KeySym sym); - -private: - bool CompareOffsets (int current_x, int current_y, int best_x, int best_y) const; - guint ConvertKeyToKeycode (XkbKeyPtr key) const; - - bool FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const; - bool FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section, XkbBoundsRec const& target_bounds, guint &keycode) const; - - XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const; - - Display *display_; - XkbDescPtr keyboard_; -}; - -} -} - -#endif // KEYBOARDUTIL_H - diff --git a/unity-shared/XKeyboardUtil.cpp b/unity-shared/XKeyboardUtil.cpp new file mode 100644 index 000000000..039eba3a8 --- /dev/null +++ b/unity-shared/XKeyboardUtil.cpp @@ -0,0 +1,288 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 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 . + * + * Authored by: Jason Smith + */ + +#include +#include +#include + +#include +#include +#include + +#include "KeyboardUtil.h" +#include "XKeyboardUtil.h" + +namespace unity +{ +namespace keyboard +{ +namespace +{ +const unsigned int FETCH_MASK = (XkbGBN_KeyNamesMask | + XkbGBN_ClientSymbolsMask | + XkbGBN_GeometryMask); + +class KeyboardUtil +{ +public: + KeyboardUtil(Display* display); + ~KeyboardUtil(); + + guint GetKeycodeAboveKeySymbol(KeySym key_symbol) const; + +private: + bool CompareOffsets (int current_x, int current_y, int best_x, int best_y) const; + guint ConvertKeyToKeycode (XkbKeyPtr key) const; + + bool FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const; + bool FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section, XkbBoundsRec const& target_bounds, guint &keycode) const; + + XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const; + + Display *display_; + XkbDescPtr keyboard_; +}; + + +KeyboardUtil::KeyboardUtil(Display* display) + : display_(display) + , keyboard_(XkbGetKeyboard(display_, FETCH_MASK, XkbUseCoreKbd)) +{} + +KeyboardUtil::~KeyboardUtil() +{ + XkbFreeKeyboard(keyboard_, 0, True); +} + +bool KeyboardUtil::FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const +{ + // seems that Xkb does not give null terminated strings... was painful + int name_length = XkbKeyNameLength; + + int sections_in_geometry = geo->num_sections; + for (int i = 0; i < sections_in_geometry; i++) + { + XkbSectionPtr section = &geo->sections[i]; + + int rows_in_section = section->num_rows; + for (int j = 0; j < rows_in_section; j++) + { + XkbRowPtr row = §ion->rows[j]; + int keys_in_row = row->num_keys; + for (int k = 0; k < keys_in_row; k++) + { + XkbKeyPtr key = &row->keys[k]; + if (!strncmp (key->name.name, key_name, name_length)) + { + res_section = i; + res_bounds = GetAbsoluteKeyBounds(key, row, section, geo); + return true; + } + // end key + } + // end row + } + // end section + } + + return false; +} + +bool KeyboardUtil::CompareOffsets(int current_x, int current_y, int best_x, int best_y) const +{ + // never EVER prefer something higher on the keyboard than what we have + if (current_y > best_y) + return false; + + if (current_x < best_x || current_y < best_y) + return true; + + return false; +} + +guint KeyboardUtil::ConvertKeyToKeycode(XkbKeyPtr key) const +{ + if (!keyboard_) + return 0; + + int min_code = keyboard_->min_key_code; + int max_code = keyboard_->max_key_code; + + for (int i = min_code; i < max_code; i++) + { + if (!strncmp(key->name.name, keyboard_->names->keys[i].name, XkbKeyNameLength)) + return i; + } + + return 0; +} + +XkbBoundsRec KeyboardUtil::GetAbsoluteKeyBounds(XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const +{ + XkbShapePtr shape = XkbKeyShape(geo, key); + + XkbBoundsRec result; + result = shape->bounds; + + int x_offset = 0; + int y_offset = 0; + int i = 0; + while (&row->keys[i] != key) + { + XkbKeyPtr local_key = &row->keys[i]; + XkbShapePtr local_shape = XkbKeyShape(geo, local_key); + + if (row->vertical) + y_offset += local_shape->bounds.y2 - local_shape->bounds.y1; + else + x_offset += local_shape->bounds.x2 - local_shape->bounds.x1; + + i++; + } + + result.x1 += row->left + section->left + key->gap + x_offset; + result.x2 += row->left + section->left + key->gap + x_offset; + result.y1 += row->top + section->top + key->gap + y_offset; + result.y2 += row->top + section->top + key->gap + y_offset; + + return result; +} + +bool KeyboardUtil::FindKeyInSectionAboveBounds(XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, guint &keycode) const +{ + XkbKeyPtr best = NULL; + int best_x_offset = G_MAXINT; + int best_y_offset = G_MAXINT; + + int sections_in_geometry = geo->num_sections; + for (int k = 0; k < sections_in_geometry; k++) + { + + XkbSectionPtr section = &geo->sections[section_index]; + int rows_in_section = section->num_rows; + for (int i = 0; i < rows_in_section; i++) + { + XkbRowPtr row = §ion->rows[i]; + + int keys_in_row = row->num_keys; + for (int j = 0; j < keys_in_row; j++) + { + XkbKeyPtr key = &row->keys[j]; + XkbBoundsRec bounds = GetAbsoluteKeyBounds (key, row, section, geo); + + // make sure we are actually over the target bounds + int center = (bounds.x1 + bounds.x2) / 2; + if (center < target_bounds.x1 || center > target_bounds.x2) + continue; + + // make sure the key is actually above our target. + int current_y_offset = target_bounds.y1 - bounds.y2; + if (current_y_offset < 0) + continue; + + int current_x_offset = std::abs(center - (target_bounds.x1 + target_bounds.x2) / 2); + + if (CompareOffsets(current_x_offset, current_y_offset, best_x_offset, best_y_offset)) + { + best = key; + best_x_offset = current_x_offset; + best_y_offset = current_y_offset; + } + } + } + } + + if (best) + { + keycode = ConvertKeyToKeycode(best); + return true; + } + return false; +} + +guint KeyboardUtil::GetKeycodeAboveKeySymbol(KeySym key_symbol) const +{ + guint result = 0; + + int code = XKeysymToKeycode(display_, key_symbol); + + if (!code || !keyboard_) + return result; + + if (keyboard_->min_key_code > code || keyboard_->max_key_code < code) + return result; + + char* key_str = keyboard_->names->keys[code].name; + + + int key_section; + XkbBoundsRec key_bounds; + bool found_key = FindKeyInGeometry(keyboard_->geom, key_str, key_section, key_bounds); + + if (found_key) + { + guint maybe; + found_key = FindKeyInSectionAboveBounds(keyboard_->geom, key_section, key_bounds, maybe); + + if (found_key) + result = maybe; + } + + return result; +} + + +} // anon namespace + + +bool is_printable_key_symbol(unsigned long key_symbol) +{ + bool printable_key = false; + + if (key_symbol == XK_Delete || + key_symbol == XK_BackSpace || + key_symbol == XK_Return) + { + printable_key = true; + } + else + { + unsigned int unicode = gdk_keyval_to_unicode(key_symbol); + printable_key = g_unichar_isprint(unicode); + } + + return printable_key; +} + +bool is_move_key_symbol(unsigned long key_symbol) +{ + return (key_symbol >= XK_Home && key_symbol <= XK_Begin); +} + +KeySym get_key_above_key_symbol(Display* display, KeySym key_symbol) +{ + KeyboardUtil util(display); + guint above_keycode = util.GetKeycodeAboveKeySymbol(key_symbol); + const unsigned int group_interest = 0; + const unsigned int shift_interest = 0; + return XkbKeycodeToKeysym(display, above_keycode, group_interest, shift_interest); +} + +} // namespace keyboard +} // namespace unity diff --git a/unity-shared/XKeyboardUtil.h b/unity-shared/XKeyboardUtil.h new file mode 100644 index 000000000..230bd834a --- /dev/null +++ b/unity-shared/XKeyboardUtil.h @@ -0,0 +1,37 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011-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 . + * + * Authored by: Jason Smith + */ + +#ifndef UNITYSHARED_XKEYBOARDUTIL_H +#define UNITYSHARED_XKEYBOARDUTIL_H + +#include + +namespace unity +{ +namespace keyboard +{ + +KeySym get_key_above_key_symbol(Display* display, KeySym key_symbol); + + +} +} + +#endif // UNITYSHARED_XKEYBOARDUTIL_H + -- cgit v1.2.3 From 2364d3844c9315be63454bc3ce299f041938e643 Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Thu, 4 Oct 2012 20:42:43 +1300 Subject: Keyboard functions. (bzr r2791.5.2) --- unity-shared/KeyboardUtil.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 unity-shared/KeyboardUtil.h (limited to 'unity-shared') diff --git a/unity-shared/KeyboardUtil.h b/unity-shared/KeyboardUtil.h new file mode 100644 index 000000000..d57ecc163 --- /dev/null +++ b/unity-shared/KeyboardUtil.h @@ -0,0 +1,35 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011-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 . + * + * Authored by: Tim Penhey + */ + +#ifndef UNITYSHARED_KEYBOARDUTIL_H +#define UNITYSHARED_KEYBOARDUTIL_H + +namespace unity +{ +namespace keyboard +{ + +bool is_printable_key_symbol(unsigned long key_symbol); +bool is_move_key_symbol(unsigned long key_symbol); + +} +} + +#endif // UNITYSHARED_KEYBOARDUTIL_H + -- cgit v1.2.3 From 29df63b4adc9eea52d7890e9618334f89c11b133 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 4 Oct 2012 14:05:43 +0100 Subject: Remove 'No Image Available' on all coverart texture loading. Fixes LP: #1057035 (bzr r2793.2.1) --- unity-shared/CoverArt.cpp | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'unity-shared') diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp index 5cc5e1788..840924efd 100644 --- a/unity-shared/CoverArt.cpp +++ b/unity-shared/CoverArt.cpp @@ -88,9 +88,7 @@ void CoverArt::AddProperties(GVariantBuilder* builder) void CoverArt::SetImage(std::string const& image_hint) { - spinner_timeout_.reset(); - frame_timeout_.reset(); - waiting_ = false; + StopWaiting(); if (slot_handle_ > 0) { @@ -98,8 +96,6 @@ void CoverArt::SetImage(std::string const& image_hint) slot_handle_ = 0; } - GIcon* icon = g_icon_new_for_string(image_hint.c_str(), NULL); - bool bLoadTexture = false; bLoadTexture |= g_strrstr(image_hint.c_str(), "://") != NULL; if (!bLoadTexture && !image_hint.empty()) @@ -115,10 +111,8 @@ void CoverArt::SetImage(std::string const& image_hint) } else if (!image_hint.empty()) { - if (GetLayout()) - GetLayout()->RemoveChildObject(overlay_text_); - - if (G_IS_ICON(icon)) + glib::Object icon(g_icon_new_for_string(image_hint.c_str(), NULL)); + if (G_IS_ICON(icon.RawPtr())) { StartWaiting(); slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, ICON_SIZE, ICON_SIZE, sigc::mem_fun(this, &CoverArt::IconLoaded)); @@ -133,9 +127,6 @@ void CoverArt::SetImage(std::string const& image_hint) { SetNoImageAvailable(); } - - if (icon != NULL) - g_object_unref(icon); } void CoverArt::GenerateImage(std::string const& uri) @@ -221,11 +212,13 @@ void CoverArt::IconLoaded(std::string const& texid, pixbuf_height = (pixbuf_height) ? pixbuf_height: 1; // no zeros please } + if (GetLayout()) + GetLayout()->RemoveChildObject(overlay_text_); + if (pixbuf_width == pixbuf_height) - { + { // quick path for square icons texture_screenshot_.Adopt(nux::CreateTexture2DFromPixbuf(pixbuf, true)); - QueueDraw(); } else { @@ -273,8 +266,8 @@ void CoverArt::IconLoaded(std::string const& texid, cairo_paint(cr); texture_screenshot_.Adopt(texture_from_cairo_graphics(cairo_graphics)); - QueueDraw(); } + QueueDraw(); } void CoverArt::TextureLoaded(std::string const& texid, @@ -291,6 +284,10 @@ void CoverArt::TextureLoaded(std::string const& texid, SetNoImageAvailable(); return; } + + if (GetLayout()) + GetLayout()->RemoveChildObject(overlay_text_); + texture_screenshot_.Adopt(nux::CreateTexture2DFromPixbuf(pixbuf, true)); QueueDraw(); } @@ -472,13 +469,7 @@ void CoverArt::OnThumbnailError(std::string const& error_hint) StopWaiting(); texture_screenshot_.Release(); - if (GetLayout()) - { - GetLayout()->RemoveChildObject(overlay_text_); - GetLayout()->AddView(overlay_text_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL, 100.0, nux::LayoutPosition(1)); - ComputeContentSize(); - } - QueueDraw(); + SetNoImageAvailable(); notifier_.Release(); } -- cgit v1.2.3 From 397da7ef88e54b57b642753e348859825d67ac7d Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 4 Oct 2012 14:31:03 +0100 Subject: Remove 'No Image Available' when starting wait in cover-art (bzr r2793.2.2) --- unity-shared/CoverArt.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'unity-shared') diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp index 840924efd..295591801 100644 --- a/unity-shared/CoverArt.cpp +++ b/unity-shared/CoverArt.cpp @@ -150,6 +150,8 @@ void CoverArt::StartWaiting() if (waiting_) return; + if (GetLayout()) + GetLayout()->RemoveChildObject(overlay_text_); waiting_ = true; rotate_matrix_.Rotate_z(0.0f); -- cgit v1.2.3 From 96f3dc47e31717fbfe2ba2246f1c975cf674b376 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 4 Oct 2012 15:02:25 +0100 Subject: Changed G_IS_ICON to glib::Object::IsType (bzr r2793.2.3) --- unity-shared/CoverArt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'unity-shared') diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp index 295591801..ae500f473 100644 --- a/unity-shared/CoverArt.cpp +++ b/unity-shared/CoverArt.cpp @@ -112,7 +112,7 @@ void CoverArt::SetImage(std::string const& image_hint) else if (!image_hint.empty()) { glib::Object icon(g_icon_new_for_string(image_hint.c_str(), NULL)); - if (G_IS_ICON(icon.RawPtr())) + if (icon.IsType(G_TYPE_ICON)) { StartWaiting(); slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, ICON_SIZE, ICON_SIZE, sigc::mem_fun(this, &CoverArt::IconLoaded)); -- cgit v1.2.3 From 22d87a562653695bb0e0ac06e4b65eba1097e460 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Thu, 4 Oct 2012 16:37:13 +0100 Subject: Increased cover-art timeout to 30 seconds. (bzr r2793.2.4) --- unity-shared/CoverArt.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'unity-shared') diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp index ae500f473..d45ca65e9 100644 --- a/unity-shared/CoverArt.cpp +++ b/unity-shared/CoverArt.cpp @@ -42,6 +42,7 @@ namespace nux::logging::Logger logger("unity.dash.previews.coverart"); const int ICON_SIZE = 256; +const int IMAGE_TIMEOUT = 30; } NUX_IMPLEMENT_OBJECT_TYPE(CoverArt); @@ -157,7 +158,7 @@ void CoverArt::StartWaiting() rotate_matrix_.Rotate_z(0.0f); rotation_ = 0.0f; - spinner_timeout_.reset(new glib::TimeoutSeconds(5, [&] + spinner_timeout_.reset(new glib::TimeoutSeconds(IMAGE_TIMEOUT, [&] { StopWaiting(); -- cgit v1.2.3 From f6ccf95dcb4d3e5f894ce9a1924b55bbe154be18 Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Fri, 5 Oct 2012 12:10:23 +1300 Subject: Make the decorate and undecorate methods const. (bzr r2791.4.4) --- unity-shared/PluginAdapter.cpp | 6 +++--- unity-shared/PluginAdapter.h | 4 ++-- unity-shared/WindowManager.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'unity-shared') diff --git a/unity-shared/PluginAdapter.cpp b/unity-shared/PluginAdapter.cpp index 8aa4c3723..a49a0a9b9 100644 --- a/unity-shared/PluginAdapter.cpp +++ b/unity-shared/PluginAdapter.cpp @@ -1006,7 +1006,7 @@ void PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) XFree(data); } -void PluginAdapter::Decorate(Window window_id) +void PluginAdapter::Decorate(Window window_id) const { MotifWmHints hints = { 0 }; @@ -1016,7 +1016,7 @@ void PluginAdapter::Decorate(Window window_id) SetMwmWindowHints(window_id, &hints); } -void PluginAdapter::Undecorate(Window window_id) +void PluginAdapter::Undecorate(Window window_id) const { MotifWmHints hints = { 0 }; @@ -1301,4 +1301,4 @@ std::string PluginAdapter::GetTextProperty(Window window_id, Atom atom) const return retval; } -} +} // namespace unity diff --git a/unity-shared/PluginAdapter.h b/unity-shared/PluginAdapter.h index 8f09bf3f7..c91855e63 100644 --- a/unity-shared/PluginAdapter.h +++ b/unity-shared/PluginAdapter.h @@ -121,8 +121,8 @@ public: Window GetActiveWindow() const; - void Decorate(Window xid); - void Undecorate(Window xid); + void Decorate(Window xid) const; + void Undecorate(Window xid) const; // WindowManager implementation bool IsWindowMaximized(Window window_id) const; diff --git a/unity-shared/WindowManager.h b/unity-shared/WindowManager.h index 17186b424..b9a7c7e42 100644 --- a/unity-shared/WindowManager.h +++ b/unity-shared/WindowManager.h @@ -105,8 +105,8 @@ public: virtual bool ScaleWindowGroup(std::vector const& windows, int state, bool force) = 0; - virtual void Decorate(Window window_id) {}; - virtual void Undecorate(Window window_id) {}; + virtual void Decorate(Window window_id) const {}; + virtual void Undecorate(Window window_id) const {}; virtual bool IsScreenGrabbed() const = 0; virtual bool IsViewPortSwitchStarted() const = 0; -- cgit v1.2.3 From 255b88389efc37b0b10a18573cde3b5f93aa45eb Mon Sep 17 00:00:00 2001 From: Tim Penhey Date: Fri, 5 Oct 2012 16:45:41 +1300 Subject: Make SetMwmWindowHints const too. (bzr r2791.4.6) --- unity-shared/PluginAdapter.cpp | 2 +- unity-shared/PluginAdapter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'unity-shared') diff --git a/unity-shared/PluginAdapter.cpp b/unity-shared/PluginAdapter.cpp index a49a0a9b9..f0cfbc4ef 100644 --- a/unity-shared/PluginAdapter.cpp +++ b/unity-shared/PluginAdapter.cpp @@ -955,7 +955,7 @@ int PluginAdapter::WorkspaceCount() const return m_Screen->vpSize().width() * m_Screen->vpSize().height(); } -void PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) +void PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) const { Display* display = m_Screen->dpy(); Atom hints_atom = None; diff --git a/unity-shared/PluginAdapter.h b/unity-shared/PluginAdapter.h index c91855e63..7a3e69a0c 100644 --- a/unity-shared/PluginAdapter.h +++ b/unity-shared/PluginAdapter.h @@ -188,7 +188,7 @@ private: void InitiateScale(std::string const& match, int state = 0); bool CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) const; - void SetMwmWindowHints(Window xid, MotifWmHints* new_hints); + void SetMwmWindowHints(Window xid, MotifWmHints* new_hints) const; Window GetTopMostValidWindowInViewport() const; -- cgit v1.2.3