Merge pull request #1920 from Airblader/feature-1873

Set and unset individual atoms in _NET_WM_STATE
This commit is contained in:
Michael Stapelberg
2015-09-17 10:08:27 +02:00
6 changed files with 146 additions and 19 deletions

View File

@ -658,14 +658,13 @@ static void con_set_fullscreen_mode(Con *con, fullscreen_mode_t fullscreen_mode)
if (con->window == NULL)
return;
uint32_t values[1];
unsigned int num = 0;
if (con->fullscreen_mode != CF_NONE)
values[num++] = A__NET_WM_STATE_FULLSCREEN;
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
A__NET_WM_STATE, XCB_ATOM_ATOM, 32, num, values);
if (con->fullscreen_mode != CF_NONE) {
DLOG("Setting _NET_WM_STATE_FULLSCREEN for con = %p / window = %d.\n", con, con->window->id);
xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_FULLSCREEN);
} else {
DLOG("Removing _NET_WM_STATE_FULLSCREEN for con = %p / window = %d.\n", con, con->window->id);
xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_FULLSCREEN);
}
}
/*

View File

@ -218,13 +218,13 @@ void ewmh_update_client_list_stacking(xcb_window_t *stack, int num_windows) {
*
*/
void ewmh_update_sticky(xcb_window_t window, bool sticky) {
uint32_t values[1];
unsigned int num = 0;
if (sticky)
values[num++] = A__NET_WM_STATE_STICKY;
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, A__NET_WM_STATE, XCB_ATOM_ATOM, 32, num, values);
if (sticky) {
DLOG("Setting _NET_WM_STATE_STICKY for window = %d.\n", window);
xcb_add_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_STICKY);
} else {
DLOG("Removing _NET_WM_STATE_STICKY for window = %d.\n", window);
xcb_remove_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_STICKY);
}
}
/*

View File

@ -631,16 +631,14 @@ static void set_hidden_state(Con *con) {
if (should_be_hidden == state->is_hidden)
return;
unsigned int num = 0;
uint32_t values[1];
if (should_be_hidden) {
DLOG("setting _NET_WM_STATE_HIDDEN for con = %p\n", con);
values[num++] = A__NET_WM_STATE_HIDDEN;
xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
} else {
DLOG("removing _NET_WM_STATE_HIDDEN for con = %p\n", con);
xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
}
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id, A__NET_WM_STATE, XCB_ATOM_ATOM, 32, num, values);
state->is_hidden = should_be_hidden;
}

View File

@ -274,3 +274,48 @@ xcb_visualid_t get_visualid_by_depth(uint16_t depth) {
}
return 0;
}
/*
* Add an atom to a list of atoms the given property defines.
* This is useful, for example, for manipulating _NET_WM_STATE.
*
*/
void xcb_add_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom) {
xcb_change_property(conn, XCB_PROP_MODE_APPEND, window, property, XCB_ATOM_ATOM, 32, 1, (uint32_t[]){atom});
}
/*
* Remove an atom from a list of atoms the given property defines without
* removing any other potentially set atoms. This is useful, for example, for
* manipulating _NET_WM_STATE.
*
*/
void xcb_remove_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom) {
xcb_grab_server(conn);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(conn,
xcb_get_property(conn, false, window, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 4096), NULL);
if (reply == NULL || xcb_get_property_value_length(reply) == 0)
goto release_grab;
xcb_atom_t *atoms = xcb_get_property_value(reply);
if (atoms == NULL) {
goto release_grab;
}
{
int num = 0;
const int current_size = xcb_get_property_value_length(reply) / (reply->format / 8);
xcb_atom_t values[current_size];
for (int i = 0; i < current_size; i++) {
if (atoms[i] != atom)
values[num++] = atoms[i];
}
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, property, XCB_ATOM_ATOM, 32, num, values);
}
release_grab:
FREE(reply);
xcb_ungrab_server(conn);
}