diff --git a/CMakeLists.txt b/CMakeLists.txt index e386e88aa8..09c1a0022b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,7 @@ set(kwin_KDEINIT_SRCS cursor.cpp tabgroup.cpp focuschain.cpp + netinfo.cpp placement.cpp atoms.cpp utils.cpp diff --git a/activation.cpp b/activation.cpp index 19b962c20e..de27953d47 100644 --- a/activation.cpp +++ b/activation.cpp @@ -29,6 +29,7 @@ along with this program. If not, see . #include "client.h" #include "cursor.h" #include "focuschain.h" +#include "netinfo.h" #include "workspace.h" #ifdef KWIN_BUILD_ACTIVITIES #include "activities.h" diff --git a/client.h b/client.h index 36f57dd12a..43ca849c59 100644 --- a/client.h +++ b/client.h @@ -1012,26 +1012,6 @@ private: Client* cl; }; -/** - * NET WM Protocol handler class - */ -class WinInfo : public NETWinInfo2 -{ -private: - typedef KWin::Client Client; // Because of NET::Client - -public: - WinInfo(Client* c, Display * display, Window window, - Window rwin, const unsigned long pr[], int pr_size); - virtual void changeDesktop(int desktop); - virtual void changeFullscreenMonitors(NETFullscreenMonitors topology); - virtual void changeState(unsigned long state, unsigned long mask); - void disable(); - -private: - Client * m_client; -}; - inline Window Client::wrapperId() const { return wrapper; diff --git a/deleted.cpp b/deleted.cpp index a2840ba60c..ddec5ce800 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -22,6 +22,7 @@ along with this program. If not, see . #include "workspace.h" #include "client.h" +#include "netinfo.h" #include "paintredirector.h" #include "shadow.h" diff --git a/events.cpp b/events.cpp index 253fb01ba9..8f0a60dc96 100644 --- a/events.cpp +++ b/events.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . #include "cursor.h" #include "decorations.h" #include "focuschain.h" +#include "netinfo.h" #include "workspace.h" #include "atoms.h" #ifdef KWIN_BUILD_TABBOX @@ -65,163 +66,6 @@ namespace KWin extern int currentRefreshRate(); -// **************************************** -// WinInfo -// **************************************** - -WinInfo::WinInfo(Client * c, Display * display, Window window, - Window rwin, const unsigned long pr[], int pr_size) - : NETWinInfo2(display, window, rwin, pr, pr_size, NET::WindowManager), m_client(c) -{ -} - -void WinInfo::changeDesktop(int desktop) -{ - m_client->workspace()->sendClientToDesktop(m_client, desktop, true); -} - -void WinInfo::changeFullscreenMonitors(NETFullscreenMonitors topology) -{ - m_client->updateFullscreenMonitors(topology); -} - -void WinInfo::changeState(unsigned long state, unsigned long mask) -{ - mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore - mask &= ~NET::Hidden; // clients are not allowed to change this directly - state &= mask; // for safety, clear all other bits - - if ((mask & NET::FullScreen) != 0 && (state & NET::FullScreen) == 0) - m_client->setFullScreen(false, false); - if ((mask & NET::Max) == NET::Max) - m_client->setMaximize(state & NET::MaxVert, state & NET::MaxHoriz); - else if (mask & NET::MaxVert) - m_client->setMaximize(state & NET::MaxVert, m_client->maximizeMode() & Client::MaximizeHorizontal); - else if (mask & NET::MaxHoriz) - m_client->setMaximize(m_client->maximizeMode() & Client::MaximizeVertical, state & NET::MaxHoriz); - - if (mask & NET::Shaded) - m_client->setShade(state & NET::Shaded ? ShadeNormal : ShadeNone); - if (mask & NET::KeepAbove) - m_client->setKeepAbove((state & NET::KeepAbove) != 0); - if (mask & NET::KeepBelow) - m_client->setKeepBelow((state & NET::KeepBelow) != 0); - if (mask & NET::SkipTaskbar) - m_client->setSkipTaskbar((state & NET::SkipTaskbar) != 0, true); - if (mask & NET::SkipPager) - m_client->setSkipPager((state & NET::SkipPager) != 0); - if (mask & NET::DemandsAttention) - m_client->demandAttention((state & NET::DemandsAttention) != 0); - if (mask & NET::Modal) - m_client->setModal((state & NET::Modal) != 0); - // unsetting fullscreen first, setting it last (because e.g. maximize works only for !isFullScreen() ) - if ((mask & NET::FullScreen) != 0 && (state & NET::FullScreen) != 0) - m_client->setFullScreen(true, false); -} - -void WinInfo::disable() -{ - m_client = NULL; // only used when the object is passed to Deleted -} - -// **************************************** -// RootInfo -// **************************************** - -RootInfo::RootInfo(Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr) - : NETRootInfo(dpy, w, name, pr, pr_num, scr) -{ - workspace = ws; -} - -void RootInfo::changeNumberOfDesktops(int n) -{ - VirtualDesktopManager::self()->setCount(n); -} - -void RootInfo::changeCurrentDesktop(int d) -{ - VirtualDesktopManager::self()->setCurrent(d); -} - -void RootInfo::changeActiveWindow(Window w, NET::RequestSource src, Time timestamp, Window active_window) -{ - if (Client* c = workspace->findClient(WindowMatchPredicate(w))) { - if (timestamp == CurrentTime) - timestamp = c->userTime(); - if (src != NET::FromApplication && src != FromTool) - src = NET::FromTool; - if (src == NET::FromTool) - workspace->activateClient(c, true); // force - else if (c == workspace->mostRecentlyActivatedClient()) { - return; // WORKAROUND? With > 1 plasma activities, we cause this ourselves. bug #240673 - } else { // NET::FromApplication - Client* c2; - if (workspace->allowClientActivation(c, timestamp, false, true)) - workspace->activateClient(c); - // if activation of the requestor's window would be allowed, allow activation too - else if (active_window != None - && (c2 = workspace->findClient(WindowMatchPredicate(active_window))) != NULL - && workspace->allowClientActivation(c2, - timestampCompare(timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true)) { - workspace->activateClient(c); - } else - c->demandAttention(); - } - } -} - -void RootInfo::restackWindow(Window w, RequestSource src, Window above, int detail, Time timestamp) -{ - if (Client* c = workspace->findClient(WindowMatchPredicate(w))) { - if (timestamp == CurrentTime) - timestamp = c->userTime(); - if (src != NET::FromApplication && src != FromTool) - src = NET::FromTool; - c->restackWindow(above, detail, src, timestamp, true); - } -} - -void RootInfo::gotTakeActivity(Window w, Time timestamp, long flags) -{ - if (Client* c = workspace->findClient(WindowMatchPredicate(w))) - workspace->handleTakeActivity(c, timestamp, flags); -} - -void RootInfo::closeWindow(Window w) -{ - Client* c = workspace->findClient(WindowMatchPredicate(w)); - if (c) - c->closeWindow(); -} - -void RootInfo::moveResize(Window w, int x_root, int y_root, unsigned long direction) -{ - Client* c = workspace->findClient(WindowMatchPredicate(w)); - if (c) { - updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp - c->NETMoveResize(x_root, y_root, (Direction)direction); - } -} - -void RootInfo::moveResizeWindow(Window w, int flags, int x, int y, int width, int height) -{ - Client* c = workspace->findClient(WindowMatchPredicate(w)); - if (c) - c->NETMoveResizeWindow(flags, x, y, width, height); -} - -void RootInfo::gotPing(Window w, Time timestamp) -{ - if (Client* c = workspace->findClient(WindowMatchPredicate(w))) - c->gotPing(timestamp); -} - -void RootInfo::changeShowingDesktop(bool showing) -{ - workspace->setShowingDesktop(showing); -} - // **************************************** // Workspace // **************************************** @@ -565,26 +409,26 @@ bool Client::windowEvent(XEvent* e) double old_opacity = opacity(); info->event(e, dirty, 2); // pass through the NET stuff - if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMName) != 0) + if ((dirty[ NETWinInfo::PROTOCOLS ] & NET::WMName) != 0) fetchName(); - if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMIconName) != 0) + if ((dirty[ NETWinInfo::PROTOCOLS ] & NET::WMIconName) != 0) fetchIconicName(); - if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMStrut) != 0 - || (dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut) != 0) { + if ((dirty[ NETWinInfo::PROTOCOLS ] & NET::WMStrut) != 0 + || (dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut) != 0) { workspace()->updateClientArea(); } - if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0) + if ((dirty[ NETWinInfo::PROTOCOLS ] & NET::WMIcon) != 0) getIcons(); // Note there's a difference between userTime() and info->userTime() // info->userTime() is the value of the property, userTime() also includes // updates of the time done by KWin (ButtonPress on windowrapper etc.). - if ((dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2UserTime) != 0) { + if ((dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2UserTime) != 0) { workspace()->setWasUserInteraction(); updateUserTime(info->userTime()); } - if ((dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId) != 0) + if ((dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2StartupId) != 0) startupIdChanged(); - if (dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity) { + if (dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity) { if (compositing()) { addRepaintFull(); emit opacityChanged(this, old_opacity); @@ -594,7 +438,7 @@ bool Client::windowEvent(XEvent* e) i.setOpacity(info->opacity()); } } - if (dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2FrameOverlap) { + if (dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2FrameOverlap) { // ### Inform the decoration } } @@ -1701,7 +1545,7 @@ bool Group::groupEvent(XEvent* e) { unsigned long dirty[ 2 ]; leader_info->event(e, dirty, 2); // pass through the NET stuff - if ((dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId) != 0) + if ((dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2StartupId) != 0) startupIdChanged(); return false; } diff --git a/geometry.cpp b/geometry.cpp index 673edbf39b..1233d601a7 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -30,6 +30,7 @@ along with this program. If not, see . #include "client.h" #include "composite.h" #include "cursor.h" +#include "netinfo.h" #include "workspace.h" #include diff --git a/layers.cpp b/layers.cpp index 63529f8c54..cc7ac2c699 100644 --- a/layers.cpp +++ b/layers.cpp @@ -79,6 +79,7 @@ along with this program. If not, see . #include "utils.h" #include "client.h" #include "focuschain.h" +#include "netinfo.h" #include "workspace.h" #include "tabbox.h" #include "group.h" diff --git a/manage.cpp b/manage.cpp index 93eaa592cf..35f2cda4d9 100644 --- a/manage.cpp +++ b/manage.cpp @@ -34,6 +34,7 @@ along with this program. If not, see . #include #include "rules.h" #include "group.h" +#include "netinfo.h" #include "screens.h" #include "workspace.h" #include "xcbutils.h" diff --git a/netinfo.cpp b/netinfo.cpp new file mode 100644 index 0000000000..dd674ef367 --- /dev/null +++ b/netinfo.cpp @@ -0,0 +1,186 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 1999, 2000 Matthias Ettrich +Copyright (C) 2003 Lubos Lunak +Copyright (C) 2013 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +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 . +*********************************************************************/ +// own +#include "netinfo.h" +// kwin +#include "client.h" +#include "virtualdesktops.h" +#include "workspace.h" + +namespace KWin +{ + +RootInfo::RootInfo(Window w, const char *name, unsigned long pr[], int pr_num, int scr) + : NETRootInfo(display(), w, name, pr, pr_num, scr) +{ +} + +void RootInfo::changeNumberOfDesktops(int n) +{ + VirtualDesktopManager::self()->setCount(n); +} + +void RootInfo::changeCurrentDesktop(int d) +{ + VirtualDesktopManager::self()->setCurrent(d); +} + +void RootInfo::changeActiveWindow(Window w, NET::RequestSource src, Time timestamp, Window active_window) +{ + Workspace *workspace = Workspace::self(); + if (Client* c = workspace->findClient(WindowMatchPredicate(w))) { + if (timestamp == CurrentTime) + timestamp = c->userTime(); + if (src != NET::FromApplication && src != FromTool) + src = NET::FromTool; + if (src == NET::FromTool) + workspace->activateClient(c, true); // force + else if (c == workspace->mostRecentlyActivatedClient()) { + return; // WORKAROUND? With > 1 plasma activities, we cause this ourselves. bug #240673 + } else { // NET::FromApplication + Client* c2; + if (workspace->allowClientActivation(c, timestamp, false, true)) + workspace->activateClient(c); + // if activation of the requestor's window would be allowed, allow activation too + else if (active_window != None + && (c2 = workspace->findClient(WindowMatchPredicate(active_window))) != NULL + && workspace->allowClientActivation(c2, + timestampCompare(timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true)) { + workspace->activateClient(c); + } else + c->demandAttention(); + } + } +} + +void RootInfo::restackWindow(Window w, RequestSource src, Window above, int detail, Time timestamp) +{ + if (Client* c = Workspace::self()->findClient(WindowMatchPredicate(w))) { + if (timestamp == CurrentTime) + timestamp = c->userTime(); + if (src != NET::FromApplication && src != FromTool) + src = NET::FromTool; + c->restackWindow(above, detail, src, timestamp, true); + } +} + +void RootInfo::gotTakeActivity(Window w, Time timestamp, long flags) +{ + Workspace *workspace = Workspace::self(); + if (Client* c = workspace->findClient(WindowMatchPredicate(w))) + workspace->handleTakeActivity(c, timestamp, flags); +} + +void RootInfo::closeWindow(Window w) +{ + Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + if (c) + c->closeWindow(); +} + +void RootInfo::moveResize(Window w, int x_root, int y_root, unsigned long direction) +{ + Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + if (c) { + updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp + c->NETMoveResize(x_root, y_root, (Direction)direction); + } +} + +void RootInfo::moveResizeWindow(Window w, int flags, int x, int y, int width, int height) +{ + Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + if (c) + c->NETMoveResizeWindow(flags, x, y, width, height); +} + +void RootInfo::gotPing(Window w, Time timestamp) +{ + if (Client* c = Workspace::self()->findClient(WindowMatchPredicate(w))) + c->gotPing(timestamp); +} + +void RootInfo::changeShowingDesktop(bool showing) +{ + Workspace::self()->setShowingDesktop(showing); +} + +// **************************************** +// WinInfo +// **************************************** + +WinInfo::WinInfo(Client * c, Display * display, Window window, + Window rwin, const unsigned long pr[], int pr_size) + : NETWinInfo2(display, window, rwin, pr, pr_size, NET::WindowManager), m_client(c) +{ +} + +void WinInfo::changeDesktop(int desktop) +{ + Workspace::self()->sendClientToDesktop(m_client, desktop, true); +} + +void WinInfo::changeFullscreenMonitors(NETFullscreenMonitors topology) +{ + m_client->updateFullscreenMonitors(topology); +} + +void WinInfo::changeState(unsigned long state, unsigned long mask) +{ + mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore + mask &= ~NET::Hidden; // clients are not allowed to change this directly + state &= mask; // for safety, clear all other bits + + if ((mask & NET::FullScreen) != 0 && (state & NET::FullScreen) == 0) + m_client->setFullScreen(false, false); + if ((mask & NET::Max) == NET::Max) + m_client->setMaximize(state & NET::MaxVert, state & NET::MaxHoriz); + else if (mask & NET::MaxVert) + m_client->setMaximize(state & NET::MaxVert, m_client->maximizeMode() & Client::MaximizeHorizontal); + else if (mask & NET::MaxHoriz) + m_client->setMaximize(m_client->maximizeMode() & Client::MaximizeVertical, state & NET::MaxHoriz); + + if (mask & NET::Shaded) + m_client->setShade(state & NET::Shaded ? ShadeNormal : ShadeNone); + if (mask & NET::KeepAbove) + m_client->setKeepAbove((state & NET::KeepAbove) != 0); + if (mask & NET::KeepBelow) + m_client->setKeepBelow((state & NET::KeepBelow) != 0); + if (mask & NET::SkipTaskbar) + m_client->setSkipTaskbar((state & NET::SkipTaskbar) != 0, true); + if (mask & NET::SkipPager) + m_client->setSkipPager((state & NET::SkipPager) != 0); + if (mask & NET::DemandsAttention) + m_client->demandAttention((state & NET::DemandsAttention) != 0); + if (mask & NET::Modal) + m_client->setModal((state & NET::Modal) != 0); + // unsetting fullscreen first, setting it last (because e.g. maximize works only for !isFullScreen() ) + if ((mask & NET::FullScreen) != 0 && (state & NET::FullScreen) != 0) + m_client->setFullScreen(true, false); +} + +void WinInfo::disable() +{ + m_client = NULL; // only used when the object is passed to Deleted +} + +} // namespace diff --git a/netinfo.h b/netinfo.h new file mode 100644 index 0000000000..5539154c98 --- /dev/null +++ b/netinfo.h @@ -0,0 +1,80 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 1999, 2000 Matthias Ettrich +Copyright (C) 2003 Lubos Lunak +Copyright (C) 2009 Lucas Murray +Copyright (C) 2013 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +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 . +*********************************************************************/ +#ifndef KWIN_NETINFO_H +#define KWIN_NETINFO_H + +#include + +namespace KWin +{ + +class Client; + +/** + * NET WM Protocol handler class + */ +class RootInfo : public NETRootInfo +{ +private: + typedef KWin::Client Client; // Because of NET::Client + +public: + RootInfo(Window w, const char* name, unsigned long pr[], + int pr_num, int scr = -1); + +protected: + virtual void changeNumberOfDesktops(int n); + virtual void changeCurrentDesktop(int d); + virtual void changeActiveWindow(Window w, NET::RequestSource src, Time timestamp, Window active_window); + virtual void closeWindow(Window w); + virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction); + virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height); + virtual void gotPing(Window w, Time timestamp); + virtual void restackWindow(Window w, RequestSource source, Window above, int detail, Time timestamp); + virtual void gotTakeActivity(Window w, Time timestamp, long flags); + virtual void changeShowingDesktop(bool showing); +}; + +/** + * NET WM Protocol handler class + */ +class WinInfo : public NETWinInfo2 +{ +private: + typedef KWin::Client Client; // Because of NET::Client + +public: + WinInfo(Client* c, Display * display, Window window, + Window rwin, const unsigned long pr[], int pr_size); + virtual void changeDesktop(int desktop); + virtual void changeFullscreenMonitors(NETFullscreenMonitors topology); + virtual void changeState(unsigned long state, unsigned long mask); + void disable(); + +private: + Client * m_client; +}; + +} // KWin + +#endif diff --git a/toplevel.h b/toplevel.h index c4412a0515..88bbb73b2c 100644 --- a/toplevel.h +++ b/toplevel.h @@ -26,6 +26,8 @@ along with this program. If not, see . // kwin #include "utils.h" #include "virtualdesktops.h" +// KDE +#include // Qt #include // xcb @@ -34,8 +36,6 @@ along with this program. If not, see . // system #include -class NETWinInfo2; - namespace KWin { diff --git a/workspace.cpp b/workspace.cpp index 42dd9c185e..e9739228c4 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -41,6 +41,7 @@ along with this program. If not, see . #include "focuschain.h" #include "group.h" #include "killwindow.h" +#include "netinfo.h" #include "outline.h" #include "placement.h" #include "rules.h" @@ -329,7 +330,7 @@ void Workspace::init() if (!deco->isDisabled() && deco->factory()->supports(AbilityExtendIntoClientArea)) protocols[ NETRootInfo::PROTOCOLS2 ] |= NET::WM2FrameOverlap; - rootInfo = new RootInfo(this, display(), supportWindow->winId(), "KWin", protocols, 5, screen_number); + rootInfo = new RootInfo(supportWindow->winId(), "KWin", protocols, 5, screen_number); // create VirtualDesktopManager and perform dependency injection VirtualDesktopManager *vds = VirtualDesktopManager::self(); diff --git a/workspace.h b/workspace.h index da968c8549..e28c3b3167 100644 --- a/workspace.h +++ b/workspace.h @@ -27,8 +27,6 @@ along with this program. If not, see . #include #include "sm.h" #include "utils.h" -// KDE -#include // Qt #include #include @@ -586,34 +584,6 @@ private: Workspace* ws; }; -/** - * NET WM Protocol handler class - */ -class RootInfo : public NETRootInfo -{ -private: - typedef KWin::Client Client; // Because of NET::Client - -public: - RootInfo(Workspace* ws, Display* dpy, Window w, const char* name, unsigned long pr[], - int pr_num, int scr = -1); - -protected: - virtual void changeNumberOfDesktops(int n); - virtual void changeCurrentDesktop(int d); - virtual void changeActiveWindow(Window w, NET::RequestSource src, Time timestamp, Window active_window); - virtual void closeWindow(Window w); - virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction); - virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height); - virtual void gotPing(Window w, Time timestamp); - virtual void restackWindow(Window w, RequestSource source, Window above, int detail, Time timestamp); - virtual void gotTakeActivity(Window w, Time timestamp, long flags); - virtual void changeShowingDesktop(bool showing); - -private: - Workspace* workspace; -}; - //--------------------------------------------------------- // Unsorted