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-randr
|
||||||
xcb-xtest
|
xcb-xtest
|
||||||
xcb-xinerama
|
xcb-xinerama
|
||||||
|
xcb-shape
|
||||||
xcb-event>=0.3.4
|
xcb-event>=0.3.4
|
||||||
xcb-aux>=0.3.0
|
xcb-aux>=0.3.0
|
||||||
xcb-atom>=0.3.0
|
xcb-atom>=0.3.0
|
||||||
|
|
|
@ -89,6 +89,8 @@ role
|
||||||
screen
|
screen
|
||||||
selected
|
selected
|
||||||
session
|
session
|
||||||
|
shape_bounding
|
||||||
|
shape_clip
|
||||||
Shift
|
Shift
|
||||||
size_hints
|
size_hints
|
||||||
size_hints_honor
|
size_hints_honor
|
||||||
|
|
57
swindow.c
57
swindow.c
|
@ -22,12 +22,67 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/shape.h>
|
||||||
|
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "swindow.h"
|
#include "swindow.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "common/xutil.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
|
static void
|
||||||
simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s)
|
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 */
|
/* The default GC is just a newly created associated to the root window */
|
||||||
sw->gc = xcb_generate_id(globalconf.connection);
|
sw->gc = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values);
|
xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values);
|
||||||
|
|
||||||
|
simplewindow_update_shape(sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroy all resources of a simple window.
|
/** Destroy all resources of a simple window.
|
||||||
|
|
|
@ -55,6 +55,14 @@ typedef struct simple_window_t
|
||||||
orientation_t orientation;
|
orientation_t orientation;
|
||||||
/** Opacity */
|
/** Opacity */
|
||||||
double 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;
|
} simple_window_t;
|
||||||
|
|
||||||
void simplewindow_init(simple_window_t *s,
|
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_border_color_set(simple_window_t *, const xcolor_t *);
|
||||||
void simplewindow_orientation_set(simple_window_t *, orientation_t);
|
void simplewindow_orientation_set(simple_window_t *, orientation_t);
|
||||||
void simplewindow_cursor_set(simple_window_t *, xcb_cursor_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.
|
/** Refresh the window content by copying its pixmap data to its window.
|
||||||
* \param sw The simple window to refresh.
|
* \param sw The simple window to refresh.
|
||||||
|
|
25
wibox.c
25
wibox.c
|
@ -326,8 +326,15 @@ void
|
||||||
wibox_refresh(void)
|
wibox_refresh(void)
|
||||||
{
|
{
|
||||||
foreach(w, globalconf.wiboxes)
|
foreach(w, globalconf.wiboxes)
|
||||||
|
{
|
||||||
|
if((*w)->need_shape_update)
|
||||||
|
{
|
||||||
|
simplewindow_update_shape(&(*w)->sw);
|
||||||
|
(*w)->need_shape_update = false;
|
||||||
|
}
|
||||||
if((*w)->need_update)
|
if((*w)->need_update)
|
||||||
wibox_draw(*w);
|
wibox_draw(*w);
|
||||||
|
}
|
||||||
|
|
||||||
foreach(_c, globalconf.clients)
|
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 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_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 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
|
static int
|
||||||
luaA_wibox_index(lua_State *L)
|
luaA_wibox_index(lua_State *L)
|
||||||
|
@ -652,6 +661,12 @@ luaA_wibox_index(lua_State *L)
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
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:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -855,6 +870,16 @@ luaA_wibox_newindex(lua_State *L)
|
||||||
case A_TK_MOUSE_LEAVE:
|
case A_TK_MOUSE_LEAVE:
|
||||||
luaA_registerfct(L, 3, &wibox->mouse_leave);
|
luaA_registerfct(L, 3, &wibox->mouse_leave);
|
||||||
return 0;
|
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:
|
default:
|
||||||
switch(wibox->type)
|
switch(wibox->type)
|
||||||
{
|
{
|
||||||
|
|
2
wibox.h
2
wibox.h
|
@ -59,6 +59,8 @@ struct wibox_t
|
||||||
luaA_ref mouse_enter, mouse_leave;
|
luaA_ref mouse_enter, mouse_leave;
|
||||||
/** Need update */
|
/** Need update */
|
||||||
bool need_update;
|
bool need_update;
|
||||||
|
/** Need shape update */
|
||||||
|
bool need_shape_update;
|
||||||
/** Cursor */
|
/** Cursor */
|
||||||
char *cursor;
|
char *cursor;
|
||||||
/** Background image */
|
/** Background image */
|
||||||
|
|
Loading…
Reference in New Issue