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 && |