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