Turn RootInfo into a KWIN_SINGLETON
It's not a typical singleton as the ctor is not taking a Workspace* and needs addtional data to be passed to NETRootInfo. All the initialization code is moved to RootInfo::create() and the tear- down code is moved to RootInfo::destroyed(). This includes the support window which used to be a member of Workspace. It's only needed by RootInfo, so there is no need to have the ownership inside Workspace. Instead of using a QWidget we just create a normal window through xcb. It gets destroyed again in the tear-down code after the RootInfo got destroyed. REVIEW: 110238
This commit is contained in:
parent
2320b71cb7
commit
b6681ddc3a
8 changed files with 154 additions and 113 deletions
|
@ -263,7 +263,7 @@ void Workspace::setActiveClient(Client* c)
|
|||
|
||||
updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active
|
||||
|
||||
rootInfo->setActiveWindow(active_client ? active_client->window() : 0);
|
||||
rootInfo()->setActiveWindow(active_client ? active_client->window() : 0);
|
||||
updateColormap();
|
||||
|
||||
emit clientActivated(active_client);
|
||||
|
|
|
@ -87,7 +87,7 @@ bool Workspace::workspaceEvent(XEvent * e)
|
|||
|
||||
if (e->type == PropertyNotify || e->type == ClientMessage) {
|
||||
unsigned long dirty[ NETRootInfo::PROPERTIES_SIZE ];
|
||||
rootInfo->event(e, dirty, NETRootInfo::PROPERTIES_SIZE);
|
||||
rootInfo()->event(e, dirty, NETRootInfo::PROPERTIES_SIZE);
|
||||
if (dirty[ NETRootInfo::PROTOCOLS ] & NET::DesktopNames)
|
||||
VirtualDesktopManager::self()->save();
|
||||
if (dirty[ NETRootInfo::PROTOCOLS2 ] & NET::WM2DesktopLayout)
|
||||
|
|
|
@ -77,7 +77,7 @@ void Workspace::desktopResized()
|
|||
NETSize desktop_geometry;
|
||||
desktop_geometry.width = geom.width();
|
||||
desktop_geometry.height = geom.height();
|
||||
rootInfo->setDesktopGeometry(-1, desktop_geometry);
|
||||
rootInfo()->setDesktopGeometry(-1, desktop_geometry);
|
||||
|
||||
updateClientArea();
|
||||
saveOldScreenSizes(); // after updateClientArea(), so that one still uses the previous one
|
||||
|
@ -231,7 +231,7 @@ void Workspace::updateClientArea(bool force)
|
|||
r.pos.y = workarea[ i ].y();
|
||||
r.size.width = workarea[ i ].width();
|
||||
r.size.height = workarea[ i ].height();
|
||||
rootInfo->setWorkArea(i, r);
|
||||
rootInfo()->setWorkArea(i, r);
|
||||
}
|
||||
|
||||
for (ClientList::ConstIterator it = clients.constBegin();
|
||||
|
|
10
layers.cpp
10
layers.cpp
|
@ -157,7 +157,7 @@ void Workspace::updateStackingOrder(bool propagate_new_clients)
|
|||
*/
|
||||
void Workspace::stackScreenEdgesUnderOverrideRedirect()
|
||||
{
|
||||
Xcb::restackWindows(QVector<xcb_window_t>() << supportWindow->winId() << ScreenEdges::self()->windows());
|
||||
Xcb::restackWindows(QVector<xcb_window_t>() << rootInfo()->supportWindow() << ScreenEdges::self()->windows());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -176,7 +176,7 @@ void Workspace::propagateClients(bool propagate_new_clients)
|
|||
// but it was lowered after kwin startup. Stacking all clients below
|
||||
// it ensures that no client will be ever shown above override-redirect
|
||||
// windows (e.g. popups).
|
||||
newWindowStack << supportWindow->winId();
|
||||
newWindowStack << rootInfo()->supportWindow();
|
||||
|
||||
#ifdef KWIN_BUILD_SCREENEDGES
|
||||
newWindowStack << ScreenEdges::self()->windows();
|
||||
|
@ -208,7 +208,7 @@ void Workspace::propagateClients(bool propagate_new_clients)
|
|||
}
|
||||
// TODO isn't it too inefficient to restack always all clients?
|
||||
// TODO don't restack not visible windows?
|
||||
assert(newWindowStack.at(0) == supportWindow->winId());
|
||||
assert(newWindowStack.at(0) == rootInfo()->supportWindow());
|
||||
Xcb::restackWindows(newWindowStack);
|
||||
|
||||
int pos = 0;
|
||||
|
@ -220,7 +220,7 @@ void Workspace::propagateClients(bool propagate_new_clients)
|
|||
cl[pos++] = (*it)->window();
|
||||
for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it)
|
||||
cl[pos++] = (*it)->window();
|
||||
rootInfo->setClientList(cl, pos);
|
||||
rootInfo()->setClientList(cl, pos);
|
||||
delete [] cl;
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ void Workspace::propagateClients(bool propagate_new_clients)
|
|||
if ((*it)->isClient())
|
||||
cl[pos++] = (*it)->window();
|
||||
}
|
||||
rootInfo->setClientListStacking(cl, pos);
|
||||
rootInfo()->setClientListStacking(cl, pos);
|
||||
delete [] cl;
|
||||
|
||||
// Make the cached stacking order invalid here, in case we need the new stacking order before we get
|
||||
|
|
122
netinfo.cpp
122
netinfo.cpp
|
@ -21,15 +21,135 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*********************************************************************/
|
||||
// own
|
||||
#include "netinfo.h"
|
||||
// kwin libs
|
||||
#include <kdecorationfactory.h>
|
||||
// kwin
|
||||
#include "client.h"
|
||||
#include "decorations.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "workspace.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
extern int screen_number;
|
||||
|
||||
RootInfo::RootInfo(Window w, const char *name, unsigned long pr[], int pr_num, int scr)
|
||||
RootInfo *RootInfo::s_self = NULL;
|
||||
|
||||
RootInfo *RootInfo::create()
|
||||
{
|
||||
Q_ASSERT(!s_self);
|
||||
xcb_window_t supportWindow = xcb_generate_id(connection());
|
||||
const uint32_t values[] = {true};
|
||||
xcb_create_window(connection(), XCB_COPY_FROM_PARENT, supportWindow, KWin::rootWindow(),
|
||||
0, 0, 0, 0, 0, XCB_COPY_FROM_PARENT,
|
||||
XCB_COPY_FROM_PARENT, XCB_CW_OVERRIDE_REDIRECT, values);
|
||||
|
||||
const uint32_t lowerValues[] = { XCB_STACK_MODE_BELOW }; // See usage in layers.cpp
|
||||
// we need to do the lower window with a roundtrip, otherwise NETRootInfo is not functioning
|
||||
QScopedPointer<xcb_generic_error_t> error(xcb_request_check(connection(),
|
||||
xcb_configure_window_checked(connection(), supportWindow, XCB_CONFIG_WINDOW_STACK_MODE, lowerValues)));
|
||||
if (!error.isNull()) {
|
||||
kDebug(1212) << "Error occurred while lowering support window: " << error->error_code;
|
||||
}
|
||||
|
||||
unsigned long protocols[5] = {
|
||||
NET::Supported |
|
||||
NET::SupportingWMCheck |
|
||||
NET::ClientList |
|
||||
NET::ClientListStacking |
|
||||
NET::DesktopGeometry |
|
||||
NET::NumberOfDesktops |
|
||||
NET::CurrentDesktop |
|
||||
NET::ActiveWindow |
|
||||
NET::WorkArea |
|
||||
NET::CloseWindow |
|
||||
NET::DesktopNames |
|
||||
NET::WMName |
|
||||
NET::WMVisibleName |
|
||||
NET::WMDesktop |
|
||||
NET::WMWindowType |
|
||||
NET::WMState |
|
||||
NET::WMStrut |
|
||||
NET::WMIconGeometry |
|
||||
NET::WMIcon |
|
||||
NET::WMPid |
|
||||
NET::WMMoveResize |
|
||||
NET::WMFrameExtents |
|
||||
NET::WMPing
|
||||
,
|
||||
NET::NormalMask |
|
||||
NET::DesktopMask |
|
||||
NET::DockMask |
|
||||
NET::ToolbarMask |
|
||||
NET::MenuMask |
|
||||
NET::DialogMask |
|
||||
NET::OverrideMask |
|
||||
NET::UtilityMask |
|
||||
NET::SplashMask |
|
||||
// No compositing window types here unless we support them also as managed window types
|
||||
0
|
||||
,
|
||||
NET::Modal |
|
||||
//NET::Sticky | // Large desktops not supported (and probably never will be)
|
||||
NET::MaxVert |
|
||||
NET::MaxHoriz |
|
||||
NET::Shaded |
|
||||
NET::SkipTaskbar |
|
||||
NET::KeepAbove |
|
||||
//NET::StaysOnTop | // The same like KeepAbove
|
||||
NET::SkipPager |
|
||||
NET::Hidden |
|
||||
NET::FullScreen |
|
||||
NET::KeepBelow |
|
||||
NET::DemandsAttention |
|
||||
0
|
||||
,
|
||||
NET::WM2UserTime |
|
||||
NET::WM2StartupId |
|
||||
NET::WM2AllowedActions |
|
||||
NET::WM2RestackWindow |
|
||||
NET::WM2MoveResizeWindow |
|
||||
NET::WM2ExtendedStrut |
|
||||
NET::WM2KDETemporaryRules |
|
||||
NET::WM2ShowingDesktop |
|
||||
NET::WM2DesktopLayout |
|
||||
NET::WM2FullPlacement |
|
||||
NET::WM2FullscreenMonitors |
|
||||
NET::WM2KDEShadow |
|
||||
0
|
||||
,
|
||||
NET::ActionMove |
|
||||
NET::ActionResize |
|
||||
NET::ActionMinimize |
|
||||
NET::ActionShade |
|
||||
//NET::ActionStick | // Sticky state is not supported
|
||||
NET::ActionMaxVert |
|
||||
NET::ActionMaxHoriz |
|
||||
NET::ActionFullScreen |
|
||||
NET::ActionChangeDesktop |
|
||||
NET::ActionClose |
|
||||
0
|
||||
,
|
||||
};
|
||||
|
||||
DecorationPlugin *deco = DecorationPlugin::self();
|
||||
if (!deco->isDisabled() && deco->factory()->supports(KDecorationDefines::AbilityExtendIntoClientArea))
|
||||
protocols[ NETRootInfo::PROTOCOLS2 ] |= NET::WM2FrameOverlap;
|
||||
|
||||
s_self = new RootInfo(supportWindow, "KWin", protocols, 5, screen_number);
|
||||
return s_self;
|
||||
}
|
||||
|
||||
void RootInfo::destroy()
|
||||
{
|
||||
Q_ASSERT(s_self);
|
||||
xcb_window_t supportWindow = s_self->supportWindow();
|
||||
delete s_self;
|
||||
s_self = NULL;
|
||||
xcb_destroy_window(connection(), supportWindow);
|
||||
}
|
||||
|
||||
RootInfo::RootInfo(xcb_window_t w, const char *name, unsigned long pr[], int pr_num, int scr)
|
||||
: NETRootInfo(display(), w, name, pr, pr_num, scr)
|
||||
{
|
||||
}
|
||||
|
|
17
netinfo.h
17
netinfo.h
|
@ -25,6 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <KDE/NETRootInfo>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -39,8 +41,8 @@ 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);
|
||||
static RootInfo *create();
|
||||
static void destroy();
|
||||
|
||||
protected:
|
||||
virtual void changeNumberOfDesktops(int n);
|
||||
|
@ -53,8 +55,19 @@ protected:
|
|||
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:
|
||||
RootInfo(xcb_window_t w, const char* name, unsigned long pr[],
|
||||
int pr_num, int scr = -1);
|
||||
static RootInfo *s_self;
|
||||
friend RootInfo *rootInfo();
|
||||
};
|
||||
|
||||
inline RootInfo *rootInfo()
|
||||
{
|
||||
return RootInfo::s_self;
|
||||
}
|
||||
|
||||
/**
|
||||
* NET WM Protocol handler class
|
||||
*/
|
||||
|
|
106
workspace.cpp
106
workspace.cpp
|
@ -237,98 +237,11 @@ void Workspace::init()
|
|||
connect(options, SIGNAL(separateScreenFocusChanged(bool)), focusChain, SLOT(setSeparateScreenFocus(bool)));
|
||||
focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());
|
||||
|
||||
supportWindow = new QWidget(NULL, Qt::X11BypassWindowManagerHint);
|
||||
XLowerWindow(display(), supportWindow->winId()); // See usage in layers.cpp
|
||||
|
||||
const uint32_t nullFocusValues[] = {true};
|
||||
m_nullFocus.reset(new Xcb::Window(QRect(-1, -1, 1, 1), XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, nullFocusValues));
|
||||
m_nullFocus->map();
|
||||
|
||||
unsigned long protocols[5] = {
|
||||
NET::Supported |
|
||||
NET::SupportingWMCheck |
|
||||
NET::ClientList |
|
||||
NET::ClientListStacking |
|
||||
NET::DesktopGeometry |
|
||||
NET::NumberOfDesktops |
|
||||
NET::CurrentDesktop |
|
||||
NET::ActiveWindow |
|
||||
NET::WorkArea |
|
||||
NET::CloseWindow |
|
||||
NET::DesktopNames |
|
||||
NET::WMName |
|
||||
NET::WMVisibleName |
|
||||
NET::WMDesktop |
|
||||
NET::WMWindowType |
|
||||
NET::WMState |
|
||||
NET::WMStrut |
|
||||
NET::WMIconGeometry |
|
||||
NET::WMIcon |
|
||||
NET::WMPid |
|
||||
NET::WMMoveResize |
|
||||
NET::WMFrameExtents |
|
||||
NET::WMPing
|
||||
,
|
||||
NET::NormalMask |
|
||||
NET::DesktopMask |
|
||||
NET::DockMask |
|
||||
NET::ToolbarMask |
|
||||
NET::MenuMask |
|
||||
NET::DialogMask |
|
||||
NET::OverrideMask |
|
||||
NET::UtilityMask |
|
||||
NET::SplashMask |
|
||||
// No compositing window types here unless we support them also as managed window types
|
||||
0
|
||||
,
|
||||
NET::Modal |
|
||||
//NET::Sticky | // Large desktops not supported (and probably never will be)
|
||||
NET::MaxVert |
|
||||
NET::MaxHoriz |
|
||||
NET::Shaded |
|
||||
NET::SkipTaskbar |
|
||||
NET::KeepAbove |
|
||||
//NET::StaysOnTop | // The same like KeepAbove
|
||||
NET::SkipPager |
|
||||
NET::Hidden |
|
||||
NET::FullScreen |
|
||||
NET::KeepBelow |
|
||||
NET::DemandsAttention |
|
||||
0
|
||||
,
|
||||
NET::WM2UserTime |
|
||||
NET::WM2StartupId |
|
||||
NET::WM2AllowedActions |
|
||||
NET::WM2RestackWindow |
|
||||
NET::WM2MoveResizeWindow |
|
||||
NET::WM2ExtendedStrut |
|
||||
NET::WM2KDETemporaryRules |
|
||||
NET::WM2ShowingDesktop |
|
||||
NET::WM2DesktopLayout |
|
||||
NET::WM2FullPlacement |
|
||||
NET::WM2FullscreenMonitors |
|
||||
NET::WM2KDEShadow |
|
||||
0
|
||||
,
|
||||
NET::ActionMove |
|
||||
NET::ActionResize |
|
||||
NET::ActionMinimize |
|
||||
NET::ActionShade |
|
||||
//NET::ActionStick | // Sticky state is not supported
|
||||
NET::ActionMaxVert |
|
||||
NET::ActionMaxHoriz |
|
||||
NET::ActionFullScreen |
|
||||
NET::ActionChangeDesktop |
|
||||
NET::ActionClose |
|
||||
0
|
||||
,
|
||||
};
|
||||
|
||||
DecorationPlugin *deco = DecorationPlugin::self();
|
||||
if (!deco->isDisabled() && deco->factory()->supports(AbilityExtendIntoClientArea))
|
||||
protocols[ NETRootInfo::PROTOCOLS2 ] |= NET::WM2FrameOverlap;
|
||||
|
||||
rootInfo = new RootInfo(supportWindow->winId(), "KWin", protocols, 5, screen_number);
|
||||
RootInfo *rootInfo = RootInfo::create();
|
||||
|
||||
// create VirtualDesktopManager and perform dependency injection
|
||||
VirtualDesktopManager *vds = VirtualDesktopManager::self();
|
||||
|
@ -502,8 +415,7 @@ Workspace::~Workspace()
|
|||
delete RuleBook::self();
|
||||
KGlobal::config()->sync();
|
||||
|
||||
delete rootInfo;
|
||||
delete supportWindow;
|
||||
RootInfo::destroy();
|
||||
delete startup;
|
||||
delete Placement::self();
|
||||
delete client_keys_dialog;
|
||||
|
@ -918,9 +830,9 @@ void Workspace::slotReconfigure()
|
|||
}
|
||||
|
||||
if (!deco->isDisabled()) {
|
||||
rootInfo->setSupported(NET::WM2FrameOverlap, deco->factory()->supports(AbilityExtendIntoClientArea));
|
||||
rootInfo()->setSupported(NET::WM2FrameOverlap, deco->factory()->supports(AbilityExtendIntoClientArea));
|
||||
} else {
|
||||
rootInfo->setSupported(NET::WM2FrameOverlap, false);
|
||||
rootInfo()->setSupported(NET::WM2FrameOverlap, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1019,7 +931,7 @@ void Workspace::updateClientVisibilityOnDesktopChange(uint oldDesktop, uint newD
|
|||
}
|
||||
}
|
||||
// Now propagate the change, after hiding, before showing
|
||||
rootInfo->setCurrentDesktop(VirtualDesktopManager::self()->current());
|
||||
rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current());
|
||||
|
||||
if (movingClient && !movingClient->isOnDesktop(newDesktop)) {
|
||||
movingClient->setDesktop(newDesktop);
|
||||
|
@ -1330,12 +1242,12 @@ void Workspace::sendClientToScreen(Client* c, int screen)
|
|||
|
||||
void Workspace::sendPingToWindow(xcb_window_t window, xcb_timestamp_t timestamp)
|
||||
{
|
||||
rootInfo->sendPing(window, timestamp);
|
||||
rootInfo()->sendPing(window, timestamp);
|
||||
}
|
||||
|
||||
void Workspace::sendTakeActivity(KWin::Client *c, xcb_timestamp_t timestamp, long int flags)
|
||||
{
|
||||
rootInfo->takeActivity(c->window(), timestamp, flags);
|
||||
rootInfo()->takeActivity(c->window(), timestamp, flags);
|
||||
pending_take_activity = c;
|
||||
}
|
||||
|
||||
|
@ -1380,7 +1292,7 @@ void Workspace::focusToNull()
|
|||
|
||||
void Workspace::setShowingDesktop(bool showing)
|
||||
{
|
||||
rootInfo->setShowingDesktop(showing);
|
||||
rootInfo()->setShowingDesktop(showing);
|
||||
showing_desktop = showing;
|
||||
++block_showing_desktop;
|
||||
if (showing_desktop) {
|
||||
|
@ -1433,7 +1345,7 @@ void Workspace::resetShowingDesktop(bool keep_hidden)
|
|||
{
|
||||
if (block_showing_desktop > 0)
|
||||
return;
|
||||
rootInfo->setShowingDesktop(false);
|
||||
rootInfo()->setShowingDesktop(false);
|
||||
showing_desktop = false;
|
||||
++block_showing_desktop;
|
||||
if (!keep_hidden) {
|
||||
|
|
|
@ -53,7 +53,6 @@ class Window;
|
|||
|
||||
class Client;
|
||||
class KillWindow;
|
||||
class RootInfo;
|
||||
class ShortcutDialog;
|
||||
class UserActionsMenu;
|
||||
class Compositor;
|
||||
|
@ -531,9 +530,6 @@ private:
|
|||
bool global_shortcuts_disabled;
|
||||
bool global_shortcuts_disabled_for_client;
|
||||
|
||||
RootInfo* rootInfo;
|
||||
QWidget* supportWindow;
|
||||
|
||||
// Colormap handling
|
||||
Colormap default_colormap;
|
||||
Colormap installed_colormap;
|
||||
|
|
Loading…
Reference in a new issue