Merge pull request #513 from psychon/WM_Sn_selection
Various selection stuff that ICCCM requires us to do. Fixes https://awesome.naquadah.org/bugs/index.php?do=details&task_id=782. Fixes https://github.com/awesomeWM/awesome/issues/292. Closes https://github.com/awesomeWM/awesome/pull/513.
This commit is contained in:
commit
0478b946fb
83
awesome.c
83
awesome.c
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include <xcb/bigreq.h>
|
||||
#include <xcb/randr.h>
|
||||
#include <xcb/xcb_atom.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#include <xcb/xcb_event.h>
|
||||
#include <xcb/xinerama.h>
|
||||
|
@ -221,6 +222,76 @@ scan(xcb_query_tree_cookie_t tree_c)
|
|||
restore_client_order(prop_cookie);
|
||||
}
|
||||
|
||||
static void
|
||||
acquire_WM_Sn(bool replace)
|
||||
{
|
||||
xcb_intern_atom_cookie_t atom_q;
|
||||
xcb_intern_atom_reply_t *atom_r;
|
||||
char *atom_name;
|
||||
xcb_get_selection_owner_reply_t *get_sel_reply;
|
||||
xcb_client_message_event_t ev;
|
||||
|
||||
/* Get the WM_Sn atom */
|
||||
globalconf.selection_owner_window = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_window(globalconf.connection, globalconf.screen->root_depth,
|
||||
globalconf.selection_owner_window, globalconf.screen->root,
|
||||
-1, -1, 1, 1, 0,
|
||||
XCB_COPY_FROM_PARENT, globalconf.screen->root_visual,
|
||||
0, NULL);
|
||||
|
||||
atom_name = xcb_atom_name_by_screen("WM_S", globalconf.default_screen);
|
||||
if(!atom_name)
|
||||
fatal("error getting WM_Sn atom name");
|
||||
|
||||
atom_q = xcb_intern_atom_unchecked(globalconf.connection, false,
|
||||
a_strlen(atom_name), atom_name);
|
||||
|
||||
p_delete(&atom_name);
|
||||
|
||||
atom_r = xcb_intern_atom_reply(globalconf.connection, atom_q, NULL);
|
||||
if(!atom_r)
|
||||
fatal("error getting WM_Sn atom");
|
||||
|
||||
globalconf.selection_atom = atom_r->atom;
|
||||
p_delete(&atom_r);
|
||||
|
||||
/* Is the selection already owned? */
|
||||
get_sel_reply = xcb_get_selection_owner_reply(globalconf.connection,
|
||||
xcb_get_selection_owner(globalconf.connection, globalconf.selection_atom),
|
||||
NULL);
|
||||
if (!replace && get_sel_reply->owner != XCB_NONE)
|
||||
fatal("another window manager is already running (selection owned; use --replace)");
|
||||
|
||||
/* Acquire the selection */
|
||||
xcb_set_selection_owner(globalconf.connection, globalconf.selection_owner_window,
|
||||
globalconf.selection_atom, XCB_CURRENT_TIME);
|
||||
if (get_sel_reply->owner != XCB_NONE)
|
||||
{
|
||||
/* Wait for the old owner to go away */
|
||||
xcb_get_geometry_reply_t *geom_reply = NULL;
|
||||
do {
|
||||
p_delete(&geom_reply);
|
||||
geom_reply = xcb_get_geometry_reply(globalconf.connection,
|
||||
xcb_get_geometry(globalconf.connection, get_sel_reply->owner),
|
||||
NULL);
|
||||
} while (geom_reply != NULL);
|
||||
}
|
||||
p_delete(&get_sel_reply);
|
||||
|
||||
/* Announce that we are the new owner */
|
||||
p_clear(&ev, 1);
|
||||
ev.response_type = XCB_CLIENT_MESSAGE;
|
||||
ev.window = globalconf.screen->root;
|
||||
ev.format = 32;
|
||||
ev.type = MANAGER;
|
||||
ev.data.data32[0] = XCB_CURRENT_TIME;
|
||||
ev.data.data32[1] = globalconf.selection_atom;
|
||||
ev.data.data32[2] = globalconf.selection_owner_window;
|
||||
ev.data.data32[3] = ev.data.data32[4] = 0;
|
||||
|
||||
xcb_send_event(globalconf.connection, false, globalconf.screen->root, 0xFFFFFF, (char *) &ev);
|
||||
}
|
||||
|
||||
static void
|
||||
a_xcb_check(void)
|
||||
{
|
||||
|
@ -365,6 +436,7 @@ main(int argc, char **argv)
|
|||
xdgHandle xdg;
|
||||
bool no_argb = false;
|
||||
bool run_test = false;
|
||||
bool replace_wm = false;
|
||||
xcb_query_tree_cookie_t tree_c;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
|
@ -373,6 +445,7 @@ main(int argc, char **argv)
|
|||
{ "config", 1, NULL, 'c' },
|
||||
{ "check", 0, NULL, 'k' },
|
||||
{ "no-argb", 0, NULL, 'a' },
|
||||
{ "replace", 0, NULL, 'r' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -409,7 +482,7 @@ main(int argc, char **argv)
|
|||
luaA_init(&xdg);
|
||||
|
||||
/* check args */
|
||||
while((opt = getopt_long(argc, argv, "vhkc:a",
|
||||
while((opt = getopt_long(argc, argv, "vhkc:ar",
|
||||
long_options, NULL)) != -1)
|
||||
switch(opt)
|
||||
{
|
||||
|
@ -431,6 +504,9 @@ main(int argc, char **argv)
|
|||
case 'a':
|
||||
no_argb = true;
|
||||
break;
|
||||
case 'r':
|
||||
replace_wm = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (run_test)
|
||||
|
@ -506,6 +582,9 @@ main(int argc, char **argv)
|
|||
/* Did we get some usable data from the above X11 setup? */
|
||||
draw_test_cairo_xcb();
|
||||
|
||||
/* Acquire the WM_Sn selection */
|
||||
acquire_WM_Sn(replace_wm);
|
||||
|
||||
/* initialize dbus */
|
||||
a_dbus_init();
|
||||
|
||||
|
@ -527,7 +606,7 @@ main(int argc, char **argv)
|
|||
globalconf.screen->root,
|
||||
XCB_CW_EVENT_MASK, &select_input_val);
|
||||
if (xcb_request_check(globalconf.connection, cookie))
|
||||
fatal("another window manager is already running");
|
||||
fatal("another window manager is already running (can't select SubstructureRedirect)");
|
||||
}
|
||||
|
||||
/* Prefetch the maximum request length */
|
||||
|
|
11
event.c
11
event.c
|
@ -862,6 +862,16 @@ event_handle_reparentnotify(xcb_reparent_notify_event_t *ev)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
event_handle_selectionclear(xcb_selection_clear_event_t *ev)
|
||||
{
|
||||
if(ev->selection == globalconf.selection_atom)
|
||||
{
|
||||
warn("Lost WM_Sn selection, exiting...");
|
||||
g_main_loop_quit(globalconf.loop);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief awesome xerror function.
|
||||
* There's no way to check accesses to destroyed windows, thus those cases are
|
||||
* ignored (especially on UnmapNotify's).
|
||||
|
@ -921,6 +931,7 @@ void event_handle(xcb_generic_event_t *event)
|
|||
EVENT(XCB_PROPERTY_NOTIFY, property_handle_propertynotify);
|
||||
EVENT(XCB_REPARENT_NOTIFY, event_handle_reparentnotify);
|
||||
EVENT(XCB_UNMAP_NOTIFY, event_handle_unmapnotify);
|
||||
EVENT(XCB_SELECTION_CLEAR, event_handle_selectionclear);
|
||||
#undef EVENT
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,10 @@ typedef struct
|
|||
key_array_t keys;
|
||||
/** Root window mouse bindings */
|
||||
button_array_t buttons;
|
||||
/** Atom for WM_Sn */
|
||||
xcb_atom_t selection_atom;
|
||||
/** Window owning the WM_Sn selection */
|
||||
xcb_window_t selection_owner_window;
|
||||
/** Modifiers masks */
|
||||
uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask;
|
||||
/** Check for XTest extension */
|
||||
|
|
|
@ -35,6 +35,8 @@ OPTIONEN
|
|||
Überprüft die Konfigurationsdatei auf Syntaxfehler.
|
||||
*-a*, *--no-argb*::
|
||||
Verwende keine ARGB-Visuals
|
||||
*-r*, *--replace*::
|
||||
Existierenden Fenstermanager ersetzen.
|
||||
|
||||
TASTENBELEGUNG FÜR MAUSZEIGER
|
||||
-----------------------------
|
||||
|
|
|
@ -52,6 +52,8 @@ OPCIONES
|
|||
Verifica la sintaxis del archivo de configuración.
|
||||
*-a*, *--no-argb*::
|
||||
No utilice colores ARGB.
|
||||
*-r*, *--replace*::
|
||||
Replace an existing window manager.
|
||||
|
||||
ATAJOS DE RAtÓN POR OMISIÓN
|
||||
---------------------------
|
||||
|
|
|
@ -45,6 +45,9 @@ OPTIONS
|
|||
Vérifie la syntaxe du fichier de configuration.
|
||||
*-a*, *--no-argb*::
|
||||
N'utilise pas le codage ARGB.
|
||||
*-r*, *--replace*::
|
||||
Remplace le gestionnaire de fenêtres existant.
|
||||
|
||||
|
||||
ASSOCIATIONS AVEC LA SOURIS (PAR DÉFAUT)
|
||||
----------------------------------------
|
||||
|
|
|
@ -52,6 +52,8 @@ OPZIONI
|
|||
Verifica la sintassi del file di configurazione.
|
||||
*-a*, *--no-argb*::
|
||||
Non usare visuali ARGB.
|
||||
*-r*, *--replace*::
|
||||
Replace an existing window manager.
|
||||
|
||||
DEFAULT SCORCIATOIE CON IL MOUSE
|
||||
--------------------------------
|
||||
|
|
|
@ -47,6 +47,8 @@ awesome - потрясающий оконный менеджер
|
|||
Проверить синтаксис конфигурационного файла.
|
||||
*-a*, *--no-argb*::
|
||||
Не использовать ARGB.
|
||||
*-r*, *--replace*::
|
||||
Replace an existing window manager.
|
||||
|
||||
НАСТРОЙКИ МЫШИ ПО-УМОЛЧАНИЮ
|
||||
---------------------------
|
||||
|
|
|
@ -44,6 +44,8 @@ OPTIONS
|
|||
Check configuration file syntax.
|
||||
*-a*, *--no-argb*::
|
||||
Don't use ARGB visuals.
|
||||
*-r*, *--replace*::
|
||||
Replace an existing window manager.
|
||||
|
||||
DEFAULT MOUSE BINDINGS
|
||||
-----------------------
|
||||
|
|
Loading…
Reference in New Issue