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

View File

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

View File

@ -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,

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
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);

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);
/* 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)
{

View File

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

View File

@ -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 */

2
tag.h
View File

@ -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);