i3/src/ewmh.c
Steve Jones 0e27ff3cd0 Set EWMH desktop properties on startup.
Calls ewmh_update_current_desktop on startup to set the
_NET_CURRENT_DESKTOP property. Without this change the property only
gets set after the workspaces have been manipulated. Also exclude
hidden workspaces (i.e. those starting with "__" from the workspace
index.

Adds tests for startup and workspace switching.
2014-02-08 20:38:16 +01:00

127 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#undef I3__FILE__
#define I3__FILE__ "ewmh.c"
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
*
* ewmh.c: Get/set certain EWMH properties easily.
*
*/
#include "all.h"
/*
* Updates _NET_CURRENT_DESKTOP with the current desktop number.
*
* EWMH: The index of the current desktop. This is always an integer between 0
* and _NET_NUMBER_OF_DESKTOPS - 1.
*
*/
void ewmh_update_current_desktop(void) {
Con *focused_ws = con_get_workspace(focused);
Con *output;
uint32_t idx = 0;
/* We count to get the index of this workspace because named workspaces
* dont have the ->num property */
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
Con *ws;
TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
if (STARTS_WITH(ws->name, "__"))
continue;
if (ws == focused_ws) {
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
A__NET_CURRENT_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &idx);
return;
}
++idx;
}
}
}
/*
* Updates _NET_ACTIVE_WINDOW with the currently focused window.
*
* EWMH: The window ID of the currently active window or None if no window has
* the focus.
*
*/
void ewmh_update_active_window(xcb_window_t window) {
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
A__NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 32, 1, &window);
}
/*
* i3 currently does not support _NET_WORKAREA, because it does not correspond
* to i3s concept of workspaces. See also:
* http://bugs.i3wm.org/539
* http://bugs.i3wm.org/301
* http://bugs.i3wm.org/1038
*
* We need to actively delete this property because some display managers (e.g.
* LightDM) set it.
*
* EWMH: Contains a geometry for each desktop. These geometries specify an area
* that is completely contained within the viewport. Work area SHOULD be used by
* desktop applications to place desktop icons appropriately.
*
*/
void ewmh_update_workarea(void) {
xcb_delete_property(conn, root, A__NET_WORKAREA);
}
/*
* Updates the _NET_CLIENT_LIST_STACKING hint.
*
*/
void ewmh_update_client_list_stacking(xcb_window_t *stack, int num_windows) {
xcb_change_property(
conn,
XCB_PROP_MODE_REPLACE,
root,
A__NET_CLIENT_LIST_STACKING,
XCB_ATOM_WINDOW,
32,
num_windows,
stack);
}
/*
* Set up the EWMH hints on the root window.
*
*/
void ewmh_setup_hints(void) {
xcb_atom_t supported_atoms[] = {
#define xmacro(atom) A_ ## atom,
#include "atoms.xmacro"
#undef xmacro
};
/* Set up the window managers name. According to EWMH, section "Root Window
* Properties", to indicate that an EWMH-compliant window manager is
* present, a child window has to be created (and kept alive as long as the
* window manager is running) which has the _NET_SUPPORTING_WM_CHECK and
* _NET_WM_ATOMS. */
xcb_window_t child_window = xcb_generate_id(conn);
xcb_create_window(
conn,
XCB_COPY_FROM_PARENT, /* depth */
child_window, /* window id */
root, /* parent */
0, 0, 1, 1, /* dimensions (x, y, w, h) */
0, /* border */
XCB_WINDOW_CLASS_INPUT_ONLY, /* window class */
XCB_COPY_FROM_PARENT, /* visual */
0,
NULL);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, child_window, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &child_window);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, child_window, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &child_window);
/* Im not entirely sure if we need to keep _NET_WM_NAME on root. */
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 18, supported_atoms);
}