Add a lua api for setting a wibox' shape
When the SHAPE extension is not available, this code prints a harmless warn() on stderr. Signed-off-by: Uli Schlachter <psychon@znc.in> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
154d3a0d4a
commit
a77a1b7b64
|
@ -139,6 +139,7 @@ pkg_check_modules(AWESOME_REQUIRED REQUIRED
|
|||
xcb-randr
|
||||
xcb-xtest
|
||||
xcb-xinerama
|
||||
xcb-shape
|
||||
xcb-event>=0.3.4
|
||||
xcb-aux>=0.3.0
|
||||
xcb-atom>=0.3.0
|
||||
|
|
|
@ -89,6 +89,8 @@ role
|
|||
screen
|
||||
selected
|
||||
session
|
||||
shape_bounding
|
||||
shape_clip
|
||||
Shift
|
||||
size_hints
|
||||
size_hints_honor
|
||||
|
|
57
swindow.c
57
swindow.c
|
@ -22,12 +22,67 @@
|
|||
#include <math.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/shape.h>
|
||||
|
||||
#include "structs.h"
|
||||
#include "swindow.h"
|
||||
#include "draw.h"
|
||||
#include "common/xutil.h"
|
||||
|
||||
static int
|
||||
have_shape(void)
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply;
|
||||
|
||||
reply = xcb_get_extension_data(globalconf.connection, &xcb_shape_id);
|
||||
if (!reply || !reply->present)
|
||||
return 0;
|
||||
|
||||
/* We don't need a specific version of SHAPE, no version check required */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
do_update_shape(xcb_window_t win, xcb_shape_kind_t kind, image_t *image, int offset)
|
||||
{
|
||||
xcb_pixmap_t shape;
|
||||
|
||||
if(image)
|
||||
shape = image_to_1bit_pixmap(image, win);
|
||||
else
|
||||
/* Reset the shape */
|
||||
shape = XCB_NONE;
|
||||
|
||||
xcb_shape_mask(globalconf.connection, XCB_SHAPE_SO_SET, kind,
|
||||
win, offset, offset, shape);
|
||||
|
||||
if (shape != XCB_NONE)
|
||||
xcb_free_pixmap(globalconf.connection, shape);
|
||||
}
|
||||
|
||||
/** Update the window's shape.
|
||||
* \param sw The simplw window whose shape should be updated.
|
||||
*/
|
||||
void
|
||||
simplewindow_update_shape(simple_window_t *sw)
|
||||
{
|
||||
if(sw->window == XCB_NONE)
|
||||
return;
|
||||
|
||||
if(!have_shape())
|
||||
{
|
||||
static bool warned = false;
|
||||
if (!warned)
|
||||
warn("The X server doesn't have the SHAPE extension; "
|
||||
"can't change window's shape");
|
||||
warned = true;
|
||||
return;
|
||||
}
|
||||
|
||||
do_update_shape(sw->window, XCB_SHAPE_SK_CLIP, sw->shape.clip, 0);
|
||||
do_update_shape(sw->window, XCB_SHAPE_SK_BOUNDING, sw->shape.bounding, -sw->border.width);
|
||||
}
|
||||
|
||||
static void
|
||||
simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s)
|
||||
{
|
||||
|
@ -127,6 +182,8 @@ simplewindow_init(simple_window_t *sw,
|
|||
/* The default GC is just a newly created associated to the root window */
|
||||
sw->gc = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values);
|
||||
|
||||
simplewindow_update_shape(sw);
|
||||
}
|
||||
|
||||
/** Destroy all resources of a simple window.
|
||||
|
|
|
@ -55,6 +55,14 @@ typedef struct simple_window_t
|
|||
orientation_t orientation;
|
||||
/** Opacity */
|
||||
double opacity;
|
||||
/** The window's shape */
|
||||
struct
|
||||
{
|
||||
/** The window's content */
|
||||
image_t *clip;
|
||||
/** The window's content and border */
|
||||
image_t *bounding;
|
||||
} shape;
|
||||
} simple_window_t;
|
||||
|
||||
void simplewindow_init(simple_window_t *s,
|
||||
|
@ -71,6 +79,7 @@ void simplewindow_border_width_set(simple_window_t *, uint32_t);
|
|||
void simplewindow_border_color_set(simple_window_t *, const xcolor_t *);
|
||||
void simplewindow_orientation_set(simple_window_t *, orientation_t);
|
||||
void simplewindow_cursor_set(simple_window_t *, xcb_cursor_t);
|
||||
void simplewindow_update_shape(simple_window_t *);
|
||||
|
||||
/** Refresh the window content by copying its pixmap data to its window.
|
||||
* \param sw The simple window to refresh.
|
||||
|
|
25
wibox.c
25
wibox.c
|
@ -326,8 +326,15 @@ void
|
|||
wibox_refresh(void)
|
||||
{
|
||||
foreach(w, globalconf.wiboxes)
|
||||
{
|
||||
if((*w)->need_shape_update)
|
||||
{
|
||||
simplewindow_update_shape(&(*w)->sw);
|
||||
(*w)->need_shape_update = false;
|
||||
}
|
||||
if((*w)->need_update)
|
||||
wibox_draw(*w);
|
||||
}
|
||||
|
||||
foreach(_c, globalconf.clients)
|
||||
{
|
||||
|
@ -568,6 +575,8 @@ luaA_wibox_invalidate_byitem(lua_State *L, const void *item)
|
|||
* \lfield opacity The opacity of the wibox, between 0 and 1.
|
||||
* \lfield mouse_enter A function to execute when the mouse enter the widget.
|
||||
* \lfield mouse_leave A function to execute when the mouse leave the widget.
|
||||
* \lfield shape_clip Image describing the window's content shape.
|
||||
* \lfield shape_bounding Image describing the window's border shape.
|
||||
*/
|
||||
static int
|
||||
luaA_wibox_index(lua_State *L)
|
||||
|
@ -652,6 +661,12 @@ luaA_wibox_index(lua_State *L)
|
|||
else
|
||||
return 0;
|
||||
return 1;
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
image_push(L, wibox->sw.shape.bounding);
|
||||
break;
|
||||
case A_TK_SHAPE_CLIP:
|
||||
image_push(L, wibox->sw.shape.clip);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -855,6 +870,16 @@ luaA_wibox_newindex(lua_State *L)
|
|||
case A_TK_MOUSE_LEAVE:
|
||||
luaA_registerfct(L, 3, &wibox->mouse_leave);
|
||||
return 0;
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
image_unref(L, wibox->sw.shape.bounding);
|
||||
wibox->sw.shape.bounding = image_ref(L, 3);
|
||||
wibox->need_shape_update = true;
|
||||
break;
|
||||
case A_TK_SHAPE_CLIP:
|
||||
image_unref(L, wibox->sw.shape.clip);
|
||||
wibox->sw.shape.clip = image_ref(L, 3);
|
||||
wibox->need_shape_update = true;
|
||||
break;
|
||||
default:
|
||||
switch(wibox->type)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue