client: use a type attribute for NET WM window type

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-09-03 14:59:18 +02:00
parent 34d49ac4ee
commit 427679b0fa
8 changed files with 99 additions and 109 deletions

View File

@ -146,7 +146,7 @@ client_maybevisible(client_t *c, int screen)
{ {
if(c->screen == screen) if(c->screen == screen)
{ {
if(c->issticky) if(c->issticky || c->type == WINDOW_TYPE_DESKTOP)
return true; return true;
tag_array_t *tags = &globalconf.screens[screen].tags; tag_array_t *tags = &globalconf.screens[screen].tags;
@ -332,7 +332,19 @@ client_layer_translator(client_t *c)
return LAYER_ABOVE; return LAYER_ABOVE;
else if(c->isfloating) else if(c->isfloating)
return LAYER_FLOAT; 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. /** Restack clients.
@ -385,9 +397,8 @@ void
client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen)
{ {
xcb_get_property_cookie_t ewmh_icon_cookie; xcb_get_property_cookie_t ewmh_icon_cookie;
client_t *c, *t = NULL; client_t *c;
xcb_window_t trans; bool retloadprops;
bool rettrans, retloadprops;
const uint32_t select_input_val[] = const uint32_t select_input_val[] =
{ {
XCB_EVENT_MASK_STRUCTURE_NOTIFY 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.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.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->geometry.height = c->f_geometry.height = c->m_geometry.height = wgeom->height;
c->layer = LAYER_TILE;
client_setborder(c, wgeom->border_width); client_setborder(c, wgeom->border_width);
c->icon = ewmh_window_icon_get_reply(ewmh_icon_cookie); 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 */ /* Then check clients hints */
ewmh_check_client_hints(c); 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 */ /* Push client in client list */
client_list_push(&globalconf.clients, c); client_list_push(&globalconf.clients, c);
client_ref(&c); client_ref(&c);
@ -533,12 +526,12 @@ client_resize(client_t *c, area_t geometry, bool hints)
int new_screen; int new_screen;
area_t area; area_t area;
layout_t *layout = layout_get_current(c->screen); 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 /* Values to configure a window is an array where values are
* stored according to 'value_mask' */ * stored according to 'value_mask' */
uint32_t values[5]; 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); geometry = titlebar_geometry_remove(c->titlebar, c->border, geometry);
if(hints) if(hints)
@ -551,6 +544,8 @@ client_resize(client_t *c, area_t geometry, bool hints)
area = display_area_get(c->phys_screen, NULL, area = display_area_get(c->phys_screen, NULL,
&globalconf.screens[c->screen].padding); &globalconf.screens[c->screen].padding);
fixed = client_isfixed(c);
if(geometry.x > area.width) if(geometry.x > area.width)
geometry.x = area.width - geometry.width - 2 * c->border; geometry.x = area.width - geometry.width - 2 * c->border;
if(geometry.y > area.height) 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) if(geometry.y + geometry.height + 2 * c->border < 0)
geometry.y = 0; geometry.y = 0;
if(c->geometry.x != geometry.x || c->geometry.y != geometry.y /* fixed windows can only change their x,y */
|| c->geometry.width != geometry.width || c->geometry.height != geometry.height) 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 = new_screen =
screen_get_bycoord(globalconf.screens_info, c->screen, geometry.x, geometry.y); 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 /* save the floating geometry if the window is floating but not
* maximized */ * maximized */
if(c->ismoving || c->isfloating if(c->ismoving || client_isfloating(c)
|| layout_get_current(new_screen) == layout_floating) || layout_get_current(new_screen) == layout_floating)
{ {
titlebar_update_geometry_floating(c); 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, /* call it again like it was floating,
* we want it to be sticked to the window */ * 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); titlebar_update_geometry_floating(c);
return resized; 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. /** Set a clinet floating.
* \param c The client. * \param c The client.
* \param floating Set floating, or not. * \param floating Set floating, or not.
@ -683,7 +671,6 @@ client_setfullscreen(client_t *c, bool s)
c->m_geometry = c->geometry; c->m_geometry = c->geometry;
c->oldborder = c->border; c->oldborder = c->border;
client_setborder(c, 0); client_setborder(c, 0);
c->noborder = true;
} }
else else
{ {
@ -691,7 +678,6 @@ client_setfullscreen(client_t *c, bool s)
if(c->titlebar && c->titlebar->sw && (c->titlebar->position = c->titlebar->oldposition)) if(c->titlebar && c->titlebar->sw && (c->titlebar->position = c->titlebar->oldposition))
xcb_map_window(globalconf.connection, c->titlebar->sw->window); xcb_map_window(globalconf.connection, c->titlebar->sw->window);
geometry = c->m_geometry; geometry = c->m_geometry;
c->noborder = false;
client_setborder(c, c->oldborder); client_setborder(c, c->oldborder);
client_resize(c, c->m_geometry, false); client_resize(c, c->m_geometry, false);
} }
@ -936,10 +922,6 @@ client_updatesizehints(client_t *c)
else else
c->minax = c->maxax = c->minay = c->maxay = 0; 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->hassizehints = !(!c->basew && !c->baseh && !c->incw && !c->inch
&& !c->maxw && !c->maxh && !c->minw && !c->minh && !c->maxw && !c->maxh && !c->minw && !c->minh
&& !c->minax && !c->maxax && !c->minax && !c->minay); && !c->minax && !c->maxax && !c->minax && !c->minay);
@ -1031,7 +1013,13 @@ client_setborder(client_t *c, int width)
{ {
uint32_t w = 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; return;
c->border = width; c->border = width;
@ -1040,7 +1028,7 @@ client_setborder(client_t *c, int width)
if(client_isvisible(c, c->screen)) 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); titlebar_update_geometry_floating(c);
else else
globalconf.screens[c->screen].need_arrange = true; globalconf.screens[c->screen].need_arrange = true;

View File

@ -37,7 +37,6 @@
bool client_maybevisible(client_t *, int); bool client_maybevisible(client_t *, int);
bool client_isvisible(client_t *, int); bool client_isvisible(client_t *, int);
client_t * client_getbywin(xcb_window_t); client_t * client_getbywin(xcb_window_t);
void client_setlayer(client_t *, layer_t);
void client_stack(void); void client_stack(void);
void client_ban(client_t *); void client_ban(client_t *);
void client_unban(client_t *); void client_unban(client_t *);
@ -76,6 +75,30 @@ client_raise(client_t *c)
client_stack(); 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 #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -213,7 +213,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)),
if(geometry.x != c->geometry.x || geometry.y != c->geometry.y if(geometry.x != c->geometry.x || geometry.y != c->geometry.y
|| geometry.width != c->geometry.width || geometry.height != c->geometry.height) || 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); client_resize(c, geometry, false);
titlebar_draw(c); titlebar_draw(c);
@ -641,7 +641,7 @@ event_handle_propertynotify(void *data __attribute__ ((unused)),
{ {
if(ev->atom == WM_TRANSIENT_FOR) if(ev->atom == WM_TRANSIENT_FOR)
{ {
if(!c->isfloating && !c->isfullscreen) if(!client_isfloating(c))
{ {
xcb_window_t trans; xcb_window_t trans;
xcb_get_wm_transient_for_reply(connection, xcb_get_wm_transient_for_reply(connection,

48
ewmh.c
View File

@ -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 int
ewmh_process_client_message(xcb_client_message_event_t *ev) 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; state = (xcb_atom_t *) data;
for(int i = 0; i < xcb_get_property_value_length(reply); i++) 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); p_delete(&reply);

25
mouse.c
View File

@ -496,15 +496,19 @@ mouse_client_move(client_t *c, int snap, bool infobox)
mouse_query_pointer(root, &last_x, &last_y, NULL); mouse_query_pointer(root, &last_x, &last_y, NULL);
/* grab pointer */ /* 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; 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); sw = mouse_infobox_new(c->phys_screen, c->border, c->geometry, &ctx);
/* for each motion event */ /* for each motion event */
while(mouse_track_mouse_drag(&mouse_x, &mouse_y)) 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; area_t geometry;
@ -517,6 +521,7 @@ mouse_client_move(client_t *c, int snap, bool infobox)
geometry = mouse_snapclient(c, geometry, snap); geometry = mouse_snapclient(c, geometry, snap);
c->ismoving = true; c->ismoving = true;
client_resize(c, geometry, false); client_resize(c, geometry, false);
xcb_flush(globalconf.connection);
c->ismoving = false; c->ismoving = false;
/* draw the infobox */ /* draw the infobox */
@ -943,7 +948,10 @@ mouse_client_resize(client_t *c, corner_t corner, bool infobox)
layout_t *layout; layout_t *layout;
xcb_screen_t *s; 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; return;
curtags = tags_get_current(c->screen); 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); s = xutil_screen_get(globalconf.connection, c->phys_screen);
/* only handle floating, tiled and magnifier layouts */ /* only handle floating, tiled and magnifier layouts */
if(layout == layout_floating || c->isfloating) if(layout == layout_floating || client_isfloating(c))
{
if(c->isfixed)
goto bailout;
client_setfullscreen(c, false);
mouse_client_resize_floating(c, corner, infobox); mouse_client_resize_floating(c, corner, infobox);
}
else if(layout == layout_tile || layout == layout_tileleft else if(layout == layout_tile || layout == layout_tileleft
|| layout == layout_tilebottom || layout == layout_tiletop) || layout == layout_tilebottom || layout == layout_tiletop)
{ {

View File

@ -205,7 +205,7 @@ screen_client_moveto(client_t *c, int new_screen, bool doresize)
client_resize(c, new_geometry, false); client_resize(c, new_geometry, false);
} }
/* if floating, move to this new coords */ /* if floating, move to this new coords */
else if(c->isfloating) else if(client_isfloating(c))
client_resize(c, new_f_geometry, false); client_resize(c, new_f_geometry, false);
/* otherwise just register them */ /* otherwise just register them */
else else

View File

@ -49,6 +49,16 @@ typedef enum
LAYER_OUTOFSPACE LAYER_OUTOFSPACE
} layer_t; } 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 */ /** Cursors */
enum enum
{ {
@ -274,16 +284,12 @@ struct client_t
bool honorsizehints; bool honorsizehints;
int border, oldborder; int border, oldborder;
xcolor_t border_color; xcolor_t border_color;
/** True if the client does not want any border */
bool noborder;
/** True if the client is sticky */ /** True if the client is sticky */
bool issticky; bool issticky;
/** Has urgency hint */ /** Has urgency hint */
bool isurgent; bool isurgent;
/** true if the window is floating */ /** true if the window is floating */
bool isfloating; bool isfloating;
/** true if the window is fixed */
bool isfixed;
/** true if the client is moving */ /** true if the client is moving */
bool ismoving; bool ismoving;
/** True if the client is hidden */ /** True if the client is hidden */
@ -300,14 +306,14 @@ struct client_t
bool isontop; bool isontop;
/** true if the client must be skipped from task bar client list */ /** true if the client must be skipped from task bar client list */
bool skiptb; bool skiptb;
/** The window type */
window_type_t type;
/** Window of the client */ /** Window of the client */
xcb_window_t win; xcb_window_t win;
/** Client logical screen */ /** Client logical screen */
int screen; int screen;
/** Client physical screen */ /** Client physical screen */
int phys_screen; int phys_screen;
/** Layer in the stacking order */
layer_t layer;
/** Path to an icon */ /** Path to an icon */
char *icon_path; char *icon_path;
/** Titlebar */ /** Titlebar */

2
tag.h
View File

@ -26,7 +26,7 @@
#include "common/refcount.h" #include "common/refcount.h"
/** Check if a client is tiled */ /** 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 */ /* Contructor, destructor and referencors */
tag_t *tag_new(const char *, ssize_t, layout_t *, double, int, int); tag_t *tag_new(const char *, ssize_t, layout_t *, double, int, int);