feature: implement ewmh desktop viewport property
Patch status: merged
Patch by Tony Crisci
Long description:
Set and update the _NET_DESKTOP_VIEWPORT property http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140146176862048 > _NET_DESKTOP_VIEWPORT x, y, CARDINAL[][2]/32 > Array of pairs of cardinals that define the top left corner of each > desktop's viewport.
To apply this patch, use:
curl http://cr.i3wm.org/patch/603/raw.patch | git am
b/include/atoms.xmacro
24 |
@@ -17,6 +17,7 @@ xmacro(_NET_CLIENT_LIST) |
25 |
xmacro(_NET_CLIENT_LIST_STACKING) |
26 |
xmacro(_NET_CURRENT_DESKTOP) |
27 |
xmacro(_NET_NUMBER_OF_DESKTOPS) |
28 |
+xmacro(_NET_DESKTOP_VIEWPORT) |
29 |
xmacro(_NET_ACTIVE_WINDOW) |
30 |
xmacro(_NET_STARTUP_ID) |
31 |
xmacro(_NET_WORKAREA) |
b/include/ewmh.h
36 |
@@ -25,6 +25,12 @@ void ewmh_update_current_desktop(void); |
37 |
void ewmh_update_number_of_desktops(void); |
38 |
|
39 |
/** |
40 |
+ * Updates _NET_DESKTOP_VIEWPORT, which is an array of pairs of cardinals that |
41 |
+ * define the top left corner of each desktop's viewport. |
42 |
+ */ |
43 |
+void ewmh_update_desktop_viewport(void); |
44 |
+ |
45 |
+/** |
46 |
* Updates _NET_ACTIVE_WINDOW with the currently focused window. |
47 |
* |
48 |
* EWMH: The window ID of the currently active window or None if no window has |
b/src/ewmh.c
53 |
@@ -62,6 +62,43 @@ void ewmh_update_number_of_desktops(void) { |
54 |
} |
55 |
|
56 |
/* |
57 |
+ * Updates _NET_DESKTOP_VIEWPORT, which is an array of pairs of cardinals that |
58 |
+ * define the top left corner of each desktop's viewport. |
59 |
+ */ |
60 |
+void ewmh_update_desktop_viewport(void) { |
61 |
+ Con *output; |
62 |
+ int num_desktops = 0; |
63 |
+ /* count number of desktops */ |
64 |
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { |
65 |
+ Con *ws; |
66 |
+ TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) { |
67 |
+ if (STARTS_WITH(ws->name, "__")) |
68 |
+ continue; |
69 |
+ |
70 |
+ num_desktops++; |
71 |
+ } |
72 |
+ } |
73 |
+ |
74 |
+ uint32_t viewports[num_desktops * 2]; |
75 |
+ |
76 |
+ int current_position = 0; |
77 |
+ /* fill the viewport buffer */ |
78 |
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { |
79 |
+ Con *ws; |
80 |
+ TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) { |
81 |
+ if (STARTS_WITH(ws->name, "__")) |
82 |
+ continue; |
83 |
+ |
84 |
+ viewports[current_position++] = output->rect.x; |
85 |
+ viewports[current_position++] = output->rect.y; |
86 |
+ } |
87 |
+ } |
88 |
+ |
89 |
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, |
90 |
+ A__NET_DESKTOP_VIEWPORT, XCB_ATOM_CARDINAL, 32, current_position, &viewports); |
91 |
+} |
92 |
+ |
93 |
+/* |
94 |
* Updates _NET_ACTIVE_WINDOW with the currently focused window. |
95 |
* |
96 |
* EWMH: The window ID of the currently active window or None if no window has |
97 |
@@ -159,5 +196,5 @@ void ewmh_setup_hints(void) { |
98 |
/* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */ |
99 |
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3"); |
100 |
|
101 |
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 19, supported_atoms); |
102 |
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 20, supported_atoms); |
103 |
} |
b/src/main.c
108 |
@@ -674,6 +674,7 @@ int main(int argc, char *argv[]) { |
109 |
/* Set the ewmh desktop properties. */ |
110 |
ewmh_update_current_desktop(); |
111 |
ewmh_update_number_of_desktops(); |
112 |
+ ewmh_update_desktop_viewport(); |
113 |
|
114 |
struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io)); |
115 |
xcb_check = scalloc(sizeof(struct ev_check)); |
b/src/workspace.c
120 |
@@ -93,6 +93,7 @@ Con *workspace_get(const char *num, bool *created) { |
121 |
|
122 |
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}"); |
123 |
ewmh_update_number_of_desktops(); |
124 |
+ ewmh_update_desktop_viewport(); |
125 |
if (created != NULL) |
126 |
*created = true; |
127 |
} else if (created != NULL) { |
128 |
@@ -426,6 +427,7 @@ static void _workspace_show(Con *workspace) { |
129 |
tree_close(old, DONT_KILL_WINDOW, false, false); |
130 |
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"empty\"}"); |
131 |
ewmh_update_number_of_desktops(); |
132 |
+ ewmh_update_desktop_viewport(); |
133 |
} |
134 |
} |
135 |
|