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:
Uli Schlachter 2009-06-23 12:55:50 +02:00 committed by Julien Danjou
parent 154d3a0d4a
commit a77a1b7b64
6 changed files with 96 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

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

View File

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