Improved detection of windows that want floating
Patch status: needinfo
Patch by Kernc
Long description:
Windows that match certain criteria are floated by default. The criteria established by this revision are: * dialog, utility, toolbar, splash, or notification windows, * modal windows, or * windows that have specified equal minimum and maximum size. Closes ticket #1182.
To apply this patch, use:
curl http://cr.i3wm.org/patch/427/raw.patch | git am
b/include/atoms.xmacro
22 |
@@ -3,6 +3,7 @@ xmacro(_NET_SUPPORTING_WM_CHECK) |
23 |
xmacro(_NET_WM_NAME) |
24 |
xmacro(_NET_WM_STATE_FULLSCREEN) |
25 |
xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) |
26 |
+xmacro(_NET_WM_STATE_MODAL) |
27 |
xmacro(_NET_WM_STATE) |
28 |
xmacro(_NET_WM_WINDOW_TYPE) |
29 |
xmacro(_NET_WM_WINDOW_TYPE_DOCK) |
30 |
@@ -10,6 +11,8 @@ xmacro(_NET_WM_WINDOW_TYPE_DIALOG) |
31 |
xmacro(_NET_WM_WINDOW_TYPE_UTILITY) |
32 |
xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR) |
33 |
xmacro(_NET_WM_WINDOW_TYPE_SPLASH) |
34 |
+xmacro(_NET_WM_WINDOW_TYPE_DESKTOP) |
35 |
+xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION) |
36 |
xmacro(_NET_WM_DESKTOP) |
37 |
xmacro(_NET_WM_STRUT_PARTIAL) |
38 |
xmacro(_NET_CLIENT_LIST_STACKING) |
b/include/xcb_compat.h
43 |
@@ -19,9 +19,12 @@ |
44 |
#define XCB_ICCCM_WM_STATE_NORMAL XCB_WM_STATE_NORMAL |
45 |
#define XCB_ICCCM_WM_STATE_WITHDRAWN XCB_WM_STATE_WITHDRAWN |
46 |
#define xcb_icccm_get_wm_size_hints_from_reply xcb_get_wm_size_hints_from_reply |
47 |
+#define xcb_icccm_get_wm_size_hints_reply xcb_get_wm_size_hints_reply |
48 |
+#define xcb_icccm_get_wm_normal_hints xcb_get_wm_normal_hints |
49 |
#define xcb_icccm_get_wm_normal_hints_reply xcb_get_wm_normal_hints_reply |
50 |
#define xcb_icccm_get_wm_normal_hints_unchecked xcb_get_wm_normal_hints_unchecked |
51 |
#define XCB_ICCCM_SIZE_HINT_P_MIN_SIZE XCB_SIZE_HINT_P_MIN_SIZE |
52 |
+#define XCB_ICCCM_SIZE_HINT_P_MAX_SIZE XCB_SIZE_HINT_P_MAX_SIZE |
53 |
#define XCB_ICCCM_SIZE_HINT_P_RESIZE_INC XCB_SIZE_HINT_P_RESIZE_INC |
54 |
#define XCB_ICCCM_SIZE_HINT_BASE_SIZE XCB_SIZE_HINT_BASE_SIZE |
55 |
#define XCB_ICCCM_SIZE_HINT_P_ASPECT XCB_SIZE_HINT_P_ASPECT |
b/src/manage.c
60 |
@@ -119,7 +119,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
61 |
utf8_title_cookie, title_cookie, |
62 |
class_cookie, leader_cookie, transient_cookie, |
63 |
role_cookie, startup_id_cookie, wm_hints_cookie, |
64 |
- motif_wm_hints_cookie; |
65 |
+ wm_normal_hints_cookie, motif_wm_hints_cookie; |
66 |
|
67 |
|
68 |
geomc = xcb_get_geometry(conn, d); |
69 |
@@ -189,8 +189,8 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
70 |
role_cookie = GET_PROPERTY(A_WM_WINDOW_ROLE, 128); |
71 |
startup_id_cookie = GET_PROPERTY(A__NET_STARTUP_ID, 512); |
72 |
wm_hints_cookie = xcb_icccm_get_wm_hints(conn, window); |
73 |
+ wm_normal_hints_cookie = xcb_icccm_get_wm_normal_hints(conn, window); |
74 |
motif_wm_hints_cookie = GET_PROPERTY(A__MOTIF_WM_HINTS, 5 * sizeof(uint64_t)); |
75 |
- /* TODO: also get wm_normal_hints here. implement after we got rid of xcb-event */ |
76 |
|
77 |
DLOG("Managing window 0x%08x\n", window); |
78 |
|
79 |
@@ -226,6 +226,8 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
80 |
window_update_hints(cwindow, xcb_get_property_reply(conn, wm_hints_cookie, NULL), &urgency_hint); |
81 |
border_style_t motif_border_style = BS_NORMAL; |
82 |
window_update_motif_hints(cwindow, xcb_get_property_reply(conn, motif_wm_hints_cookie, NULL), &motif_border_style); |
83 |
+ xcb_size_hints_t wm_size_hints; |
84 |
+ xcb_icccm_get_wm_size_hints_reply(conn, wm_normal_hints_cookie, &wm_size_hints, NULL); |
85 |
|
86 |
xcb_get_property_reply_t *startup_id_reply; |
87 |
startup_id_reply = xcb_get_property_reply(conn, startup_id_cookie, NULL); |
88 |
@@ -238,8 +240,8 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
89 |
/* Where to start searching for a container that swallows the new one? */ |
90 |
Con *search_at = croot; |
91 |
|
92 |
- xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, wm_type_cookie, NULL); |
93 |
- if (xcb_reply_contains_atom(reply, A__NET_WM_WINDOW_TYPE_DOCK)) { |
94 |
+ xcb_get_property_reply_t *type_reply = xcb_get_property_reply(conn, wm_type_cookie, NULL); |
95 |
+ if (xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_DOCK)) { |
96 |
LOG("This window is of type dock\n"); |
97 |
Output *output = get_output_containing(geom->x, geom->y); |
98 |
if (output != NULL) { |
99 |
@@ -358,8 +360,6 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
100 |
con_toggle_fullscreen(nc, CF_OUTPUT); |
101 |
} |
102 |
|
103 |
- FREE(state_reply); |
104 |
- |
105 |
if (fs == NULL) { |
106 |
DLOG("Not in fullscreen mode, focusing\n"); |
107 |
if (!cwindow->dock) { |
108 |
@@ -392,15 +392,23 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki |
109 |
|
110 |
/* set floating if necessary */ |
111 |
bool want_floating = false; |
112 |
- if (xcb_reply_contains_atom(reply, A__NET_WM_WINDOW_TYPE_DIALOG) || |
113 |
- xcb_reply_contains_atom(reply, A__NET_WM_WINDOW_TYPE_UTILITY) || |
114 |
- xcb_reply_contains_atom(reply, A__NET_WM_WINDOW_TYPE_TOOLBAR) || |
115 |
- xcb_reply_contains_atom(reply, A__NET_WM_WINDOW_TYPE_SPLASH)) { |
116 |
+ if (xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_DIALOG) || |
117 |
+ xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_UTILITY) || |
118 |
+ xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_TOOLBAR) || |
119 |
+ xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_SPLASH) || |
120 |
+ xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_NOTIFICATION) || |
121 |
+ (!xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_DESKTOP) && |
122 |
+ (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_MODAL) || |
123 |
+ (wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE && |
124 |
+ wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE && |
125 |
+ wm_size_hints.min_height == wm_size_hints.max_height && |
126 |
+ wm_size_hints.min_width == wm_size_hints.max_width)))) { |
127 |
LOG("This window is a dialog window, setting floating\n"); |
128 |
want_floating = true; |
129 |
} |
130 |
|
131 |
- FREE(reply); |
132 |
+ FREE(state_reply); |
133 |
+ FREE(type_reply); |
134 |
|
135 |
if (cwindow->transient_for != XCB_NONE || |
136 |
(cwindow->leader != XCB_NONE && |