Commit 6404dde4 authored by Thomas Lübking's avatar Thomas Lübking
Browse files

Support multiple X servers in the NETWM classes

Original patch by M. Graesslin
--------
So far on first creation of a NETRootInfo or NETWinInfo a static
initialization of atoms was performed. This meant that the NET classes
are only able to interact with the X server the first NET class is
connected to.

Normally applications don't need to interact with multiple X servers.
An exception is kwin_wayland which needs a connection to its Xwayland
server and on the x11 backend to the X server it renders to. So far
KWin could not use the NET classes for it, causing the rendering window
to e.g. not have a window title.

This change removes the implicit constraint on one X server by
creating a hash of connection and atoms. For each created NET class
we check whether we have already resolved the atoms, if yes we reuse
otherwise we create them.

For the normal use case of one X11 connection the change should be
rather minimal. Instead of performing the check whether the static
atoms have been created, it now is a check whether the atoms for the
connection have been created. The atoms are kept in a
QSharedDataPointer ensuring that we don't needless copy the atoms into
each class.

---

As we cannot avoid touching each and every atom referencing code line
we use the opportunity to clean up the code by getting rid of atom
variables (with ambigious names) and an array to link their references to
strings and an integer to define the length of the array by an atom array
(instead of the variables), enums to reference and count them
(by the actual atom tokens) and a string array - with some preproc magic, to
keep atoms, strings and counter in sync automagically.

CHANGELOG: Allow interacting with multiple X servers in the NETWM classes.
REVIEW: 125309
parent 4b9317af
/*
* Copyright 2015 Thomas Lübking <thomas.luebking@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#if (!defined ATOMS_H) || (defined ENUM_CREATE_CHAR_ARRAY)
#undef ENUM_BEGIN
#undef ENUM
#undef ENUM_END
#undef ENUM_COUNT
// the following macros are set in a way so that
// the code below will either construct an enum for "<typ>"
// or a const *char array "<typ>Strings" containing all enum
// symbols as strings, depending on whether ENUM_CREATE_CHAR_ARRAY is
// defined
// The enum gets one extra item "<typ>Count", describing also the
// length of the array
// The header is safe for re-inclusion unless you define ENUM_CREATE_CHAR_ARRAY
// which is therefore undefined after usage
// => You *must* "#define ENUM_CREATE_CHAR_ARRAY 1" *every* time you want to create
// a string array!
#ifndef ENUM_CREATE_CHAR_ARRAY
#define ATOMS_H
#define ENUM_BEGIN(typ) enum typ {
#define ENUM(nam) nam
#define ENUM_COUNT(typ) , typ##Count
#else
#define ENUM_BEGIN(typ) const char * typ##Strings [] = {
#define ENUM(nam) #nam
#define ENUM_COUNT(typ)
#undef ENUM_CREATE_CHAR_ARRAY
#endif
#define ENUM_END(typ) };
ENUM_BEGIN(KwsAtom)
ENUM(UTF8_STRING),
// root window properties
ENUM(_NET_SUPPORTED),
ENUM(_NET_SUPPORTING_WM_CHECK),
ENUM(_NET_CLIENT_LIST),
ENUM(_NET_CLIENT_LIST_STACKING),
ENUM(_NET_NUMBER_OF_DESKTOPS),
ENUM(_NET_DESKTOP_GEOMETRY),
ENUM(_NET_DESKTOP_VIEWPORT),
ENUM(_NET_CURRENT_DESKTOP),
ENUM(_NET_DESKTOP_NAMES),
ENUM(_NET_ACTIVE_WINDOW),
ENUM(_NET_WORKAREA),
ENUM(_NET_VIRTUAL_ROOTS),
ENUM(_NET_DESKTOP_LAYOUT),
ENUM(_NET_SHOWING_DESKTOP),
// root window messages
ENUM(_NET_CLOSE_WINDOW),
ENUM(_NET_RESTACK_WINDOW),
ENUM(_NET_WM_MOVERESIZE),
ENUM(_NET_MOVERESIZE_WINDOW),
// application window properties
ENUM(_NET_WM_NAME),
ENUM(_NET_WM_VISIBLE_NAME),
ENUM(_NET_WM_ICON_NAME),
ENUM(_NET_WM_VISIBLE_ICON_NAME),
ENUM(_NET_WM_DESKTOP),
ENUM(_NET_WM_WINDOW_TYPE),
ENUM(_NET_WM_STATE),
ENUM(_NET_WM_STRUT),
ENUM(_NET_WM_STRUT_PARTIAL),
ENUM(_NET_WM_ICON_GEOMETRY),
ENUM(_NET_WM_ICON),
ENUM(_NET_WM_PID),
ENUM(_NET_WM_USER_TIME),
ENUM(_NET_WM_HANDLED_ICONS),
ENUM(_NET_STARTUP_ID),
ENUM(_NET_WM_ALLOWED_ACTIONS),
ENUM(WM_WINDOW_ROLE),
ENUM(_NET_FRAME_EXTENTS),
ENUM(_NET_WM_WINDOW_OPACITY),
ENUM(_NET_WM_FULLSCREEN_MONITORS),
ENUM(_NET_WM_OPAQUE_REGION),
// used to determine whether application window is managed or not
ENUM(WM_STATE),
// application window types
ENUM(_NET_WM_WINDOW_TYPE_NORMAL),
ENUM(_NET_WM_WINDOW_TYPE_DESKTOP),
ENUM(_NET_WM_WINDOW_TYPE_DOCK),
ENUM(_NET_WM_WINDOW_TYPE_TOOLBAR),
ENUM(_NET_WM_WINDOW_TYPE_MENU),
ENUM(_NET_WM_WINDOW_TYPE_DIALOG),
ENUM(_NET_WM_WINDOW_TYPE_UTILITY),
ENUM(_NET_WM_WINDOW_TYPE_SPLASH),
ENUM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU),
ENUM(_NET_WM_WINDOW_TYPE_POPUP_MENU),
ENUM(_NET_WM_WINDOW_TYPE_TOOLTIP),
ENUM(_NET_WM_WINDOW_TYPE_NOTIFICATION),
ENUM(_NET_WM_WINDOW_TYPE_COMBOBOX),
ENUM(_NET_WM_WINDOW_TYPE_DND),
// application window state
ENUM(_NET_WM_STATE_MODAL),
ENUM(_NET_WM_STATE_STICKY),
ENUM(_NET_WM_STATE_MAXIMIZED_VERT),
ENUM(_NET_WM_STATE_MAXIMIZED_HORZ),
ENUM(_NET_WM_STATE_SHADED),
ENUM(_NET_WM_STATE_SKIP_TASKBAR),
ENUM(_NET_WM_STATE_SKIP_PAGER),
ENUM(_NET_WM_STATE_HIDDEN),
ENUM(_NET_WM_STATE_FULLSCREEN),
ENUM(_NET_WM_STATE_ABOVE),
ENUM(_NET_WM_STATE_BELOW),
ENUM(_NET_WM_STATE_DEMANDS_ATTENTION),
// allowed actions
ENUM(_NET_WM_ACTION_MOVE),
ENUM(_NET_WM_ACTION_RESIZE),
ENUM(_NET_WM_ACTION_MINIMIZE),
ENUM(_NET_WM_ACTION_SHADE),
ENUM(_NET_WM_ACTION_STICK),
ENUM(_NET_WM_ACTION_MAXIMIZE_VERT),
ENUM(_NET_WM_ACTION_MAXIMIZE_HORZ),
ENUM(_NET_WM_ACTION_FULLSCREEN),
ENUM(_NET_WM_ACTION_CHANGE_DESKTOP),
ENUM(_NET_WM_ACTION_CLOSE),
// KDE extensions
ENUM(_KDE_NET_WM_FRAME_STRUT),
ENUM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE),
ENUM(_KDE_NET_WM_WINDOW_TYPE_TOPMENU),
ENUM(_KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY),
ENUM(_KDE_NET_WM_TEMPORARY_RULES),
ENUM(_NET_WM_FRAME_OVERLAP),
// deprecated and naming convention violation
ENUM(_NET_WM_STATE_STAYS_ON_TOP),
// application protocols
ENUM(WM_PROTOCOLS),
ENUM(WM_TAKE_FOCUS),
ENUM(WM_DELETE_WINDOW),
ENUM(_NET_WM_PING),
ENUM(_NET_WM_SYNC_REQUEST),
ENUM(_NET_WM_CONTEXT_HELP),
// ability flags
ENUM(_NET_WM_FULL_PLACEMENT),
ENUM(_KDE_NET_WM_ACTIVITIES),
ENUM(_KDE_NET_WM_BLOCK_COMPOSITING),
ENUM(_KDE_NET_WM_SHADOW)
ENUM_COUNT(KwsAtom)
ENUM_END(KwsAtom)
#endif // ATOMS_H
\ No newline at end of file
This diff is collapsed.
......@@ -26,6 +26,26 @@
#ifndef netwm_p_h
#define netwm_p_h
#include <QSharedData>
#include <QSharedDataPointer>
#include "atoms_p.h"
class Atoms : public QSharedData
{
public:
explicit Atoms(xcb_connection_t *c);
xcb_atom_t atom(KwsAtom atom) const {
return m_atoms[atom];
}
private:
void init();
xcb_atom_t m_atoms[KwsAtomCount];
xcb_connection_t *m_connection;
};
/**
Resizable array class.
......@@ -121,6 +141,11 @@ struct NETRootInfoPrivate {
NET::Properties2 clientProperties2;
int ref;
QSharedDataPointer<Atoms> atoms;
xcb_atom_t atom(KwsAtom atom) const {
return atoms->atom(atom);
}
};
/**
......@@ -173,6 +198,11 @@ struct NETWinInfoPrivate {
std::vector<NETRect> opaqueRegion;
int ref;
QSharedDataPointer<Atoms> atoms;
xcb_atom_t atom(KwsAtom atom) const {
return atoms->atom(atom);
}
};
#endif // netwm_p_h
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment