From 427679b0facd89cc50d72ca68909783b27a608bd Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 3 Sep 2008 14:59:18 +0200 Subject: [PATCH] client: use a type attribute for NET WM window type Signed-off-by: Julien Danjou --- client.c | 84 ++++++++++++++++++++++++------------------------------- client.h | 25 ++++++++++++++++- event.c | 4 +-- ewmh.c | 48 +++++++------------------------ mouse.c | 25 +++++++++-------- screen.c | 2 +- structs.h | 18 ++++++++---- tag.h | 2 +- 8 files changed, 99 insertions(+), 109 deletions(-) diff --git a/client.c b/client.c index 1f983e84..f0cf24ad 100644 --- a/client.c +++ b/client.c @@ -146,7 +146,7 @@ client_maybevisible(client_t *c, int screen) { if(c->screen == screen) { - if(c->issticky) + if(c->issticky || c->type == WINDOW_TYPE_DESKTOP) return true; tag_array_t *tags = &globalconf.screens[screen].tags; @@ -332,7 +332,19 @@ client_layer_translator(client_t *c) return LAYER_ABOVE; else if(c->isfloating) return LAYER_FLOAT; - return c->layer; + + switch(c->type) + { + case WINDOW_TYPE_DOCK: + return LAYER_DESKTOP; + case WINDOW_TYPE_SPLASH: + case WINDOW_TYPE_DIALOG: + return LAYER_ABOVE; + case WINDOW_TYPE_DESKTOP: + return LAYER_DESKTOP; + default: + return LAYER_TILE; + } } /** Restack clients. @@ -385,9 +397,8 @@ void client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) { xcb_get_property_cookie_t ewmh_icon_cookie; - client_t *c, *t = NULL; - xcb_window_t trans; - bool rettrans, retloadprops; + client_t *c; + bool retloadprops; const uint32_t select_input_val[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY @@ -420,7 +431,6 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) c->geometry.y = c->f_geometry.y = c->m_geometry.y = wgeom->y; c->geometry.width = c->f_geometry.width = c->m_geometry.width = wgeom->width; c->geometry.height = c->f_geometry.height = c->m_geometry.height = wgeom->height; - c->layer = LAYER_TILE; client_setborder(c, wgeom->border_width); c->icon = ewmh_window_icon_get_reply(ewmh_icon_cookie); @@ -435,23 +445,6 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) /* Then check clients hints */ ewmh_check_client_hints(c); - /* check for transient and set tags like its parent */ - if((rettrans = xcb_get_wm_transient_for_reply(globalconf.connection, - xcb_get_wm_transient_for_unchecked(globalconf.connection, - w), - &trans, NULL)) - && (t = client_getbywin(trans))) - { - tag_array_t *tags = &globalconf.screens[c->screen].tags; - for(int i = 0; i < tags->len; i++) - if(is_client_tagged(t, tags->tab[i])) - tag_client(c, tags->tab[i]); - } - - /* should be floating if transsient or fixed */ - if(rettrans || c->isfixed) - client_setfloating(c, true); - /* Push client in client list */ client_list_push(&globalconf.clients, c); client_ref(&c); @@ -533,12 +526,12 @@ client_resize(client_t *c, area_t geometry, bool hints) int new_screen; area_t area; layout_t *layout = layout_get_current(c->screen); - bool resized = false; + bool resized = false, fixed; /* Values to configure a window is an array where values are * stored according to 'value_mask' */ uint32_t values[5]; - if(c->titlebar && !c->ismoving && !c->isfloating && !c->isfullscreen && layout != layout_floating) + if(c->titlebar && !c->ismoving && !client_isfloating(c) && layout != layout_floating) geometry = titlebar_geometry_remove(c->titlebar, c->border, geometry); if(hints) @@ -551,6 +544,8 @@ client_resize(client_t *c, area_t geometry, bool hints) area = display_area_get(c->phys_screen, NULL, &globalconf.screens[c->screen].padding); + fixed = client_isfixed(c); + if(geometry.x > area.width) geometry.x = area.width - geometry.width - 2 * c->border; if(geometry.y > area.height) @@ -560,8 +555,12 @@ client_resize(client_t *c, area_t geometry, bool hints) if(geometry.y + geometry.height + 2 * c->border < 0) geometry.y = 0; - if(c->geometry.x != geometry.x || c->geometry.y != geometry.y - || c->geometry.width != geometry.width || c->geometry.height != geometry.height) + /* fixed windows can only change their x,y */ + if((fixed && (c->geometry.x != geometry.x || c->geometry.y != geometry.y)) + || (!fixed && (c->geometry.x != geometry.x + || c->geometry.y != geometry.y + || c->geometry.width != geometry.width + || c->geometry.height != geometry.height))) { new_screen = screen_get_bycoord(globalconf.screens_info, c->screen, geometry.x, geometry.y); @@ -574,7 +573,7 @@ client_resize(client_t *c, area_t geometry, bool hints) /* save the floating geometry if the window is floating but not * maximized */ - if(c->ismoving || c->isfloating + if(c->ismoving || client_isfloating(c) || layout_get_current(new_screen) == layout_floating) { titlebar_update_geometry_floating(c); @@ -597,23 +596,12 @@ client_resize(client_t *c, area_t geometry, bool hints) /* call it again like it was floating, * we want it to be sticked to the window */ - if(!c->ismoving && !c->isfloating && layout != layout_floating) + if(!c->ismoving && !client_isfloating(c) && layout != layout_floating) titlebar_update_geometry_floating(c); return resized; } -/* Set the client layer. - * \param c The client. - * \param layer The layer. - */ -void -client_setlayer(client_t *c, layer_t layer) -{ - c->layer = layer; - client_raise(c); -} - /** Set a clinet floating. * \param c The client. * \param floating Set floating, or not. @@ -683,7 +671,6 @@ client_setfullscreen(client_t *c, bool s) c->m_geometry = c->geometry; c->oldborder = c->border; client_setborder(c, 0); - c->noborder = true; } else { @@ -691,7 +678,6 @@ client_setfullscreen(client_t *c, bool s) if(c->titlebar && c->titlebar->sw && (c->titlebar->position = c->titlebar->oldposition)) xcb_map_window(globalconf.connection, c->titlebar->sw->window); geometry = c->m_geometry; - c->noborder = false; client_setborder(c, c->oldborder); client_resize(c, c->m_geometry, false); } @@ -936,10 +922,6 @@ client_updatesizehints(client_t *c) else c->minax = c->maxax = c->minay = c->maxay = 0; - if(c->maxw && c->minw && c->maxh && c->minh - && c->maxw == c->minw && c->maxh == c->minh) - c->isfixed = true; - c->hassizehints = !(!c->basew && !c->baseh && !c->incw && !c->inch && !c->maxw && !c->maxh && !c->minw && !c->minh && !c->minax && !c->maxax && !c->minax && !c->minay); @@ -1031,7 +1013,13 @@ client_setborder(client_t *c, int width) { uint32_t w = width; - if((c->noborder && width > 0) || width == c->border || width < 0) + if(width > 0 && (c->type == WINDOW_TYPE_DOCK + || c->type == WINDOW_TYPE_SPLASH + || c->type == WINDOW_TYPE_DESKTOP + || c->isfullscreen)) + return; + + if(width == c->border || width < 0) return; c->border = width; @@ -1040,7 +1028,7 @@ client_setborder(client_t *c, int width) if(client_isvisible(c, c->screen)) { - if(c->isfloating || layout_get_current(c->screen) == layout_floating) + if(client_isfloating(c) || layout_get_current(c->screen) == layout_floating) titlebar_update_geometry_floating(c); else globalconf.screens[c->screen].need_arrange = true; diff --git a/client.h b/client.h index f60f74f1..4618fa7f 100644 --- a/client.h +++ b/client.h @@ -37,7 +37,6 @@ bool client_maybevisible(client_t *, int); bool client_isvisible(client_t *, int); client_t * client_getbywin(xcb_window_t); -void client_setlayer(client_t *, layer_t); void client_stack(void); void client_ban(client_t *); void client_unban(client_t *); @@ -76,6 +75,30 @@ client_raise(client_t *c) client_stack(); } +/** Check if a client has fixed size. + * \param c A client. + * \return A boolean value, true if the client has a fixed size. + */ +static inline bool +client_isfixed(client_t *c) +{ + return (c->maxw && c->minw && c->maxh && c->minh + && c->maxw == c->minw && c->maxh == c->minh); + +} + +/** Check if a client is floating. + * \param c A client. + * \return A boolean value, true if the client is floating. + */ +static inline bool +client_isfloating(client_t *c) +{ + return (c->type != WINDOW_TYPE_NORMAL + || c->isfloating + || c->isfullscreen + || client_isfixed(c)); +} #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/event.c b/event.c index 3270c955..14d6a753 100644 --- a/event.c +++ b/event.c @@ -213,7 +213,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), if(geometry.x != c->geometry.x || geometry.y != c->geometry.y || geometry.width != c->geometry.width || geometry.height != c->geometry.height) { - if(c->isfloating || c->isfullscreen || layout_get_current(c->screen) == layout_floating) + if(client_isfloating(c) || layout_get_current(c->screen) == layout_floating) { client_resize(c, geometry, false); titlebar_draw(c); @@ -641,7 +641,7 @@ event_handle_propertynotify(void *data __attribute__ ((unused)), { if(ev->atom == WM_TRANSIENT_FOR) { - if(!c->isfloating && !c->isfullscreen) + if(!client_isfloating(c)) { xcb_window_t trans; xcb_get_wm_transient_for_reply(connection, diff --git a/ewmh.c b/ewmh.c index bcca6b0d..2b267a20 100644 --- a/ewmh.c +++ b/ewmh.c @@ -319,43 +319,6 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) } } -static void -ewmh_process_window_type_atom(client_t *c, xcb_atom_t state) -{ - if(state == _NET_WM_WINDOW_TYPE_NORMAL) - { - /* do nothing. this is REALLY IMPORTANT */ - } - else if(state == _NET_WM_WINDOW_TYPE_DOCK - || state == _NET_WM_WINDOW_TYPE_SPLASH) - { - c->isfixed = true; - if(c->titlebar && c->titlebar->position && c->titlebar->sw) - { - xcb_unmap_window(globalconf.connection, c->titlebar->sw->window); - c->titlebar->position = Off; - } - client_setborder(c, 0); - c->noborder = true; - client_setlayer(c, LAYER_ABOVE); - client_setfloating(c, true); - } - else if(state == _NET_WM_WINDOW_TYPE_DIALOG) - { - client_setlayer(c, LAYER_MODAL); - client_setfloating(c, true); - } - else if(state == _NET_WM_WINDOW_TYPE_DESKTOP) - { - tag_array_t *tags = &globalconf.screens[c->screen].tags; - c->noborder = true; - c->isfixed = true; - client_setlayer(c, LAYER_DESKTOP); - for(int i = 0; i < tags->len; i++) - tag_client(c, tags->tab[i]); - } -} - int ewmh_process_client_message(xcb_client_message_event_t *ev) { @@ -457,7 +420,16 @@ ewmh_check_client_hints(client_t *c) { state = (xcb_atom_t *) data; for(int i = 0; i < xcb_get_property_value_length(reply); i++) - ewmh_process_window_type_atom(c, state[i]); + if(state[i] == _NET_WM_WINDOW_TYPE_DESKTOP) + c->type = WINDOW_TYPE_DESKTOP; + else if(state[i] == _NET_WM_WINDOW_TYPE_DIALOG) + c->type = WINDOW_TYPE_DIALOG; + else if(state[i] == _NET_WM_WINDOW_TYPE_SPLASH) + c->type = WINDOW_TYPE_SPLASH; + else if(state[i] == _NET_WM_WINDOW_TYPE_DOCK) + c->type = WINDOW_TYPE_DOCK; + else + c->type = WINDOW_TYPE_NORMAL; } p_delete(&reply); diff --git a/mouse.c b/mouse.c index 3267d3c1..5d4b4bb3 100644 --- a/mouse.c +++ b/mouse.c @@ -496,15 +496,19 @@ mouse_client_move(client_t *c, int snap, bool infobox) mouse_query_pointer(root, &last_x, &last_y, NULL); /* grab pointer */ - if(c->isfullscreen || !mouse_grab_pointer(root, CurMove)) + if(c->isfullscreen + || c->type == WINDOW_TYPE_DESKTOP + || c->type == WINDOW_TYPE_SPLASH + || c->type == WINDOW_TYPE_DOCK + || !mouse_grab_pointer(root, CurMove)) return; - if(infobox && (c->isfloating || layout == layout_floating)) + if(infobox && (client_isfloating(c) || layout == layout_floating)) sw = mouse_infobox_new(c->phys_screen, c->border, c->geometry, &ctx); /* for each motion event */ while(mouse_track_mouse_drag(&mouse_x, &mouse_y)) - if(c->isfloating || layout == layout_floating) + if(client_isfloating(c) || layout == layout_floating) { area_t geometry; @@ -517,6 +521,7 @@ mouse_client_move(client_t *c, int snap, bool infobox) geometry = mouse_snapclient(c, geometry, snap); c->ismoving = true; client_resize(c, geometry, false); + xcb_flush(globalconf.connection); c->ismoving = false; /* draw the infobox */ @@ -943,7 +948,10 @@ mouse_client_resize(client_t *c, corner_t corner, bool infobox) layout_t *layout; xcb_screen_t *s; - if(c->isfullscreen) + if(c->isfullscreen + || c->type == WINDOW_TYPE_DESKTOP + || c->type == WINDOW_TYPE_SPLASH + || c->type == WINDOW_TYPE_DOCK) return; curtags = tags_get_current(c->screen); @@ -951,15 +959,8 @@ mouse_client_resize(client_t *c, corner_t corner, bool infobox) s = xutil_screen_get(globalconf.connection, c->phys_screen); /* only handle floating, tiled and magnifier layouts */ - if(layout == layout_floating || c->isfloating) - { - if(c->isfixed) - goto bailout; - - client_setfullscreen(c, false); - + if(layout == layout_floating || client_isfloating(c)) mouse_client_resize_floating(c, corner, infobox); - } else if(layout == layout_tile || layout == layout_tileleft || layout == layout_tilebottom || layout == layout_tiletop) { diff --git a/screen.c b/screen.c index e1cb035f..17dad32f 100644 --- a/screen.c +++ b/screen.c @@ -205,7 +205,7 @@ screen_client_moveto(client_t *c, int new_screen, bool doresize) client_resize(c, new_geometry, false); } /* if floating, move to this new coords */ - else if(c->isfloating) + else if(client_isfloating(c)) client_resize(c, new_f_geometry, false); /* otherwise just register them */ else diff --git a/structs.h b/structs.h index 8d03acbc..ee0d5145 100644 --- a/structs.h +++ b/structs.h @@ -49,6 +49,16 @@ typedef enum LAYER_OUTOFSPACE } layer_t; +/** Windows type */ +typedef enum +{ + WINDOW_TYPE_NORMAL = 0, + WINDOW_TYPE_DESKTOP, + WINDOW_TYPE_DOCK, + WINDOW_TYPE_SPLASH, + WINDOW_TYPE_DIALOG, +} window_type_t; + /** Cursors */ enum { @@ -274,16 +284,12 @@ struct client_t bool honorsizehints; int border, oldborder; xcolor_t border_color; - /** True if the client does not want any border */ - bool noborder; /** True if the client is sticky */ bool issticky; /** Has urgency hint */ bool isurgent; /** true if the window is floating */ bool isfloating; - /** true if the window is fixed */ - bool isfixed; /** true if the client is moving */ bool ismoving; /** True if the client is hidden */ @@ -300,14 +306,14 @@ struct client_t bool isontop; /** true if the client must be skipped from task bar client list */ bool skiptb; + /** The window type */ + window_type_t type; /** Window of the client */ xcb_window_t win; /** Client logical screen */ int screen; /** Client physical screen */ int phys_screen; - /** Layer in the stacking order */ - layer_t layer; /** Path to an icon */ char *icon_path; /** Titlebar */ diff --git a/tag.h b/tag.h index 6f2f7ed2..7e39ef4d 100644 --- a/tag.h +++ b/tag.h @@ -26,7 +26,7 @@ #include "common/refcount.h" /** Check if a client is tiled */ -#define IS_TILED(client, screen) (client && !client->isfloating && !client->isfullscreen && client_isvisible(client, screen)) +#define IS_TILED(client, screen) (client && !client_isfloating(client) && client_isvisible(client, screen)) /* Contructor, destructor and referencors */ tag_t *tag_new(const char *, ssize_t, layout_t *, double, int, int);