ewmh: add support for _NET_WM_STRUT_PARTIAL
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
6b901356e2
commit
fcde8d229b
14
client.c
14
client.c
|
@ -34,6 +34,7 @@
|
|||
#include "lua.h"
|
||||
#include "mouse.h"
|
||||
#include "systray.h"
|
||||
#include "statusbar.h"
|
||||
#include "layouts/floating.h"
|
||||
#include "common/markup.h"
|
||||
#include "common/atoms.h"
|
||||
|
@ -457,6 +458,9 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen)
|
|||
/* update window title */
|
||||
client_updatetitle(c);
|
||||
|
||||
/* update strut */
|
||||
ewmh_client_strut_update(c);
|
||||
|
||||
ewmh_update_net_client_list(c->phys_screen);
|
||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||
|
||||
|
@ -668,9 +672,7 @@ client_setfullscreen(client_t *c, bool s)
|
|||
xcb_unmap_window(globalconf.connection, c->titlebar->sw->window);
|
||||
c->titlebar->position = Off;
|
||||
}
|
||||
geometry = screen_area_get(&globalconf.screens[c->screen].geometry,
|
||||
NULL,
|
||||
&globalconf.screens[c->screen].padding);
|
||||
geometry = screen_area_get(c->screen, NULL, &globalconf.screens[c->screen].padding, false);
|
||||
c->m_geometry = c->geometry;
|
||||
c->oldborder = c->border;
|
||||
client_setborder(c, 0);
|
||||
|
@ -826,6 +828,12 @@ client_unmanage(client_t *c)
|
|||
xcb_delete_property(globalconf.connection, c->win, _AWESOME_TAGS);
|
||||
xcb_delete_property(globalconf.connection, c->win, _AWESOME_FLOATING);
|
||||
|
||||
if(client_hasstrut(c))
|
||||
/* All the statusbars (may) need to be repositioned */
|
||||
for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++)
|
||||
for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next)
|
||||
statusbar_position_update(s);
|
||||
|
||||
/* set client as invalid */
|
||||
c->invalid = true;
|
||||
|
||||
|
|
21
client.h
21
client.h
|
@ -100,5 +100,26 @@ client_isfloating(client_t *c)
|
|||
|| client_isfixed(c));
|
||||
}
|
||||
|
||||
/** Check if a client has strut information.
|
||||
* \param c A client.
|
||||
* \return A boolean value, true if the client has strut information.
|
||||
*/
|
||||
static inline bool
|
||||
client_hasstrut(client_t *c)
|
||||
{
|
||||
return (c->strut.left
|
||||
|| c->strut.right
|
||||
|| c->strut.top
|
||||
|| c->strut.bottom
|
||||
|| c->strut.left_start_y
|
||||
|| c->strut.left_end_y
|
||||
|| c->strut.right_start_y
|
||||
|| c->strut.right_end_y
|
||||
|| c->strut.top_start_x
|
||||
|| c->strut.top_end_x
|
||||
|| c->strut.bottom_start_x
|
||||
|| c->strut.bottom_end_x);
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||
|
|
|
@ -9,6 +9,7 @@ _NET_WORKAREA
|
|||
_NET_SUPPORTING_WM_CHECK
|
||||
_NET_CLOSE_WINDOW
|
||||
_NET_WM_NAME
|
||||
_NET_WM_STRUT_PARTIAL
|
||||
_NET_WM_VISIBLE_NAME
|
||||
_NET_WM_DESKTOP
|
||||
_NET_WM_ICON_NAME
|
||||
|
|
7
event.c
7
event.c
|
@ -217,6 +217,11 @@ event_handle_configurerequest(void *data __attribute__ ((unused)),
|
|||
{
|
||||
client_resize(c, geometry, false);
|
||||
titlebar_draw(c);
|
||||
if(client_hasstrut(c))
|
||||
/* All the statusbars (may) need to be repositioned */
|
||||
for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++)
|
||||
for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next)
|
||||
statusbar_position_update(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -658,6 +663,8 @@ event_handle_propertynotify(void *data __attribute__ ((unused)),
|
|||
client_updatewmhints(c);
|
||||
else if(ev->atom == WM_NAME || ev->atom == _NET_WM_NAME)
|
||||
client_updatetitle(c);
|
||||
else if(ev->atom == _NET_WM_STRUT_PARTIAL)
|
||||
ewmh_client_strut_update(c);
|
||||
else if(ev->atom == _NET_WM_ICON)
|
||||
{
|
||||
xcb_get_property_cookie_t icon_q = ewmh_window_icon_get_unchecked(c->win);
|
||||
|
|
65
ewmh.c
65
ewmh.c
|
@ -32,6 +32,7 @@
|
|||
#include "widget.h"
|
||||
#include "cnode.h"
|
||||
#include "titlebar.h"
|
||||
#include "statusbar.h"
|
||||
#include "common/atoms.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
@ -58,6 +59,7 @@ ewmh_init(int phys_screen)
|
|||
_NET_WORKAREA,
|
||||
_NET_CLOSE_WINDOW,
|
||||
_NET_WM_NAME,
|
||||
_NET_WM_STRUT_PARTIAL,
|
||||
_NET_WM_ICON_NAME,
|
||||
_NET_WM_VISIBLE_ICON_NAME,
|
||||
_NET_WM_DESKTOP,
|
||||
|
@ -213,9 +215,10 @@ ewmh_update_workarea(int phys_screen)
|
|||
{
|
||||
tag_array_t *tags = &globalconf.screens[phys_screen].tags;
|
||||
uint32_t *area = p_alloca(uint32_t, tags->len * 4);
|
||||
area_t geom = screen_area_get(&globalconf.screens[phys_screen].geometry,
|
||||
area_t geom = screen_area_get(phys_screen,
|
||||
globalconf.screens[phys_screen].statusbar,
|
||||
&globalconf.screens[phys_screen].padding);
|
||||
&globalconf.screens[phys_screen].padding,
|
||||
true);
|
||||
|
||||
|
||||
for(int i = 0; i < tags->len; i++)
|
||||
|
@ -435,6 +438,64 @@ ewmh_check_client_hints(client_t *c)
|
|||
p_delete(&reply);
|
||||
}
|
||||
|
||||
/** Update the WM strut of a client.
|
||||
* \param c The client.
|
||||
*/
|
||||
void
|
||||
ewmh_client_strut_update(client_t *c)
|
||||
{
|
||||
void *data;
|
||||
xcb_get_property_cookie_t strut_q;
|
||||
xcb_get_property_reply_t *strut_r;
|
||||
|
||||
strut_q = xcb_get_property_unchecked(globalconf.connection, false, c->win,
|
||||
_NET_WM_STRUT_PARTIAL, CARDINAL, 0, 12);
|
||||
|
||||
strut_r = xcb_get_property_reply(globalconf.connection, strut_q, NULL);
|
||||
|
||||
if(strut_r
|
||||
&& strut_r->value_len
|
||||
&& (data = xcb_get_property_value(strut_r)))
|
||||
{
|
||||
uint32_t *strut = data;
|
||||
|
||||
if(c->strut.left != strut[0]
|
||||
|| c->strut.right != strut[1]
|
||||
|| c->strut.top != strut[2]
|
||||
|| c->strut.bottom != strut[3]
|
||||
|| c->strut.left_start_y != strut[4]
|
||||
|| c->strut.left_end_y != strut[5]
|
||||
|| c->strut.right_start_y != strut[6]
|
||||
|| c->strut.right_end_y != strut[7]
|
||||
|| c->strut.top_start_x != strut[8]
|
||||
|| c->strut.top_end_x != strut[9]
|
||||
|| c->strut.bottom_start_x != strut[10]
|
||||
|| c->strut.bottom_end_x != strut[11])
|
||||
{
|
||||
c->strut.left = strut[0];
|
||||
c->strut.right = strut[1];
|
||||
c->strut.top = strut[2];
|
||||
c->strut.bottom = strut[3];
|
||||
c->strut.left_start_y = strut[4];
|
||||
c->strut.left_end_y = strut[5];
|
||||
c->strut.right_start_y = strut[6];
|
||||
c->strut.right_end_y = strut[7];
|
||||
c->strut.top_start_x = strut[8];
|
||||
c->strut.top_end_x = strut[9];
|
||||
c->strut.bottom_start_x = strut[10];
|
||||
c->strut.bottom_end_x = strut[11];
|
||||
|
||||
client_need_arrange(c);
|
||||
/* All the statusbars (may) need to be repositioned */
|
||||
for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++)
|
||||
for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next)
|
||||
statusbar_position_update(s);
|
||||
}
|
||||
}
|
||||
p_delete(&strut_r);
|
||||
}
|
||||
|
||||
|
||||
/** Send request to get NET_WM_ICON (EWMH)
|
||||
* \param w The window.
|
||||
* \return The cookie associated with the request.
|
||||
|
|
1
ewmh.h
1
ewmh.h
|
@ -44,6 +44,7 @@ int ewmh_process_client_message(xcb_client_message_event_t *);
|
|||
void ewmh_update_net_client_list_stacking(int);
|
||||
void ewmh_check_client_hints(client_t *);
|
||||
void ewmh_update_workarea(int);
|
||||
void ewmh_client_strut_update(client_t *);
|
||||
xcb_get_property_cookie_t ewmh_window_icon_get_unchecked(xcb_window_t);
|
||||
netwm_icon_t *ewmh_window_icon_get_reply(xcb_get_property_cookie_t);
|
||||
|
||||
|
|
|
@ -41,9 +41,10 @@ layout_fair(int screen, const orientation_t orientation)
|
|||
client_t *c;
|
||||
area_t geometry, area;
|
||||
|
||||
area = screen_area_get(&globalconf.screens[screen].geometry,
|
||||
area = screen_area_get(screen,
|
||||
globalconf.screens[screen].statusbar,
|
||||
&globalconf.screens[screen].padding);
|
||||
&globalconf.screens[screen].padding,
|
||||
true);
|
||||
|
||||
for(c = globalconf.clients ; c; c = c->next)
|
||||
if(IS_TILED(c, screen))
|
||||
|
|
|
@ -32,9 +32,10 @@ layout_fibonacci(int screen, int shape)
|
|||
int n = 0, i = 0;
|
||||
client_t *c;
|
||||
area_t geometry, area;
|
||||
geometry = area = screen_area_get(&globalconf.screens[screen].geometry,
|
||||
geometry = area = screen_area_get(screen,
|
||||
globalconf.screens[screen].statusbar,
|
||||
&globalconf.screens[screen].padding);
|
||||
&globalconf.screens[screen].padding,
|
||||
true);
|
||||
|
||||
for(c = globalconf.clients; c; c = c->next)
|
||||
if(IS_TILED(c, screen))
|
||||
|
|
|
@ -34,9 +34,10 @@ layout_magnifier(int screen)
|
|||
int n = 0;
|
||||
client_t *c, *focus;
|
||||
tag_t **curtags = tags_get_current(screen);
|
||||
area_t geometry, area = screen_area_get(&globalconf.screens[screen].geometry,
|
||||
area_t geometry, area = screen_area_get(screen,
|
||||
globalconf.screens[screen].statusbar,
|
||||
&globalconf.screens[screen].padding);
|
||||
&globalconf.screens[screen].padding,
|
||||
true);
|
||||
|
||||
focus = globalconf.screens[screen].client_focus;
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ void
|
|||
layout_max(int screen)
|
||||
{
|
||||
client_t *c;
|
||||
area_t area = screen_area_get(&globalconf.screens[screen].geometry,
|
||||
area_t area = screen_area_get(screen,
|
||||
globalconf.screens[screen].statusbar,
|
||||
&globalconf.screens[screen].padding);
|
||||
&globalconf.screens[screen].padding,
|
||||
true);
|
||||
|
||||
for(c = globalconf.clients; c; c = c->next)
|
||||
if(IS_TILED(c, screen))
|
||||
|
|
|
@ -42,9 +42,10 @@ _tile(int screen, const position_t position)
|
|||
client_t *c;
|
||||
tag_t **curtags = tags_get_current(screen);
|
||||
|
||||
area = screen_area_get(&globalconf.screens[screen].geometry,
|
||||
area = screen_area_get(screen,
|
||||
globalconf.screens[screen].statusbar,
|
||||
&globalconf.screens[screen].padding);
|
||||
&globalconf.screens[screen].padding,
|
||||
true);
|
||||
|
||||
for(n = 0, c = globalconf.clients; c; c = c->next)
|
||||
if(IS_TILED(c, screen))
|
||||
|
|
20
mouse.c
20
mouse.c
|
@ -130,14 +130,16 @@ mouse_snapclient(client_t *c, area_t geometry, int snap)
|
|||
client_t *snapper;
|
||||
area_t snapper_geometry;
|
||||
area_t screen_geometry =
|
||||
screen_area_get(&globalconf.screens[c->screen].geometry,
|
||||
screen_area_get(c->screen,
|
||||
globalconf.screens[c->screen].statusbar,
|
||||
&globalconf.screens[c->screen].padding);
|
||||
&globalconf.screens[c->screen].padding,
|
||||
false);
|
||||
|
||||
area_t screen_geometry_barless =
|
||||
screen_area_get(&globalconf.screens[c->screen].geometry,
|
||||
screen_area_get(c->screen,
|
||||
NULL,
|
||||
&globalconf.screens[c->screen].padding);
|
||||
&globalconf.screens[c->screen].padding,
|
||||
false);
|
||||
|
||||
geometry = titlebar_geometry_add(c->titlebar, c->border, geometry);
|
||||
|
||||
|
@ -745,9 +747,10 @@ mouse_client_resize_tiled(client_t *c)
|
|||
tag = tags_get_current(c->screen)[0];
|
||||
layout = tag->layout;
|
||||
|
||||
area = screen_area_get(&globalconf.screens[tag->screen].geometry,
|
||||
area = screen_area_get(tag->screen,
|
||||
globalconf.screens[tag->screen].statusbar,
|
||||
&globalconf.screens[tag->screen].padding);
|
||||
&globalconf.screens[tag->screen].padding,
|
||||
true);
|
||||
|
||||
mouse_query_pointer(screen->root, &mouse_x, &mouse_y, NULL);
|
||||
|
||||
|
@ -848,9 +851,10 @@ mouse_client_resize_magnified(client_t *c, bool infobox)
|
|||
|
||||
root = xutil_screen_get(globalconf.connection, c->phys_screen)->root;
|
||||
|
||||
area = screen_area_get(&globalconf.screens[tag->screen].geometry,
|
||||
area = screen_area_get(tag->screen,
|
||||
globalconf.screens[tag->screen].statusbar,
|
||||
&globalconf.screens[tag->screen].padding);
|
||||
&globalconf.screens[tag->screen].padding,
|
||||
true);
|
||||
|
||||
center_x = area.x + (round(area.width / 2.));
|
||||
center_y = area.y + (round(area.height / 2.));
|
||||
|
|
70
screen.c
70
screen.c
|
@ -36,13 +36,16 @@ extern awesome_t globalconf;
|
|||
* \param screen Screen number.
|
||||
* \param statusbar Statusbar list to remove.
|
||||
* \param padding Padding.
|
||||
* \param strut Honor windows strut.
|
||||
* \return The screen area.
|
||||
*/
|
||||
area_t
|
||||
screen_area_get(area_t *geometry, statusbar_t *statusbar, padding_t *padding)
|
||||
screen_area_get(int screen, statusbar_t *statusbar,
|
||||
padding_t *padding, bool strut)
|
||||
{
|
||||
area_t area = *geometry;
|
||||
area_t area = globalconf.screens[screen].geometry;
|
||||
statusbar_t *sb;
|
||||
uint16_t top = 0, bottom = 0, left = 0, right = 0;
|
||||
|
||||
/* make padding corrections */
|
||||
if(padding)
|
||||
|
@ -53,23 +56,68 @@ screen_area_get(area_t *geometry, statusbar_t *statusbar, padding_t *padding)
|
|||
area.height -= padding->top + padding->bottom;
|
||||
}
|
||||
|
||||
if(strut)
|
||||
{
|
||||
client_t *c;
|
||||
for(c = globalconf.clients; c; c = c->next)
|
||||
if(client_isvisible(c, screen))
|
||||
{
|
||||
if(c->strut.top_start_x || c->strut.top_end_x)
|
||||
{
|
||||
if(c->strut.top)
|
||||
top = MAX(top, c->strut.top);
|
||||
else
|
||||
top = MAX(top, (c->geometry.y - area.y) + c->geometry.height);
|
||||
}
|
||||
if(c->strut.bottom_start_x || c->strut.bottom_end_x)
|
||||
{
|
||||
if(c->strut.bottom)
|
||||
bottom = MAX(bottom, c->strut.bottom);
|
||||
else
|
||||
bottom = MAX(bottom, (area.y + area.height) - c->geometry.y);
|
||||
}
|
||||
if(c->strut.left_start_y || c->strut.left_end_y)
|
||||
{
|
||||
if(c->strut.left)
|
||||
left = MAX(left, c->strut.left);
|
||||
else
|
||||
left = MAX(left, (c->geometry.x - area.x) + c->geometry.width);
|
||||
}
|
||||
if(c->strut.right_start_y || c->strut.right_end_y)
|
||||
{
|
||||
if(c->strut.right)
|
||||
right = MAX(right, c->strut.right);
|
||||
else
|
||||
right = MAX(right, (area.x + area.width) - c->geometry.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(sb = statusbar; sb; sb = sb->next)
|
||||
switch(sb->position)
|
||||
{
|
||||
case Top:
|
||||
area.y += sb->height;
|
||||
top = MAX(top, (uint16_t) (sb->sw->geometry.y - area.y) + sb->sw->geometry.height);
|
||||
break;
|
||||
case Bottom:
|
||||
area.height -= sb->height;
|
||||
bottom = MAX(bottom, (uint16_t) (area.y + area.height) - sb->sw->geometry.y);
|
||||
break;
|
||||
case Left:
|
||||
area.x += sb->height;
|
||||
left = MAX(left, (uint16_t) (sb->sw->geometry.x - area.x) + sb->sw->geometry.width);
|
||||
break;
|
||||
case Right:
|
||||
area.width -= sb->height;
|
||||
right = MAX(right, (uint16_t) (area.x + area.width) - sb->sw->geometry.x);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
area.x += left;
|
||||
area.y += top;
|
||||
area.width -= left + right;
|
||||
area.height -= top + bottom;
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
@ -151,10 +199,10 @@ screen_client_moveto(client_t *c, int new_screen, bool doresize)
|
|||
area_t new_geometry, new_f_geometry;
|
||||
new_f_geometry = c->f_geometry;
|
||||
|
||||
to = screen_area_get(&globalconf.screens[c->screen].geometry,
|
||||
NULL, NULL);
|
||||
from = screen_area_get(&globalconf.screens[old_screen].geometry,
|
||||
NULL, NULL);
|
||||
to = screen_area_get(c->screen,
|
||||
NULL, NULL, false);
|
||||
from = screen_area_get(old_screen,
|
||||
NULL, NULL, false);
|
||||
|
||||
/* compute new coords in new screen */
|
||||
new_f_geometry.x = (c->f_geometry.x - from.x) + to.x;
|
||||
|
@ -331,7 +379,7 @@ luaA_screen_index(lua_State *L)
|
|||
lua_setfield(L, -2, "height");
|
||||
break;
|
||||
case A_TK_WORKAREA:
|
||||
g = screen_area_get(&s->geometry, s->statusbar, &s->padding);
|
||||
g = screen_area_get(s->index, s->statusbar, &s->padding, true);
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, g.x);
|
||||
lua_setfield(L, -2, "x");
|
||||
|
|
2
screen.h
2
screen.h
|
@ -26,7 +26,7 @@
|
|||
|
||||
#define SCREEN_UNDEF (-1)
|
||||
|
||||
area_t screen_area_get(area_t *, statusbar_t *, padding_t *);
|
||||
area_t screen_area_get(int, statusbar_t *, padding_t *, bool);
|
||||
area_t display_area_get(int, statusbar_t *, padding_t *);
|
||||
int screen_virttophys(int);
|
||||
void screen_client_moveto(client_t *, int, bool);
|
||||
|
|
|
@ -283,9 +283,8 @@ statusbar_position_update(statusbar_t *statusbar)
|
|||
if(statusbar->position == Off)
|
||||
return;
|
||||
|
||||
area = screen_area_get(&globalconf.screens[statusbar->screen].geometry,
|
||||
NULL,
|
||||
&globalconf.screens[statusbar->screen].padding);
|
||||
area = screen_area_get(statusbar->screen, NULL,
|
||||
&globalconf.screens[statusbar->screen].padding, true);
|
||||
|
||||
/* Top and Bottom statusbar_t have prio */
|
||||
for(sb = globalconf.screens[statusbar->screen].statusbar; sb; sb = sb->next)
|
||||
|
|
12
structs.h
12
structs.h
|
@ -261,6 +261,16 @@ typedef struct
|
|||
unsigned char *image;
|
||||
} netwm_icon_t;
|
||||
|
||||
/* Strut */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t left, right, top, bottom;
|
||||
uint16_t left_start_y, left_end_y;
|
||||
uint16_t right_start_y, right_end_y;
|
||||
uint16_t top_start_x, top_end_x;
|
||||
uint16_t bottom_start_x, bottom_end_x;
|
||||
} strut_t;
|
||||
|
||||
/** client_t type */
|
||||
struct client_t
|
||||
{
|
||||
|
@ -280,6 +290,8 @@ struct client_t
|
|||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
||||
int minax, maxax, minay, maxay;
|
||||
bool hassizehints;
|
||||
/** Strut */
|
||||
strut_t strut;
|
||||
/** Respect resize hints */
|
||||
bool honorsizehints;
|
||||
int border, oldborder;
|
||||
|
|
Loading…
Reference in New Issue