diff --git a/atoms.cpp b/atoms.cpp index 7dd4aece15..b42d05a35a 100644 --- a/atoms.cpp +++ b/atoms.cpp @@ -4,6 +4,7 @@ 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 @@ -20,120 +21,59 @@ along with this program. If not, see . *********************************************************************/ #include "atoms.h" -#include "utils.h" -#include namespace KWin { Atoms::Atoms() + : kwin_running(QByteArrayLiteral("KWIN_RUNNING")) + , activities(QByteArrayLiteral("_KDE_NET_WM_ACTIVITIES")) + , wm_protocols(QByteArrayLiteral("WM_PROTOCOLS")) + , wm_delete_window(QByteArrayLiteral("WM_DELETE_WINDOW")) + , wm_take_focus(QByteArrayLiteral("WM_TAKE_FOCUS")) + , wm_change_state(QByteArrayLiteral("WM_CHANGE_STATE")) + , wm_client_leader(QByteArrayLiteral("WM_CLIENT_LEADER")) + , wm_window_role(QByteArrayLiteral("WM_WINDOW_ROLE")) + , wm_state(QByteArrayLiteral("WM_STATE")) + , sm_client_id(QByteArrayLiteral("SM_CLIENT_ID")) + , motif_wm_hints(QByteArrayLiteral("_MOTIF_WM_HINTS")) + , net_wm_context_help(QByteArrayLiteral("_NET_WM_CONTEXT_HELP")) + , net_wm_ping(QByteArrayLiteral("_NET_WM_PING")) + , kde_wm_change_state(QByteArrayLiteral("_KDE_WM_CHANGE_STATE")) + , net_wm_user_time(QByteArrayLiteral("_NET_WM_USER_TIME")) + , kde_net_wm_user_creation_time(QByteArrayLiteral("_KDE_NET_WM_USER_CREATION_TIME")) + , kde_system_tray_embedding(QByteArrayLiteral("_KDE_SYSTEM_TRAY_EMBEDDING")) + , net_wm_take_activity(QByteArrayLiteral("_NET_WM_TAKE_ACTIVITY")) + , net_wm_window_opacity(QByteArrayLiteral("_NET_WM_WINDOW_OPACITY")) + , xdnd_aware(QByteArrayLiteral("XdndAware")) + , xdnd_position(QByteArrayLiteral("XdndPosition")) + , net_frame_extents(QByteArrayLiteral("_NET_FRAME_EXTENTS")) + , kde_net_wm_frame_strut(QByteArrayLiteral("_KDE_NET_WM_FRAME_STRUT")) + , net_wm_sync_request_counter(QByteArrayLiteral("_NET_WM_SYNC_REQUEST_COUNTER")) + , net_wm_sync_request(QByteArrayLiteral("_NET_WM_SYNC_REQUEST")) + , kde_net_wm_block_compositing(QByteArrayLiteral("_KDE_NET_WM_BLOCK_COMPOSITING")) + , kde_net_wm_shadow(QByteArrayLiteral("_KDE_NET_WM_SHADOW")) + , net_wm_opaque_region(QByteArrayLiteral("_NET_WM_OPAQUE_REGION")) + , kde_net_wm_tab_group(QByteArrayLiteral("_KDE_NET_WM_TAB_GROUP")) + , kde_first_in_window_list(QByteArrayLiteral("_KDE_FIRST_IN_WINDOWLIST")) + , m_dtSmWindowInfo(QByteArrayLiteral("_DT_SM_WINDOW_INFO")) + , m_motifSupport(QByteArrayLiteral("_MOTIF_WM_INFO")) + , m_helpersRetrieved(false) { +} - const int max = 50; - Atom* atoms[max]; - char* names[max]; - Atom atoms_return[max]; - int n = 0; - - atoms[n] = &kwin_running; - names[n++] = (char *) "KWIN_RUNNING"; - - atoms[n] = &activities; - names[n++] = (char *) "_KDE_NET_WM_ACTIVITIES"; - - atoms[n] = &wm_protocols; - names[n++] = (char *) "WM_PROTOCOLS"; - - atoms[n] = &wm_delete_window; - names[n++] = (char *) "WM_DELETE_WINDOW"; - - atoms[n] = &wm_take_focus; - names[n++] = (char *) "WM_TAKE_FOCUS"; - - atoms[n] = &wm_change_state; - names[n++] = (char *) "WM_CHANGE_STATE"; - - atoms[n] = &wm_client_leader; - names[n++] = (char *) "WM_CLIENT_LEADER"; - - atoms[n] = &wm_window_role; - names[n++] = (char *) "WM_WINDOW_ROLE"; - - atoms[n] = &wm_state; - names[n++] = (char *) "WM_STATE"; - - atoms[n] = &sm_client_id; - names[n++] = (char *) "SM_CLIENT_ID"; - - atoms[n] = &motif_wm_hints; - names[n++] = (char *) "_MOTIF_WM_HINTS"; - - atoms[n] = &net_wm_context_help; - names[n++] = (char *) "_NET_WM_CONTEXT_HELP"; - - atoms[n] = &net_wm_ping; - names[n++] = (char *) "_NET_WM_PING"; - - atoms[n] = &kde_wm_change_state; - names[n++] = (char *) "_KDE_WM_CHANGE_STATE"; - - atoms[n] = &net_wm_user_time; - names[n++] = (char *) "_NET_WM_USER_TIME"; - atoms[n] = &kde_net_wm_user_creation_time; - names[n++] = (char *) "_KDE_NET_WM_USER_CREATION_TIME"; - - atoms[n] = &kde_system_tray_embedding; - names[n++] = (char*) "_KDE_SYSTEM_TRAY_EMBEDDING"; - - atoms[n] = &net_wm_take_activity; - names[n++] = (char*) "_NET_WM_TAKE_ACTIVITY"; - - atoms[n] = &net_wm_window_opacity; - names[n++] = (char*) "_NET_WM_WINDOW_OPACITY"; - - Atom fake; - atoms[n] = &fake; - names[n++] = (char *) "_DT_SM_WINDOW_INFO"; - - atoms[n] = &fake; - names[n++] = (char *) "_MOTIF_WM_INFO"; // #172028 - - atoms[n] = &xdnd_aware; - names[n++] = (char*) "XdndAware"; - atoms[n] = &xdnd_position; - names[n++] = (char*) "XdndPosition"; - - atoms[n] = &net_frame_extents; - names[n++] = (char*) "_NET_FRAME_EXTENTS"; - atoms[n] = &kde_net_wm_frame_strut; - names[n++] = (char*) "_KDE_NET_WM_FRAME_STRUT"; - - atoms[n] = &net_wm_sync_request_counter; - names[n++] = (char*) "_NET_WM_SYNC_REQUEST_COUNTER"; - - atoms[n] = &net_wm_sync_request; - names[n++] = (char*) "_NET_WM_SYNC_REQUEST"; - - atoms[n] = &kde_net_wm_block_compositing; - names[n++] = (char*) "_KDE_NET_WM_BLOCK_COMPOSITING"; - - atoms[n] = &kde_net_wm_shadow; - names[n++] = (char*) "_KDE_NET_WM_SHADOW"; - - atoms[n] = &net_wm_opaque_region; - names[n++] = (char*) "_NET_WM_OPAQUE_REGION"; - - atoms[n] = &kde_net_wm_tab_group; - names[n++] = (char*) "_KDE_NET_WM_TAB_GROUP"; - - atoms[n] = &kde_first_in_window_list; - names[n++] = (char*) "_KDE_FIRST_IN_WINDOWLIST"; - - assert(n <= max); - - XInternAtoms(display(), names, n, false, atoms_return); - for (int i = 0; i < n; i++) - *atoms[i] = atoms_return[i]; +void Atoms::retrieveHelpers() +{ + if (m_helpersRetrieved) { + return; + } + // just retrieve the atoms once, all others are retrieved when being accessed + // Q_UNUSED is used in the hope that the compiler doesn't optimize the operations away + xcb_atom_t atom = m_dtSmWindowInfo; + Q_UNUSED(atom) + atom = m_motifSupport; + Q_UNUSED(atom) + m_helpersRetrieved = true; } } // namespace diff --git a/atoms.h b/atoms.h index 967190a6e5..500705507d 100644 --- a/atoms.h +++ b/atoms.h @@ -4,6 +4,7 @@ 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 @@ -22,9 +23,7 @@ along with this program. If not, see . #ifndef KWIN_ATOMS_H #define KWIN_ATOMS_H -#include -#include -#include +#include "xcbutils.h" namespace KWin { @@ -34,38 +33,49 @@ class Atoms public: Atoms(); - Atom kwin_running; - Atom activities; + Xcb::Atom kwin_running; + Xcb::Atom activities; - Atom wm_protocols; - Atom wm_delete_window; - Atom wm_take_focus; - Atom wm_change_state; - Atom wm_client_leader; - Atom wm_window_role; - Atom wm_state; - Atom sm_client_id; + Xcb::Atom wm_protocols; + Xcb::Atom wm_delete_window; + Xcb::Atom wm_take_focus; + Xcb::Atom wm_change_state; + Xcb::Atom wm_client_leader; + Xcb::Atom wm_window_role; + Xcb::Atom wm_state; + Xcb::Atom sm_client_id; - Atom motif_wm_hints; - Atom net_wm_context_help; - Atom net_wm_ping; - Atom kde_wm_change_state; - Atom net_wm_user_time; - Atom kde_net_wm_user_creation_time; - Atom kde_system_tray_embedding; - Atom net_wm_take_activity; - Atom net_wm_window_opacity; - Atom xdnd_aware; - Atom xdnd_position; - Atom net_frame_extents; - Atom kde_net_wm_frame_strut; - Atom net_wm_sync_request_counter; - Atom net_wm_sync_request; - Atom kde_net_wm_block_compositing; - Atom kde_net_wm_shadow; - Atom net_wm_opaque_region; - Atom kde_net_wm_tab_group; - Atom kde_first_in_window_list; + Xcb::Atom motif_wm_hints; + Xcb::Atom net_wm_context_help; + Xcb::Atom net_wm_ping; + Xcb::Atom kde_wm_change_state; + Xcb::Atom net_wm_user_time; + Xcb::Atom kde_net_wm_user_creation_time; + Xcb::Atom kde_system_tray_embedding; + Xcb::Atom net_wm_take_activity; + Xcb::Atom net_wm_window_opacity; + Xcb::Atom xdnd_aware; + Xcb::Atom xdnd_position; + Xcb::Atom net_frame_extents; + Xcb::Atom kde_net_wm_frame_strut; + Xcb::Atom net_wm_sync_request_counter; + Xcb::Atom net_wm_sync_request; + Xcb::Atom kde_net_wm_block_compositing; + Xcb::Atom kde_net_wm_shadow; + Xcb::Atom net_wm_opaque_region; + Xcb::Atom kde_net_wm_tab_group; + Xcb::Atom kde_first_in_window_list; + + /** + * @internal + **/ + void retrieveHelpers(); + +private: + // helper atoms we need to resolve to "announce" support (see #172028) + Xcb::Atom m_dtSmWindowInfo; + Xcb::Atom m_motifSupport; + bool m_helpersRetrieved; }; diff --git a/events.cpp b/events.cpp index 08070e3a66..cdb577ad50 100644 --- a/events.cpp +++ b/events.cpp @@ -47,6 +47,7 @@ along with this program. If not, see . #include "screens.h" #include "xcbutils.h" +#include #include #include diff --git a/main.cpp b/main.cpp index 77f3573ebd..20e242a6df 100644 --- a/main.cpp +++ b/main.cpp @@ -51,6 +51,8 @@ along with this program. If not, see . #include #include #include +// TODO: remove once QX11Info provides the X screen +#include // system #ifdef HAVE_UNISTD_H @@ -236,7 +238,7 @@ void Application::start() ::exit(1); } - atoms = new Atoms; + atoms->retrieveHelpers(); // This tries to detect compositing options and can use GLX. GLX problems // (X errors) shouldn't cause kwin to abort, so this is out of the @@ -263,6 +265,7 @@ void Application::start() owner.claim(m_replace, true); crashChecking(); + atoms = new Atoms; } Application::~Application() diff --git a/utils.cpp b/utils.cpp index c44b3ee268..52647f2d98 100644 --- a/utils.cpp +++ b/utils.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . #ifndef KCMRULES #include +#include #include #include diff --git a/xcbutils.h b/xcbutils.h index 9495d891fb..af37a93a26 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -169,6 +169,8 @@ public: , m_name(name) { } + Atom() = delete; + Atom(const Atom &) = delete; ~Atom() { if (!m_retrieved && m_cookie.sequence) {