wibox: get rid of simple window
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
367b3e03d5
commit
13efd8a199
|
@ -65,7 +65,6 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/image.c
|
||||
${SOURCE_DIR}/draw.c
|
||||
${SOURCE_DIR}/color.c
|
||||
${SOURCE_DIR}/swindow.c
|
||||
${SOURCE_DIR}/common/buffer.c
|
||||
${SOURCE_DIR}/common/atoms.c
|
||||
${SOURCE_DIR}/common/util.c
|
||||
|
|
12
client.c
12
client.c
|
@ -338,10 +338,10 @@ client_stack_above(client_t *c, xcb_window_t previous)
|
|||
if(c->titlebar)
|
||||
{
|
||||
xcb_configure_window(globalconf.connection,
|
||||
c->titlebar->sw.window,
|
||||
c->titlebar->window,
|
||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||
config_win_vals);
|
||||
previous = c->titlebar->sw.window;
|
||||
previous = c->titlebar->window;
|
||||
}
|
||||
else
|
||||
previous = c->win;
|
||||
|
@ -433,10 +433,10 @@ client_stack_refresh()
|
|||
if(!sb->ontop)
|
||||
{
|
||||
xcb_configure_window(globalconf.connection,
|
||||
sb->sw.window,
|
||||
sb->window,
|
||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||
config_win_vals);
|
||||
config_win_vals[0] = sb->sw.window;
|
||||
config_win_vals[0] = sb->window;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,10 +454,10 @@ client_stack_refresh()
|
|||
if(sb->ontop)
|
||||
{
|
||||
xcb_configure_window(globalconf.connection,
|
||||
sb->sw.window,
|
||||
sb->window,
|
||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||
config_win_vals);
|
||||
config_win_vals[0] = sb->sw.window;
|
||||
config_win_vals[0] = sb->window;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
event.c
30
event.c
|
@ -173,19 +173,19 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
|||
{
|
||||
/* If the wibox is child, then x,y are
|
||||
* relative to root window */
|
||||
if(wibox->sw.window == ev->child)
|
||||
if(wibox->window == ev->child)
|
||||
{
|
||||
ev->event_x -= wibox->sw.geometry.x;
|
||||
ev->event_y -= wibox->sw.geometry.y;
|
||||
ev->event_x -= wibox->geometry.x;
|
||||
ev->event_y -= wibox->geometry.y;
|
||||
}
|
||||
|
||||
wibox_push(globalconf.L, wibox);
|
||||
event_button_callback(ev, wibox->buttons, -1, 1, NULL);
|
||||
|
||||
/* then try to match a widget binding */
|
||||
widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
|
||||
wibox->sw.geometry.width,
|
||||
wibox->sw.geometry.height,
|
||||
widget_t *w = widget_getbycoords(wibox->orientation, &wibox->widgets,
|
||||
wibox->geometry.width,
|
||||
wibox->geometry.height,
|
||||
&ev->event_x, &ev->event_y);
|
||||
if(w)
|
||||
{
|
||||
|
@ -409,9 +409,9 @@ event_handle_motionnotify(void *data __attribute__ ((unused)),
|
|||
|
||||
if((wibox = wibox_getbywin(ev->event)))
|
||||
{
|
||||
widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
|
||||
wibox->sw.geometry.width,
|
||||
wibox->sw.geometry.height,
|
||||
widget_t *w = widget_getbycoords(wibox->orientation, &wibox->widgets,
|
||||
wibox->geometry.width,
|
||||
wibox->geometry.height,
|
||||
&ev->event_x, &ev->event_y);
|
||||
if(w)
|
||||
event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w);
|
||||
|
@ -485,9 +485,9 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
|
|||
|
||||
if((wibox = wibox_getbywin(ev->event)))
|
||||
{
|
||||
widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
|
||||
wibox->sw.geometry.width,
|
||||
wibox->sw.geometry.height,
|
||||
widget_t *w = widget_getbycoords(wibox->orientation, &wibox->widgets,
|
||||
wibox->geometry.width,
|
||||
wibox->geometry.height,
|
||||
&ev->event_x, &ev->event_y);
|
||||
if(w)
|
||||
event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w);
|
||||
|
@ -558,9 +558,9 @@ event_handle_expose(void *data __attribute__ ((unused)),
|
|||
wibox_t *wibox;
|
||||
|
||||
if((wibox = wibox_getbywin(ev->window)))
|
||||
simplewindow_refresh_pixmap_partial(&wibox->sw,
|
||||
ev->x, ev->y,
|
||||
ev->width, ev->height);
|
||||
wibox_refresh_pixmap_partial(wibox,
|
||||
ev->x, ev->y,
|
||||
ev->width, ev->height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
10
mouse.c
10
mouse.c
|
@ -256,12 +256,12 @@ luaA_mouse_object_under_pointer(lua_State *L)
|
|||
{
|
||||
wibox_push(L, wibox);
|
||||
|
||||
int16_t x = mouse_x - wibox->sw.geometry.x;
|
||||
int16_t y = mouse_y - wibox->sw.geometry.y;
|
||||
int16_t x = mouse_x - wibox->geometry.x;
|
||||
int16_t y = mouse_y - wibox->geometry.y;
|
||||
|
||||
widget_t *widget = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
|
||||
wibox->sw.geometry.width,
|
||||
wibox->sw.geometry.height,
|
||||
widget_t *widget = widget_getbycoords(wibox->orientation, &wibox->widgets,
|
||||
wibox->geometry.width,
|
||||
wibox->geometry.height,
|
||||
&x, &y);
|
||||
|
||||
if(widget)
|
||||
|
|
|
@ -468,7 +468,7 @@ property_handle_opacity(void *data __attribute__ ((unused)),
|
|||
wibox_t *wibox = wibox_getbywin(window);
|
||||
|
||||
if (wibox)
|
||||
wibox->sw.opacity = window_opacity_get_from_reply(reply);
|
||||
wibox->opacity = window_opacity_get_from_reply(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
389
swindow.c
389
swindow.c
|
@ -1,389 +0,0 @@
|
|||
/*
|
||||
* swindow.c - simple window handling functions
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
xcolor_t fg = sw->ctx.fg, bg = sw->ctx.bg;
|
||||
int phys_screen = sw->ctx.phys_screen;
|
||||
|
||||
draw_context_wipe(&sw->ctx);
|
||||
|
||||
/* update draw context */
|
||||
switch(sw->orientation)
|
||||
{
|
||||
case South:
|
||||
case North:
|
||||
/* we need a new pixmap this way [ ] to render */
|
||||
sw->ctx.pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection,
|
||||
s->root_depth,
|
||||
sw->ctx.pixmap, s->root,
|
||||
sw->geometries.internal.height, sw->geometries.internal.width);
|
||||
draw_context_init(&sw->ctx, phys_screen,
|
||||
sw->geometries.internal.height, sw->geometries.internal.width,
|
||||
sw->ctx.pixmap, &fg, &bg);
|
||||
break;
|
||||
case East:
|
||||
draw_context_init(&sw->ctx, phys_screen,
|
||||
sw->geometries.internal.width, sw->geometries.internal.height,
|
||||
sw->pixmap, &fg, &bg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize a simple window.
|
||||
* \param sw The simple window to initialize.
|
||||
* \param phys_screen Physical screen number.
|
||||
* \param geometry Window geometry.
|
||||
* \param border_width Window border width.
|
||||
* \param border_color Window border color.
|
||||
* \param orientation The rendering orientation.
|
||||
* \param fg Default foreground color.
|
||||
* \param bg Default background color.
|
||||
*/
|
||||
void
|
||||
simplewindow_init(simple_window_t *sw,
|
||||
int phys_screen,
|
||||
area_t geometry,
|
||||
uint16_t border_width,
|
||||
const xcolor_t *border_color,
|
||||
orientation_t orientation,
|
||||
const xcolor_t *fg, const xcolor_t *bg)
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
|
||||
uint32_t create_win_val[4];
|
||||
const uint32_t gc_mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
|
||||
const uint32_t gc_values[2] = { s->black_pixel, s->white_pixel };
|
||||
|
||||
sw->geometry.x = geometry.x;
|
||||
sw->geometry.y = geometry.y;
|
||||
sw->geometry.width = geometry.width;
|
||||
sw->geometry.height = geometry.height;
|
||||
sw->border.width = border_width;
|
||||
|
||||
/* The real protocol window. */
|
||||
sw->geometries.internal.x = geometry.x;
|
||||
sw->geometries.internal.y = geometry.y;
|
||||
sw->geometries.internal.width = geometry.width;
|
||||
sw->geometries.internal.height = geometry.height;
|
||||
|
||||
sw->orientation = orientation;
|
||||
sw->ctx.fg = *fg;
|
||||
sw->ctx.bg = *bg;
|
||||
sw->border.color = *border_color;
|
||||
|
||||
create_win_val[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE;
|
||||
create_win_val[1] = border_color->pixel;
|
||||
create_win_val[2] = 1;
|
||||
create_win_val[3] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW
|
||||
| XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||
| XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
|
||||
| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE
|
||||
| XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||
|
||||
sw->window = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root,
|
||||
sw->geometries.internal.x, sw->geometries.internal.y, sw->geometries.internal.width, sw->geometries.internal.height,
|
||||
border_width, XCB_COPY_FROM_PARENT, s->root_visual,
|
||||
XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
|
||||
create_win_val);
|
||||
|
||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root,
|
||||
sw->geometries.internal.width, sw->geometries.internal.height);
|
||||
|
||||
sw->ctx.phys_screen = phys_screen;
|
||||
simplewindow_draw_context_update(sw, s);
|
||||
|
||||
/* 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.
|
||||
* \param sw The simple_window_t to wipe.
|
||||
*/
|
||||
void
|
||||
simplewindow_wipe(simple_window_t *sw)
|
||||
{
|
||||
if(sw->window)
|
||||
{
|
||||
xcb_destroy_window(globalconf.connection, sw->window);
|
||||
sw->window = XCB_NONE;
|
||||
}
|
||||
if(sw->pixmap)
|
||||
{
|
||||
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
||||
sw->pixmap = XCB_NONE;
|
||||
}
|
||||
if(sw->gc)
|
||||
{
|
||||
xcb_free_gc(globalconf.connection, sw->gc);
|
||||
sw->gc = XCB_NONE;
|
||||
}
|
||||
draw_context_wipe(&sw->ctx);
|
||||
}
|
||||
|
||||
/** Move a simple window.
|
||||
* \param sw The simple window to move.
|
||||
* \param x New x coordinate.
|
||||
* \param y New y coordinate.
|
||||
*/
|
||||
void
|
||||
simplewindow_move(simple_window_t *sw, int x, int y)
|
||||
{
|
||||
const uint32_t move_win_vals[] = { x, y };
|
||||
|
||||
if(x != sw->geometries.internal.x || y != sw->geometries.internal.y)
|
||||
{
|
||||
sw->geometry.x = sw->geometries.internal.x = x;
|
||||
sw->geometry.y = sw->geometries.internal.y = y;
|
||||
xcb_configure_window(globalconf.connection, sw->window,
|
||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
||||
move_win_vals);
|
||||
}
|
||||
}
|
||||
|
||||
/** Resize a simple window.
|
||||
* \param sw The simple_window_t to resize.
|
||||
* \param w New width.
|
||||
* \param h New height.
|
||||
*/
|
||||
void
|
||||
simplewindow_resize(simple_window_t *sw, int w, int h)
|
||||
{
|
||||
int iw = w - 2 * sw->border.width;
|
||||
int ih = h - 2 * sw->border.width;
|
||||
|
||||
if(iw > 0 && ih > 0 &&
|
||||
(sw->geometries.internal.width != iw || sw->geometries.internal.height != ih))
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
||||
uint32_t resize_win_vals[2];
|
||||
|
||||
sw->geometries.internal.width = resize_win_vals[0] = iw;
|
||||
sw->geometries.internal.height = resize_win_vals[1] = ih;
|
||||
sw->geometry.width = w;
|
||||
sw->geometry.height = h;
|
||||
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
||||
/* orientation != East */
|
||||
if(sw->pixmap != sw->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, iw, ih);
|
||||
xcb_configure_window(globalconf.connection, sw->window,
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
resize_win_vals);
|
||||
simplewindow_draw_context_update(sw, s);
|
||||
}
|
||||
}
|
||||
|
||||
/** Move and resize a window in one call.
|
||||
* \param sw The simple window to move and resize.
|
||||
* \param geom The new geometry.
|
||||
*/
|
||||
void
|
||||
simplewindow_moveresize(simple_window_t *sw, area_t geom)
|
||||
{
|
||||
uint32_t moveresize_win_vals[4], mask_vals = 0;
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
||||
|
||||
area_t geom_internal = geom;
|
||||
geom_internal.width -= 2 * sw->border.width;
|
||||
geom_internal.height -= 2* sw->border.width;
|
||||
|
||||
if(sw->geometries.internal.x != geom_internal.x || sw->geometries.internal.y != geom_internal.y)
|
||||
{
|
||||
sw->geometries.internal.x = moveresize_win_vals[0] = geom_internal.x;
|
||||
sw->geometries.internal.y = moveresize_win_vals[1] = geom_internal.y;
|
||||
mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
}
|
||||
|
||||
if(sw->geometry.width != geom.width || sw->geometry.height != geom.height)
|
||||
{
|
||||
if(mask_vals)
|
||||
{
|
||||
sw->geometries.internal.width = moveresize_win_vals[2] = geom_internal.width;
|
||||
sw->geometries.internal.height = moveresize_win_vals[3] = geom_internal.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
sw->geometries.internal.width = moveresize_win_vals[0] = geom_internal.width;
|
||||
sw->geometries.internal.height = moveresize_win_vals[1] = geom_internal.height;
|
||||
}
|
||||
mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
||||
/* orientation != East */
|
||||
if(sw->pixmap != sw->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, geom_internal.width, geom_internal.height);
|
||||
simplewindow_draw_context_update(sw, s);
|
||||
}
|
||||
|
||||
/* Also save geometry including border. */
|
||||
sw->geometry = geom;
|
||||
|
||||
xcb_configure_window(globalconf.connection, sw->window, mask_vals, moveresize_win_vals);
|
||||
}
|
||||
|
||||
/** Refresh the window content by copying its pixmap data to its window.
|
||||
* \param sw The simple window to refresh.
|
||||
* \param x The copy starting point x component.
|
||||
* \param y The copy starting point y component.
|
||||
* \param w The copy width from the x component.
|
||||
* \param h The copy height from the y component.
|
||||
*/
|
||||
void
|
||||
simplewindow_refresh_pixmap_partial(simple_window_t *sw,
|
||||
int16_t x, int16_t y,
|
||||
uint16_t w, uint16_t h)
|
||||
{
|
||||
xcb_copy_area(globalconf.connection, sw->pixmap,
|
||||
sw->window, sw->gc, x, y, x, y,
|
||||
w, h);
|
||||
}
|
||||
|
||||
/** Set a simple window border width.
|
||||
* \param sw The simple window to change border width.
|
||||
* \param border_width The border width in pixel.
|
||||
*/
|
||||
void
|
||||
simplewindow_border_width_set(simple_window_t *sw, uint32_t border_width)
|
||||
{
|
||||
xcb_configure_window(globalconf.connection, sw->window, XCB_CONFIG_WINDOW_BORDER_WIDTH,
|
||||
&border_width);
|
||||
sw->border.width = border_width;
|
||||
}
|
||||
|
||||
/** Set a simple window border color.
|
||||
* \param sw The simple window to change border width.
|
||||
* \param color The border color.
|
||||
*/
|
||||
void
|
||||
simplewindow_border_color_set(simple_window_t *sw, const xcolor_t *color)
|
||||
{
|
||||
xcb_change_window_attributes(globalconf.connection, sw->window,
|
||||
XCB_CW_BORDER_PIXEL, &color->pixel);
|
||||
sw->border.color = *color;
|
||||
}
|
||||
|
||||
/** Set simple window orientation.
|
||||
* \param sw The simple window.
|
||||
* \param o The new orientation
|
||||
*/
|
||||
void
|
||||
simplewindow_orientation_set(simple_window_t *sw, orientation_t o)
|
||||
{
|
||||
if(o != sw->orientation)
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
||||
sw->orientation = o;
|
||||
/* orientation != East */
|
||||
if(sw->pixmap != sw->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
||||
simplewindow_draw_context_update(sw, s);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set simple window cursor.
|
||||
* \param sw The simple window.
|
||||
* \param c The cursor.
|
||||
*/
|
||||
void
|
||||
simplewindow_cursor_set(simple_window_t *sw, xcb_cursor_t c)
|
||||
{
|
||||
if(sw->window)
|
||||
{
|
||||
const uint32_t change_win_vals[] = { c };
|
||||
xcb_change_window_attributes(globalconf.connection, sw->window, XCB_CW_CURSOR, change_win_vals);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
115
swindow.h
115
swindow.h
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* swindow.h - simple window handling functions header
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_SWINDOW_H
|
||||
#define AWESOME_SWINDOW_H
|
||||
|
||||
#include "draw.h"
|
||||
#include "window.h"
|
||||
|
||||
/** A simple window. */
|
||||
typedef struct simple_window_t
|
||||
{
|
||||
/** The window object. */
|
||||
xcb_window_t window;
|
||||
/** The pixmap copied to the window object. */
|
||||
xcb_pixmap_t pixmap;
|
||||
/** The graphic context. */
|
||||
xcb_gcontext_t gc;
|
||||
/** The window geometry. */
|
||||
area_t geometry;
|
||||
struct
|
||||
{
|
||||
/** Internal geometry (matching X11 protocol) */
|
||||
area_t internal;
|
||||
} geometries;
|
||||
/** The window border */
|
||||
struct
|
||||
{
|
||||
/** The window border width */
|
||||
uint16_t width;
|
||||
/** The window border color */
|
||||
xcolor_t color;
|
||||
} border;
|
||||
/** Draw context */
|
||||
draw_context_t ctx;
|
||||
/** Orientation */
|
||||
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,
|
||||
int, area_t, uint16_t, const xcolor_t *,
|
||||
orientation_t, const xcolor_t *, const xcolor_t *);
|
||||
|
||||
void simplewindow_wipe(simple_window_t *);
|
||||
|
||||
void simplewindow_move(simple_window_t *, int, int);
|
||||
void simplewindow_resize(simple_window_t *, int, int);
|
||||
void simplewindow_moveresize(simple_window_t *, area_t);
|
||||
void simplewindow_refresh_pixmap_partial(simple_window_t *, int16_t, int16_t, uint16_t, uint16_t);
|
||||
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.
|
||||
*/
|
||||
static inline void
|
||||
simplewindow_refresh_pixmap(simple_window_t *sw)
|
||||
{
|
||||
simplewindow_refresh_pixmap_partial(sw, 0, 0, sw->geometry.width, sw->geometry.height);
|
||||
}
|
||||
|
||||
/** Set a simplewindow's opacity.
|
||||
* \param sw The window the adjust the opacity of.
|
||||
* \param opacity A value between 0 and 1 which describes the opacity.
|
||||
*/
|
||||
static inline void
|
||||
simplewindow_opacity_set(simple_window_t *sw, double opacity)
|
||||
{
|
||||
sw->opacity = opacity;
|
||||
if(sw->window != XCB_NONE)
|
||||
window_opacity_set(sw->window, opacity);
|
||||
}
|
||||
|
||||
/** Get a simplewindow's opacity.
|
||||
* \return The opacity as a value between 0 and 1, or -1 if unset.
|
||||
*/
|
||||
static inline double
|
||||
simplewindow_opacity_get(simple_window_t *sw)
|
||||
{
|
||||
return sw->opacity;
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
73
titlebar.c
73
titlebar.c
|
@ -49,7 +49,7 @@ client_t *
|
|||
client_getbytitlebarwin(xcb_window_t win)
|
||||
{
|
||||
foreach(c, globalconf.clients)
|
||||
if((*c)->titlebar && (*c)->titlebar->sw.window == win)
|
||||
if((*c)->titlebar && (*c)->titlebar->window == win)
|
||||
return *c;
|
||||
|
||||
return NULL;
|
||||
|
@ -65,10 +65,9 @@ titlebar_ban(wibox_t *titlebar)
|
|||
if(titlebar && !titlebar->isbanned)
|
||||
{
|
||||
client_t *c;
|
||||
simple_window_t *sw = &titlebar->sw;
|
||||
|
||||
if(sw->window)
|
||||
xcb_unmap_window(globalconf.connection, sw->window);
|
||||
if(titlebar->window)
|
||||
xcb_unmap_window(globalconf.connection, titlebar->window);
|
||||
|
||||
/* Remove titlebar geometry from client. */
|
||||
if((c = client_getbytitlebar(titlebar)))
|
||||
|
@ -90,10 +89,9 @@ titlebar_unban(wibox_t *titlebar)
|
|||
if(titlebar && titlebar->isbanned)
|
||||
{
|
||||
client_t *c;
|
||||
simple_window_t *sw = &titlebar->sw;
|
||||
|
||||
if(sw->window)
|
||||
xcb_map_window(globalconf.connection, sw->window);
|
||||
if(titlebar->window)
|
||||
xcb_map_window(globalconf.connection, titlebar->window);
|
||||
|
||||
titlebar->isbanned = false;
|
||||
|
||||
|
@ -131,9 +129,9 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
|||
break;
|
||||
}
|
||||
res->x = geometry.x + x_offset;
|
||||
res->y = geometry.y - c->titlebar->sw.geometry.height;
|
||||
res->y = geometry.y - c->titlebar->geometry.height;
|
||||
res->width = width;
|
||||
res->height = c->titlebar->sw.geometry.height;
|
||||
res->height = c->titlebar->geometry.height;
|
||||
break;
|
||||
case Bottom:
|
||||
width = MAX(1, geometry.width);
|
||||
|
@ -151,7 +149,7 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
|||
res->x = geometry.x + x_offset;
|
||||
res->y = geometry.y + geometry.height;
|
||||
res->width = width;
|
||||
res->height = c->titlebar->sw.geometry.height;
|
||||
res->height = c->titlebar->geometry.height;
|
||||
break;
|
||||
case Left:
|
||||
height = MAX(1, geometry.height);
|
||||
|
@ -166,9 +164,9 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
|||
y_offset = (geometry.height - height) / 2;
|
||||
break;
|
||||
}
|
||||
res->x = geometry.x - c->titlebar->sw.geometry.width;
|
||||
res->x = geometry.x - c->titlebar->geometry.width;
|
||||
res->y = geometry.y + y_offset;
|
||||
res->width = c->titlebar->sw.geometry.width;
|
||||
res->width = c->titlebar->geometry.width;
|
||||
res->height = height;
|
||||
break;
|
||||
case Right:
|
||||
|
@ -186,7 +184,7 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
|||
}
|
||||
res->x = geometry.x + geometry.width;
|
||||
res->y = geometry.y + y_offset;
|
||||
res->width = c->titlebar->sw.geometry.width;
|
||||
res->width = c->titlebar->geometry.width;
|
||||
res->height = height;
|
||||
break;
|
||||
}
|
||||
|
@ -203,7 +201,7 @@ titlebar_client_detach(client_t *c)
|
|||
{
|
||||
/* Update client geometry to exclude the titlebar. */
|
||||
c->geometry = titlebar_geometry_remove(c->titlebar, 0, c->geometry);
|
||||
simplewindow_wipe(&c->titlebar->sw);
|
||||
wibox_wipe(c->titlebar);
|
||||
c->titlebar->type = WIBOX_TYPE_NORMAL;
|
||||
c->titlebar->screen = NULL;
|
||||
|
||||
|
@ -242,13 +240,13 @@ titlebar_client_attach(client_t *c)
|
|||
{
|
||||
case Top:
|
||||
case Bottom:
|
||||
if(!t->sw.geometry.height)
|
||||
t->sw.geometry.height = 1.5 * globalconf.font->height;
|
||||
if(!t->geometry.height)
|
||||
t->geometry.height = 1.5 * globalconf.font->height;
|
||||
break;
|
||||
case Left:
|
||||
case Right:
|
||||
if(!t->sw.geometry.width)
|
||||
t->sw.geometry.width = 1.5 * globalconf.font->height;
|
||||
if(!t->geometry.width)
|
||||
t->geometry.width = 1.5 * globalconf.font->height;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -256,12 +254,9 @@ titlebar_client_attach(client_t *c)
|
|||
c->geometry = titlebar_geometry_add(c->titlebar, 0, c->geometry);
|
||||
|
||||
/* Client geometry without titlebar, but including borders, since that is always consistent. */
|
||||
area_t wingeom;
|
||||
titlebar_geometry_compute(c, titlebar_geometry_remove(c->titlebar, 0, c->geometry), &wingeom);
|
||||
titlebar_geometry_compute(c, titlebar_geometry_remove(c->titlebar, 0, c->geometry), &t->geometry);
|
||||
|
||||
simplewindow_init(&t->sw, c->phys_screen,
|
||||
wingeom, 0, &t->sw.border.color,
|
||||
t->sw.orientation, &t->sw.ctx.fg, &t->sw.ctx.bg);
|
||||
wibox_init(t, c->phys_screen);
|
||||
|
||||
t->need_update = true;
|
||||
|
||||
|
@ -270,7 +265,7 @@ titlebar_client_attach(client_t *c)
|
|||
* titlebar if needed. */
|
||||
titlebar_update_geometry(c);
|
||||
|
||||
xcb_map_window(globalconf.connection, t->sw.window);
|
||||
xcb_map_window(globalconf.connection, t->window);
|
||||
|
||||
hook_property(client, c, "titlebar");
|
||||
client_stack();
|
||||
|
@ -321,14 +316,14 @@ luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
|
|||
break;
|
||||
case A_TK_BORDER_WIDTH:
|
||||
if((i = luaL_checknumber(L, 3)) >= 0)
|
||||
simplewindow_border_width_set(&titlebar->sw, i);
|
||||
wibox_border_width_set(titlebar, i);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case A_TK_BORDER_COLOR:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&titlebar->sw.border.color, buf, len)))
|
||||
simplewindow_border_color_set(&titlebar->sw, &titlebar->sw.border.color);
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&titlebar->border.color, buf, len)))
|
||||
wibox_border_color_set(titlebar, &titlebar->border.color);
|
||||
return 0;
|
||||
case A_TK_POSITION:
|
||||
buf = luaL_checklstring(L, 3, &len);
|
||||
|
@ -346,12 +341,12 @@ luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
|
|||
break;
|
||||
case Top:
|
||||
case Bottom:
|
||||
tmp = titlebar->sw.geometry.width;
|
||||
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
|
||||
titlebar->sw.geometry.height = tmp;
|
||||
tmp = titlebar->geometry.width;
|
||||
titlebar->geometry.width = titlebar->geometry.height;
|
||||
titlebar->geometry.height = tmp;
|
||||
break;
|
||||
}
|
||||
simplewindow_orientation_set(&titlebar->sw, North);
|
||||
wibox_orientation_set(titlebar, North);
|
||||
break;
|
||||
case Right:
|
||||
switch(titlebar->position)
|
||||
|
@ -362,12 +357,12 @@ luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
|
|||
break;
|
||||
case Top:
|
||||
case Bottom:
|
||||
tmp = titlebar->sw.geometry.width;
|
||||
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
|
||||
titlebar->sw.geometry.height = tmp;
|
||||
tmp = titlebar->geometry.width;
|
||||
titlebar->geometry.width = titlebar->geometry.height;
|
||||
titlebar->geometry.height = tmp;
|
||||
break;
|
||||
}
|
||||
simplewindow_orientation_set(&titlebar->sw, South);
|
||||
wibox_orientation_set(titlebar, South);
|
||||
break;
|
||||
case Top:
|
||||
case Bottom:
|
||||
|
@ -376,15 +371,15 @@ luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
|
|||
int tmp;
|
||||
case Left:
|
||||
case Right:
|
||||
tmp = titlebar->sw.geometry.width;
|
||||
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
|
||||
titlebar->sw.geometry.height = tmp;
|
||||
tmp = titlebar->geometry.width;
|
||||
titlebar->geometry.width = titlebar->geometry.height;
|
||||
titlebar->geometry.height = tmp;
|
||||
break;
|
||||
case Top:
|
||||
case Bottom:
|
||||
break;
|
||||
}
|
||||
simplewindow_orientation_set(&titlebar->sw, East);
|
||||
wibox_orientation_set(titlebar, East);
|
||||
break;
|
||||
}
|
||||
titlebar->position = position;
|
||||
|
|
24
titlebar.h
24
titlebar.h
|
@ -69,18 +69,18 @@ titlebar_geometry_add(wibox_t *t, int border, area_t geometry)
|
|||
switch(t->position)
|
||||
{
|
||||
case Top:
|
||||
geometry.y -= t->sw.geometry.height;
|
||||
geometry.height += t->sw.geometry.height;
|
||||
geometry.y -= t->geometry.height;
|
||||
geometry.height += t->geometry.height;
|
||||
break;
|
||||
case Bottom:
|
||||
geometry.height += t->sw.geometry.height;
|
||||
geometry.height += t->geometry.height;
|
||||
break;
|
||||
case Left:
|
||||
geometry.x -= t->sw.geometry.width;
|
||||
geometry.width += t->sw.geometry.width;
|
||||
geometry.x -= t->geometry.width;
|
||||
geometry.width += t->geometry.width;
|
||||
break;
|
||||
case Right:
|
||||
geometry.width += t->sw.geometry.width;
|
||||
geometry.width += t->geometry.width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -110,18 +110,18 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t geometry)
|
|||
switch(t->position)
|
||||
{
|
||||
case Top:
|
||||
geometry.y += t->sw.geometry.height;
|
||||
unsigned_subtract(geometry.height, t->sw.geometry.height);
|
||||
geometry.y += t->geometry.height;
|
||||
unsigned_subtract(geometry.height, t->geometry.height);
|
||||
break;
|
||||
case Bottom:
|
||||
unsigned_subtract(geometry.height, t->sw.geometry.height);
|
||||
unsigned_subtract(geometry.height, t->geometry.height);
|
||||
break;
|
||||
case Left:
|
||||
geometry.x += t->sw.geometry.width;
|
||||
unsigned_subtract(geometry.width, t->sw.geometry.width);
|
||||
geometry.x += t->geometry.width;
|
||||
unsigned_subtract(geometry.width, t->geometry.width);
|
||||
break;
|
||||
case Right:
|
||||
unsigned_subtract(geometry.width, t->sw.geometry.width);
|
||||
unsigned_subtract(geometry.width, t->geometry.width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
509
wibox.c
509
wibox.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* wibox.c - wibox functions
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
* Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,6 +19,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <xcb/shape.h>
|
||||
|
||||
#include "screen.h"
|
||||
#include "wibox.h"
|
||||
#include "titlebar.h"
|
||||
|
@ -39,7 +41,7 @@ luaA_wibox_gc(lua_State *L)
|
|||
{
|
||||
wibox_t *wibox = luaL_checkudata(L, 1, "wibox");
|
||||
p_delete(&wibox->cursor);
|
||||
simplewindow_wipe(&wibox->sw);
|
||||
wibox_wipe(wibox);
|
||||
widget_node_array_wipe(&wibox->widgets);
|
||||
return luaA_object_gc(L);
|
||||
}
|
||||
|
@ -50,6 +52,289 @@ wibox_unref_simplified(wibox_t **item)
|
|||
wibox_unref(globalconf.L, *item);
|
||||
}
|
||||
|
||||
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
|
||||
shape_update(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 wibox The simplw window whose shape should be updated.
|
||||
*/
|
||||
static void
|
||||
wibox_shape_update(wibox_t *wibox)
|
||||
{
|
||||
if(wibox->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;
|
||||
}
|
||||
|
||||
shape_update(wibox->window, XCB_SHAPE_SK_CLIP, wibox->shape.clip, 0);
|
||||
shape_update(wibox->window, XCB_SHAPE_SK_BOUNDING, wibox->shape.bounding, - wibox->border.width);
|
||||
|
||||
wibox->need_shape_update = false;
|
||||
}
|
||||
|
||||
static void
|
||||
wibox_draw_context_update(wibox_t *w, xcb_screen_t *s)
|
||||
{
|
||||
xcolor_t fg = w->ctx.fg, bg = w->ctx.bg;
|
||||
int phys_screen = w->ctx.phys_screen;
|
||||
|
||||
draw_context_wipe(&w->ctx);
|
||||
|
||||
/* update draw context */
|
||||
switch(w->orientation)
|
||||
{
|
||||
case South:
|
||||
case North:
|
||||
/* we need a new pixmap this way [ ] to render */
|
||||
w->ctx.pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection,
|
||||
s->root_depth,
|
||||
w->ctx.pixmap, s->root,
|
||||
w->geometries.internal.height, w->geometries.internal.width);
|
||||
draw_context_init(&w->ctx, phys_screen,
|
||||
w->geometries.internal.height, w->geometries.internal.width,
|
||||
w->ctx.pixmap, &fg, &bg);
|
||||
break;
|
||||
case East:
|
||||
draw_context_init(&w->ctx, phys_screen,
|
||||
w->geometries.internal.width, w->geometries.internal.height,
|
||||
w->pixmap, &fg, &bg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize a wibox.
|
||||
* \param w The wibox to initialize.
|
||||
* \param phys_screen Physical screen number.
|
||||
*/
|
||||
void
|
||||
wibox_init(wibox_t *w, int phys_screen)
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
|
||||
|
||||
/* Copy the real protocol window geometry. */
|
||||
w->geometries.internal.x = w->geometry.x;
|
||||
w->geometries.internal.y = w->geometry.y;
|
||||
w->geometries.internal.width = w->geometry.width;
|
||||
w->geometries.internal.height = w->geometry.height;
|
||||
|
||||
w->window = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_window(globalconf.connection, s->root_depth, w->window, s->root,
|
||||
w->geometries.internal.x, w->geometries.internal.y,
|
||||
w->geometries.internal.width, w->geometries.internal.height,
|
||||
w->border.width, XCB_COPY_FROM_PARENT, s->root_visual,
|
||||
XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL
|
||||
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
|
||||
(const uint32_t [])
|
||||
{
|
||||
XCB_BACK_PIXMAP_PARENT_RELATIVE,
|
||||
w->border.color.pixel,
|
||||
1,
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW
|
||||
| XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||
| XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
|
||||
| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE
|
||||
| XCB_EVENT_MASK_PROPERTY_CHANGE
|
||||
});
|
||||
|
||||
/* Create a pixmap. */
|
||||
w->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, w->pixmap, s->root,
|
||||
w->geometries.internal.width, w->geometries.internal.height);
|
||||
|
||||
/* Update draw context physical screen, important for Zaphod. */
|
||||
w->ctx.phys_screen = phys_screen;
|
||||
wibox_draw_context_update(w, s);
|
||||
|
||||
/* The default GC is just a newly created associated to the root window */
|
||||
w->gc = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_gc(globalconf.connection, w->gc, s->root, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
|
||||
(const uint32_t[]) { s->black_pixel, s->white_pixel });
|
||||
|
||||
wibox_shape_update(w);
|
||||
}
|
||||
|
||||
/** Refresh the window content by copying its pixmap data to its window.
|
||||
* \param w The wibox to refresh.
|
||||
*/
|
||||
static inline void
|
||||
wibox_refresh_pixmap(wibox_t *w)
|
||||
{
|
||||
wibox_refresh_pixmap_partial(w, 0, 0, w->geometry.width, w->geometry.height);
|
||||
}
|
||||
|
||||
/** Set a wibox opacity.
|
||||
* \param w The wibox the adjust the opacity of.
|
||||
* \param opacity A value between 0 and 1 which describes the opacity.
|
||||
*/
|
||||
static inline void
|
||||
wibox_opacity_set(wibox_t *w, double opacity)
|
||||
{
|
||||
w->opacity = opacity;
|
||||
if(w->window != XCB_NONE)
|
||||
window_opacity_set(w->window, opacity);
|
||||
}
|
||||
|
||||
void
|
||||
wibox_moveresize(wibox_t *w, area_t geometry)
|
||||
{
|
||||
if(w->window)
|
||||
{
|
||||
uint32_t moveresize_win_vals[4], mask_vals = 0;
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, w->ctx.phys_screen);
|
||||
|
||||
area_t geom_internal = geometry;
|
||||
geom_internal.width -= 2 * w->border.width;
|
||||
geom_internal.height -= 2* w->border.width;
|
||||
|
||||
if(w->geometries.internal.x != geom_internal.x || w->geometries.internal.y != geom_internal.y)
|
||||
{
|
||||
w->geometries.internal.x = moveresize_win_vals[0] = geom_internal.x;
|
||||
w->geometries.internal.y = moveresize_win_vals[1] = geom_internal.y;
|
||||
mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
}
|
||||
|
||||
if(w->geometry.width != geometry.width || w->geometry.height != geometry.height)
|
||||
{
|
||||
if(mask_vals)
|
||||
{
|
||||
w->geometries.internal.width = moveresize_win_vals[2] = geom_internal.width;
|
||||
w->geometries.internal.height = moveresize_win_vals[3] = geom_internal.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
w->geometries.internal.width = moveresize_win_vals[0] = geom_internal.width;
|
||||
w->geometries.internal.height = moveresize_win_vals[1] = geom_internal.height;
|
||||
}
|
||||
mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||
xcb_free_pixmap(globalconf.connection, w->pixmap);
|
||||
/* orientation != East */
|
||||
if(w->pixmap != w->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, w->ctx.pixmap);
|
||||
w->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, w->pixmap, s->root, geom_internal.width, geom_internal.height);
|
||||
wibox_draw_context_update(w, s);
|
||||
}
|
||||
|
||||
/* Also save geometry including border. */
|
||||
w->geometry = geometry;
|
||||
|
||||
xcb_configure_window(globalconf.connection, w->window, mask_vals, moveresize_win_vals);
|
||||
}
|
||||
else
|
||||
w->geometry = geometry;
|
||||
|
||||
w->need_update = true;
|
||||
}
|
||||
|
||||
/** Refresh the window content by copying its pixmap data to its window.
|
||||
* \param wibox The wibox to refresh.
|
||||
* \param x The copy starting point x component.
|
||||
* \param y The copy starting point y component.
|
||||
* \param w The copy width from the x component.
|
||||
* \param h The copy height from the y component.
|
||||
*/
|
||||
void
|
||||
wibox_refresh_pixmap_partial(wibox_t *wibox,
|
||||
int16_t x, int16_t y,
|
||||
uint16_t w, uint16_t h)
|
||||
{
|
||||
xcb_copy_area(globalconf.connection, wibox->pixmap,
|
||||
wibox->window, wibox->gc, x, y, x, y,
|
||||
w, h);
|
||||
}
|
||||
|
||||
/** Set a wibox border width.
|
||||
* \param w The wibox to change border width.
|
||||
* \param border_width The border width in pixel.
|
||||
*/
|
||||
void
|
||||
wibox_border_width_set(wibox_t *w, uint32_t border_width)
|
||||
{
|
||||
xcb_configure_window(globalconf.connection, w->window, XCB_CONFIG_WINDOW_BORDER_WIDTH,
|
||||
&border_width);
|
||||
w->border.width = border_width;
|
||||
}
|
||||
|
||||
/** Set a wibox border color.
|
||||
* \param w The wibox to change border width.
|
||||
* \param color The border color.
|
||||
*/
|
||||
void
|
||||
wibox_border_color_set(wibox_t *w, const xcolor_t *color)
|
||||
{
|
||||
xcb_change_window_attributes(globalconf.connection, w->window,
|
||||
XCB_CW_BORDER_PIXEL, &color->pixel);
|
||||
w->border.color = *color;
|
||||
}
|
||||
|
||||
/** Set wibox orientation.
|
||||
* \param w The wibox.
|
||||
* \param o The new orientation.
|
||||
*/
|
||||
void
|
||||
wibox_orientation_set(wibox_t *w, orientation_t o)
|
||||
{
|
||||
if(o != w->orientation)
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, w->ctx.phys_screen);
|
||||
w->orientation = o;
|
||||
/* orientation != East */
|
||||
if(w->pixmap != w->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, w->ctx.pixmap);
|
||||
wibox_draw_context_update(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set wibox cursor.
|
||||
* \param w The wibox.
|
||||
* \param c The cursor.
|
||||
*/
|
||||
static void
|
||||
wibox_cursor_set(wibox_t *w, xcb_cursor_t c)
|
||||
{
|
||||
if(w->window)
|
||||
xcb_change_window_attributes(globalconf.connection, w->window, XCB_CW_CURSOR,
|
||||
(const uint32_t[]) { c });
|
||||
}
|
||||
|
||||
static void
|
||||
wibox_need_update(wibox_t *wibox)
|
||||
{
|
||||
|
@ -60,7 +345,7 @@ wibox_need_update(wibox_t *wibox)
|
|||
static void
|
||||
wibox_map(wibox_t *wibox)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, wibox->sw.window);
|
||||
xcb_map_window(globalconf.connection, wibox->window);
|
||||
/* We must make sure the wibox does not display garbage */
|
||||
wibox_need_update(wibox);
|
||||
/* Stack this wibox correctly */
|
||||
|
@ -70,32 +355,61 @@ wibox_map(wibox_t *wibox)
|
|||
static void
|
||||
wibox_move(wibox_t *wibox, int16_t x, int16_t y)
|
||||
{
|
||||
if(wibox->sw.window)
|
||||
wibox->geometry.x = x;
|
||||
wibox->geometry.y = y;
|
||||
|
||||
if(wibox->window
|
||||
&& (x != wibox->geometries.internal.x || y != wibox->geometries.internal.y))
|
||||
{
|
||||
simplewindow_move(&wibox->sw, x, y);
|
||||
wibox->geometry.x = wibox->geometries.internal.x = x;
|
||||
wibox->geometry.y = wibox->geometries.internal.y = y;
|
||||
|
||||
xcb_configure_window(globalconf.connection, wibox->window,
|
||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
||||
(const uint32_t[]) { x, y });
|
||||
|
||||
wibox->screen = screen_getbycoord(wibox->screen, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
wibox->sw.geometry.x = x;
|
||||
wibox->sw.geometry.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wibox_resize(wibox_t *wibox, uint16_t width, uint16_t height)
|
||||
wibox_resize(wibox_t *w, uint16_t width, uint16_t height)
|
||||
{
|
||||
if(wibox->sw.window)
|
||||
simplewindow_resize(&wibox->sw, width, height);
|
||||
if(w->window)
|
||||
{
|
||||
int iw = width - 2 * w->border.width;
|
||||
int ih = height - 2 * w->border.width;
|
||||
|
||||
if(iw > 0 && ih > 0 &&
|
||||
(w->geometries.internal.width != iw || w->geometries.internal.height != ih))
|
||||
{
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, w->ctx.phys_screen);
|
||||
uint32_t resize_win_vals[2];
|
||||
|
||||
w->geometries.internal.width = resize_win_vals[0] = iw;
|
||||
w->geometries.internal.height = resize_win_vals[1] = ih;
|
||||
w->geometry.width = width;
|
||||
w->geometry.height = height;
|
||||
xcb_free_pixmap(globalconf.connection, w->pixmap);
|
||||
/* orientation != East */
|
||||
if(w->pixmap != w->ctx.pixmap)
|
||||
xcb_free_pixmap(globalconf.connection, w->ctx.pixmap);
|
||||
w->pixmap = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_pixmap(globalconf.connection, s->root_depth, w->pixmap, s->root, iw, ih);
|
||||
xcb_configure_window(globalconf.connection, w->window,
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
resize_win_vals);
|
||||
wibox_draw_context_update(w, s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wibox->sw.geometry.width = width;
|
||||
wibox->sw.geometry.height = height;
|
||||
w->geometry.width = width;
|
||||
w->geometry.height = height;
|
||||
}
|
||||
wibox_need_update(wibox);
|
||||
wibox_need_update(w);
|
||||
}
|
||||
|
||||
|
||||
/** Kick out systray windows.
|
||||
* \param phys_screen Physical screen number.
|
||||
*/
|
||||
|
@ -128,11 +442,11 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
widget_node_t *systray = &wibox->widgets.tab[i];
|
||||
if(systray->widget->type == widget_systray)
|
||||
{
|
||||
uint32_t config_back[] = { wibox->sw.ctx.bg.pixel };
|
||||
uint32_t config_back[] = { wibox->ctx.bg.pixel };
|
||||
uint32_t config_win_vals[4];
|
||||
uint32_t config_win_vals_off[2] = { -512, -512 };
|
||||
xembed_window_t *em;
|
||||
int phys_screen = wibox->sw.ctx.phys_screen;
|
||||
int phys_screen = wibox->ctx.phys_screen;
|
||||
|
||||
if(wibox->isvisible
|
||||
&& systray->widget->isvisible
|
||||
|
@ -145,11 +459,11 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
/* Map it. */
|
||||
xcb_map_window(globalconf.connection, globalconf.screens.tab[phys_screen].systray.window);
|
||||
/* Move it. */
|
||||
switch(wibox->sw.orientation)
|
||||
switch(wibox->orientation)
|
||||
{
|
||||
case North:
|
||||
config_win_vals[0] = systray->geometry.y;
|
||||
config_win_vals[1] = wibox->sw.geometry.height - systray->geometry.x - systray->geometry.width;
|
||||
config_win_vals[1] = wibox->geometry.height - systray->geometry.x - systray->geometry.width;
|
||||
config_win_vals[2] = systray->geometry.height;
|
||||
config_win_vals[3] = systray->geometry.width;
|
||||
break;
|
||||
|
@ -167,13 +481,13 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
break;
|
||||
}
|
||||
/* reparent */
|
||||
if(globalconf.screens.tab[phys_screen].systray.parent != wibox->sw.window)
|
||||
if(globalconf.screens.tab[phys_screen].systray.parent != wibox->window)
|
||||
{
|
||||
xcb_reparent_window(globalconf.connection,
|
||||
globalconf.screens.tab[phys_screen].systray.window,
|
||||
wibox->sw.window,
|
||||
wibox->window,
|
||||
config_win_vals[0], config_win_vals[1]);
|
||||
globalconf.screens.tab[phys_screen].systray.parent = wibox->sw.window;
|
||||
globalconf.screens.tab[phys_screen].systray.parent = wibox->window;
|
||||
}
|
||||
xcb_configure_window(globalconf.connection,
|
||||
globalconf.screens.tab[phys_screen].systray.window,
|
||||
|
@ -189,7 +503,7 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
else
|
||||
return wibox_systray_kickout(phys_screen);
|
||||
|
||||
switch(wibox->sw.orientation)
|
||||
switch(wibox->orientation)
|
||||
{
|
||||
case North:
|
||||
config_win_vals[1] = systray->geometry.width - config_win_vals[3];
|
||||
|
@ -198,7 +512,7 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
em = &globalconf.embedded.tab[j];
|
||||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) wibox->sw.geometry.y)
|
||||
if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) wibox->geometry.y)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
|
@ -225,7 +539,7 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
/* if(y + width <= wibox.y + systray.right) */
|
||||
if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) wibox->sw.geometry.y + AREA_RIGHT(systray->geometry))
|
||||
if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) wibox->geometry.y + AREA_RIGHT(systray->geometry))
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
|
@ -252,7 +566,7 @@ wibox_systray_refresh(wibox_t *wibox)
|
|||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
/* if(x + width < systray.x + systray.width) */
|
||||
if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(systray->geometry) + wibox->sw.geometry.x)
|
||||
if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(systray->geometry) + wibox->geometry.x)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
|
@ -285,13 +599,13 @@ wibox_t *
|
|||
wibox_getbywin(xcb_window_t win)
|
||||
{
|
||||
foreach(w, globalconf.wiboxes)
|
||||
if((*w)->sw.window == win)
|
||||
if((*w)->window == win)
|
||||
return *w;
|
||||
|
||||
foreach(_c, globalconf.clients)
|
||||
{
|
||||
client_t *c = *_c;
|
||||
if(c->titlebar && c->titlebar->sw.window == win)
|
||||
if(c->titlebar && c->titlebar->window == win)
|
||||
return c->titlebar;
|
||||
}
|
||||
|
||||
|
@ -307,7 +621,7 @@ wibox_draw(wibox_t *wibox)
|
|||
if(wibox->isvisible)
|
||||
{
|
||||
widget_render(wibox);
|
||||
simplewindow_refresh_pixmap(&wibox->sw);
|
||||
wibox_refresh_pixmap(wibox);
|
||||
|
||||
wibox->need_update = false;
|
||||
}
|
||||
|
@ -323,10 +637,7 @@ wibox_refresh(void)
|
|||
foreach(w, globalconf.wiboxes)
|
||||
{
|
||||
if((*w)->need_shape_update)
|
||||
{
|
||||
simplewindow_update_shape(&(*w)->sw);
|
||||
(*w)->need_shape_update = false;
|
||||
}
|
||||
wibox_shape_update(*w);
|
||||
if((*w)->need_update)
|
||||
wibox_draw(*w);
|
||||
}
|
||||
|
@ -356,7 +667,7 @@ wibox_setvisible(wibox_t *wibox, bool v)
|
|||
if(wibox->isvisible)
|
||||
wibox_map(wibox);
|
||||
else
|
||||
xcb_unmap_window(globalconf.connection, wibox->sw.window);
|
||||
xcb_unmap_window(globalconf.connection, wibox->window);
|
||||
|
||||
/* kick out systray if needed */
|
||||
wibox_systray_refresh(wibox);
|
||||
|
@ -366,6 +677,30 @@ wibox_setvisible(wibox_t *wibox, bool v)
|
|||
}
|
||||
}
|
||||
|
||||
/** Destroy all X resources of a wibox.
|
||||
* \param w The wibox to wipe.
|
||||
*/
|
||||
void
|
||||
wibox_wipe(wibox_t *w)
|
||||
{
|
||||
if(w->window)
|
||||
{
|
||||
xcb_destroy_window(globalconf.connection, w->window);
|
||||
w->window = XCB_NONE;
|
||||
}
|
||||
if(w->pixmap)
|
||||
{
|
||||
xcb_free_pixmap(globalconf.connection, w->pixmap);
|
||||
w->pixmap = XCB_NONE;
|
||||
}
|
||||
if(w->gc)
|
||||
{
|
||||
xcb_free_gc(globalconf.connection, w->gc);
|
||||
w->gc = XCB_NONE;
|
||||
}
|
||||
draw_context_wipe(&w->ctx);
|
||||
}
|
||||
|
||||
/** Remove a wibox from a screen.
|
||||
* \param wibox Wibox to detach from screen.
|
||||
*/
|
||||
|
@ -385,7 +720,7 @@ wibox_detach(wibox_t *wibox)
|
|||
|
||||
wibox->mouse_over = NULL;
|
||||
|
||||
simplewindow_wipe(&wibox->sw);
|
||||
wibox_wipe(wibox);
|
||||
|
||||
foreach(item, globalconf.wiboxes)
|
||||
if(*item == wibox)
|
||||
|
@ -419,7 +754,7 @@ wibox_attach(screen_t *s)
|
|||
|
||||
/* Check that the wibox coordinates matches the screen. */
|
||||
screen_t *cscreen =
|
||||
screen_getbycoord(wibox->screen, wibox->sw.geometry.x, wibox->sw.geometry.y);
|
||||
screen_getbycoord(wibox->screen, wibox->geometry.x, wibox->geometry.y);
|
||||
|
||||
/* If it does not match, move it to the screen coordinates */
|
||||
if(cscreen != wibox->screen)
|
||||
|
@ -427,17 +762,12 @@ wibox_attach(screen_t *s)
|
|||
|
||||
wibox_array_append(&globalconf.wiboxes, wibox);
|
||||
|
||||
simplewindow_init(&wibox->sw, phys_screen,
|
||||
wibox->sw.geometry,
|
||||
wibox->sw.border.width,
|
||||
&wibox->sw.border.color,
|
||||
wibox->sw.orientation,
|
||||
&wibox->sw.ctx.fg, &wibox->sw.ctx.bg);
|
||||
wibox_init(wibox, phys_screen);
|
||||
|
||||
simplewindow_cursor_set(&wibox->sw,
|
||||
xcursor_new(globalconf.connection, xcursor_font_fromstr(wibox->cursor)));
|
||||
wibox_cursor_set(wibox,
|
||||
xcursor_new(globalconf.connection, xcursor_font_fromstr(wibox->cursor)));
|
||||
|
||||
simplewindow_opacity_set(&wibox->sw, wibox->sw.opacity);
|
||||
wibox_opacity_set(wibox, wibox->opacity);
|
||||
|
||||
if(wibox->isvisible)
|
||||
wibox_map(wibox);
|
||||
|
@ -468,26 +798,26 @@ luaA_wibox_new(lua_State *L)
|
|||
|
||||
w = wibox_new(L);
|
||||
|
||||
w->sw.ctx.fg = globalconf.colors.fg;
|
||||
w->ctx.fg = globalconf.colors.fg;
|
||||
if((buf = luaA_getopt_lstring(L, 2, "fg", NULL, &len)))
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.fg, buf, len);
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->ctx.fg, buf, len);
|
||||
|
||||
w->sw.ctx.bg = globalconf.colors.bg;
|
||||
w->ctx.bg = globalconf.colors.bg;
|
||||
if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len)))
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.bg, buf, len);
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->ctx.bg, buf, len);
|
||||
|
||||
w->sw.border.color = globalconf.colors.bg;
|
||||
w->border.color = globalconf.colors.bg;
|
||||
if((buf = luaA_getopt_lstring(L, 2, "border_color", NULL, &len)))
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.border.color, buf, len);
|
||||
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->border.color, buf, len);
|
||||
|
||||
w->ontop = luaA_getopt_boolean(L, 2, "ontop", false);
|
||||
|
||||
w->sw.opacity = -1;
|
||||
w->sw.border.width = luaA_getopt_number(L, 2, "border_width", 0);
|
||||
w->sw.geometry.x = luaA_getopt_number(L, 2, "x", 0);
|
||||
w->sw.geometry.y = luaA_getopt_number(L, 2, "y", 0);
|
||||
w->sw.geometry.width = luaA_getopt_number(L, 2, "width", 100);
|
||||
w->sw.geometry.height = luaA_getopt_number(L, 2, "height", globalconf.font->height * 1.5);
|
||||
w->opacity = -1;
|
||||
w->border.width = luaA_getopt_number(L, 2, "border_width", 0);
|
||||
w->geometry.x = luaA_getopt_number(L, 2, "x", 0);
|
||||
w->geometry.y = luaA_getopt_number(L, 2, "y", 0);
|
||||
w->geometry.width = luaA_getopt_number(L, 2, "width", 100);
|
||||
w->geometry.height = luaA_getopt_number(L, 2, "height", globalconf.font->height * 1.5);
|
||||
|
||||
w->isvisible = true;
|
||||
w->cursor = a_strdup("left_ptr");
|
||||
|
@ -595,10 +925,10 @@ luaA_wibox_index(lua_State *L)
|
|||
lua_pushnumber(L, screen_array_indexof(&globalconf.screens, wibox->screen) + 1);
|
||||
break;
|
||||
case A_TK_BORDER_WIDTH:
|
||||
lua_pushnumber(L, wibox->sw.border.width);
|
||||
lua_pushnumber(L, wibox->border.width);
|
||||
break;
|
||||
case A_TK_BORDER_COLOR:
|
||||
luaA_pushxcolor(L, &wibox->sw.border.color);
|
||||
luaA_pushxcolor(L, &wibox->border.color);
|
||||
break;
|
||||
case A_TK_ALIGN:
|
||||
if(wibox->type == WIBOX_TYPE_NORMAL)
|
||||
|
@ -606,10 +936,10 @@ luaA_wibox_index(lua_State *L)
|
|||
lua_pushstring(L, draw_align_tostr(wibox->align));
|
||||
break;
|
||||
case A_TK_FG:
|
||||
luaA_pushxcolor(L, &wibox->sw.ctx.fg);
|
||||
luaA_pushxcolor(L, &wibox->ctx.fg);
|
||||
break;
|
||||
case A_TK_BG:
|
||||
luaA_pushxcolor(L, &wibox->sw.ctx.bg);
|
||||
luaA_pushxcolor(L, &wibox->ctx.bg);
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
luaA_object_push_item(L, 1, wibox->bg_image);
|
||||
|
@ -623,7 +953,7 @@ luaA_wibox_index(lua_State *L)
|
|||
lua_pushboolean(L, wibox->ontop);
|
||||
break;
|
||||
case A_TK_ORIENTATION:
|
||||
lua_pushstring(L, orientation_tostr(wibox->sw.orientation));
|
||||
lua_pushstring(L, orientation_tostr(wibox->orientation));
|
||||
break;
|
||||
case A_TK_WIDGETS:
|
||||
return luaA_object_push_item(L, 1, wibox->widgets_table);
|
||||
|
@ -631,22 +961,19 @@ luaA_wibox_index(lua_State *L)
|
|||
lua_pushstring(L, wibox->cursor);
|
||||
break;
|
||||
case A_TK_OPACITY:
|
||||
{
|
||||
double d = simplewindow_opacity_get(&wibox->sw);
|
||||
if (d >= 0)
|
||||
lua_pushnumber(L, d);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (wibox->opacity >= 0)
|
||||
lua_pushnumber(L, wibox->opacity);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
return luaA_object_push_item(L, 1, wibox->mouse_enter);
|
||||
case A_TK_MOUSE_LEAVE:
|
||||
return luaA_object_push_item(L, 1, wibox->mouse_leave);
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
return luaA_object_push_item(L, 1, wibox->sw.shape.bounding);
|
||||
return luaA_object_push_item(L, 1, wibox->shape.bounding);
|
||||
case A_TK_SHAPE_CLIP:
|
||||
return luaA_object_push_item(L, 1, wibox->sw.shape.clip);
|
||||
return luaA_object_push_item(L, 1, wibox->shape.clip);
|
||||
case A_TK_BUTTONS:
|
||||
return luaA_object_push_item(L, 1, wibox->buttons);
|
||||
default:
|
||||
|
@ -673,10 +1000,10 @@ luaA_wibox_geometry(lua_State *L)
|
|||
area_t wingeom;
|
||||
|
||||
luaA_checktable(L, 2);
|
||||
wingeom.x = luaA_getopt_number(L, 2, "x", wibox->sw.geometry.x);
|
||||
wingeom.y = luaA_getopt_number(L, 2, "y", wibox->sw.geometry.y);
|
||||
wingeom.width = luaA_getopt_number(L, 2, "width", wibox->sw.geometry.width);
|
||||
wingeom.height = luaA_getopt_number(L, 2, "height", wibox->sw.geometry.height);
|
||||
wingeom.x = luaA_getopt_number(L, 2, "x", wibox->geometry.x);
|
||||
wingeom.y = luaA_getopt_number(L, 2, "y", wibox->geometry.y);
|
||||
wingeom.width = luaA_getopt_number(L, 2, "width", wibox->geometry.width);
|
||||
wingeom.height = luaA_getopt_number(L, 2, "height", wibox->geometry.height);
|
||||
|
||||
switch(wibox->type)
|
||||
{
|
||||
|
@ -689,7 +1016,7 @@ luaA_wibox_geometry(lua_State *L)
|
|||
}
|
||||
}
|
||||
|
||||
return luaA_pusharea(L, wibox->sw.geometry);
|
||||
return luaA_pusharea(L, wibox->geometry);
|
||||
}
|
||||
|
||||
/** Wibox newindex.
|
||||
|
@ -710,12 +1037,12 @@ luaA_wibox_newindex(lua_State *L)
|
|||
|
||||
case A_TK_FG:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->sw.ctx.fg, buf, len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.fg, buf, len)))
|
||||
wibox->need_update = true;
|
||||
break;
|
||||
case A_TK_BG:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->sw.ctx.bg, buf, len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.bg, buf, len)))
|
||||
wibox->need_update = true;
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
|
@ -770,7 +1097,7 @@ luaA_wibox_newindex(lua_State *L)
|
|||
xcb_cursor_t cursor = xcursor_new(globalconf.connection, cursor_font);
|
||||
p_delete(&wibox->cursor);
|
||||
wibox->cursor = a_strdup(buf);
|
||||
simplewindow_cursor_set(&wibox->sw, cursor);
|
||||
wibox_cursor_set(wibox, cursor);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -803,15 +1130,15 @@ luaA_wibox_newindex(lua_State *L)
|
|||
case A_TK_ORIENTATION:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
{
|
||||
simplewindow_orientation_set(&wibox->sw, orientation_fromstr(buf, len));
|
||||
wibox_orientation_set(wibox, orientation_fromstr(buf, len));
|
||||
wibox_need_update(wibox);
|
||||
}
|
||||
break;
|
||||
case A_TK_BORDER_COLOR:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->sw.border.color, buf, len)))
|
||||
if(wibox->sw.window)
|
||||
simplewindow_border_color_set(&wibox->sw, &wibox->sw.border.color);
|
||||
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->border.color, buf, len)))
|
||||
if(wibox->window)
|
||||
wibox_border_color_set(wibox, &wibox->border.color);
|
||||
break;
|
||||
case A_TK_VISIBLE:
|
||||
b = luaA_checkboolean(L, 3);
|
||||
|
@ -841,12 +1168,12 @@ luaA_wibox_newindex(lua_State *L)
|
|||
break;
|
||||
case A_TK_OPACITY:
|
||||
if(lua_isnil(L, 3))
|
||||
simplewindow_opacity_set(&wibox->sw, -1);
|
||||
wibox_opacity_set(wibox, -1);
|
||||
else
|
||||
{
|
||||
double d = luaL_checknumber(L, 3);
|
||||
if(d >= 0 && d <= 1)
|
||||
simplewindow_opacity_set(&wibox->sw, d);
|
||||
wibox_opacity_set(wibox, d);
|
||||
}
|
||||
break;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
|
@ -860,13 +1187,13 @@ luaA_wibox_newindex(lua_State *L)
|
|||
wibox->mouse_leave = luaA_object_ref_item(L, 1, 3);
|
||||
return 0;
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
luaA_object_unref_item(L, 1, wibox->sw.shape.bounding);
|
||||
wibox->sw.shape.bounding = luaA_object_ref_item(L, 1, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->shape.bounding);
|
||||
wibox->shape.bounding = luaA_object_ref_item(L, 1, 3);
|
||||
wibox->need_shape_update = true;
|
||||
break;
|
||||
case A_TK_SHAPE_CLIP:
|
||||
luaA_object_unref_item(L, 1, wibox->sw.shape.clip);
|
||||
wibox->sw.shape.clip = luaA_object_ref_item(L, 1, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->shape.clip);
|
||||
wibox->shape.clip = luaA_object_ref_item(L, 1, 3);
|
||||
wibox->need_shape_update = true;
|
||||
case A_TK_BUTTONS:
|
||||
luaA_object_unref_item(L, 1, wibox->buttons);
|
||||
|
|
60
wibox.h
60
wibox.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* wibox.h - wibox functions header
|
||||
*
|
||||
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
|
||||
* Copyright © 2007-2009 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,11 +19,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_STATUSBAR_H
|
||||
#define AWESOME_STATUSBAR_H
|
||||
#ifndef AWESOME_WIBOX_H
|
||||
#define AWESOME_WIBOX_H
|
||||
|
||||
#include "widget.h"
|
||||
#include "swindow.h"
|
||||
|
||||
/** Wibox types */
|
||||
typedef enum
|
||||
|
@ -44,8 +43,6 @@ struct wibox_t
|
|||
position_t position;
|
||||
/** Wibox type */
|
||||
wibox_type_t type;
|
||||
/** Window */
|
||||
simple_window_t sw;
|
||||
/** Alignment */
|
||||
alignment_t align;
|
||||
/** Screen */
|
||||
|
@ -69,6 +66,41 @@ struct wibox_t
|
|||
bool isbanned;
|
||||
/** Button bindings */
|
||||
void *buttons;
|
||||
/** The window object. */
|
||||
xcb_window_t window;
|
||||
/** The pixmap copied to the window object. */
|
||||
xcb_pixmap_t pixmap;
|
||||
/** The graphic context. */
|
||||
xcb_gcontext_t gc;
|
||||
/** The window geometry. */
|
||||
area_t geometry;
|
||||
struct
|
||||
{
|
||||
/** Internal geometry (matching X11 protocol) */
|
||||
area_t internal;
|
||||
} geometries;
|
||||
/** The window border */
|
||||
struct
|
||||
{
|
||||
/** The window border width */
|
||||
uint16_t width;
|
||||
/** The window border color */
|
||||
xcolor_t color;
|
||||
} border;
|
||||
/** Draw context */
|
||||
draw_context_t ctx;
|
||||
/** Orientation */
|
||||
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;
|
||||
};
|
||||
|
||||
void wibox_unref_simplified(wibox_t **);
|
||||
|
@ -81,15 +113,13 @@ void luaA_wibox_invalidate_byitem(lua_State *, const void *);
|
|||
|
||||
wibox_t * wibox_getbywin(xcb_window_t);
|
||||
|
||||
static inline void
|
||||
wibox_moveresize(wibox_t *wibox, area_t geometry)
|
||||
{
|
||||
if(wibox->sw.window)
|
||||
simplewindow_moveresize(&wibox->sw, geometry);
|
||||
else
|
||||
wibox->sw.geometry = geometry;
|
||||
wibox->need_update = true;
|
||||
}
|
||||
void wibox_moveresize(wibox_t *, area_t);
|
||||
void wibox_refresh_pixmap_partial(wibox_t *, int16_t, int16_t, uint16_t, uint16_t);
|
||||
void wibox_init(wibox_t *, int);
|
||||
void wibox_wipe(wibox_t *);
|
||||
void wibox_border_width_set(wibox_t *, uint32_t);
|
||||
void wibox_border_color_set(wibox_t *, const xcolor_t *);
|
||||
void wibox_orientation_set(wibox_t *, orientation_t);
|
||||
|
||||
LUA_OBJECT_FUNCS(wibox_t, wibox, "wibox")
|
||||
|
||||
|
|
30
widget.c
30
widget.c
|
@ -153,20 +153,20 @@ widget_geometries(wibox_t *wibox)
|
|||
if(lua_isfunction(globalconf.L, -1))
|
||||
{
|
||||
/* Push 1st argument: wibox geometry */
|
||||
area_t geometry = wibox->sw.geometry;
|
||||
area_t geometry = wibox->geometry;
|
||||
geometry.x = 0;
|
||||
geometry.y = 0;
|
||||
/* we need to exchange the width and height of the wibox window if it
|
||||
* it is rotated, so the layout function doesn't need to care about that
|
||||
*/
|
||||
if(wibox->sw.orientation != East)
|
||||
if(wibox->orientation != East)
|
||||
{
|
||||
int i = geometry.height;
|
||||
geometry.height = geometry.width;
|
||||
geometry.width = i;
|
||||
}
|
||||
geometry.height -= 2 * wibox->sw.border.width;
|
||||
geometry.width -= 2 * wibox->sw.border.width;
|
||||
geometry.height -= 2 * wibox->border.width;
|
||||
geometry.width -= 2 * wibox->border.width;
|
||||
luaA_pusharea(globalconf.L, geometry);
|
||||
/* Re-push 2nd argument: widget table */
|
||||
lua_pushvalue(globalconf.L, -3);
|
||||
|
@ -212,8 +212,8 @@ widget_geometries(wibox_t *wibox)
|
|||
area_t geometry = widget->extents(globalconf.L, widget);
|
||||
lua_pop(globalconf.L, 1);
|
||||
geometry.x = geometry.y = 0;
|
||||
geometry.width = MIN(wibox->sw.geometry.width, geometry.width);
|
||||
geometry.height = MIN(wibox->sw.geometry.height, geometry.height);
|
||||
geometry.width = MIN(wibox->geometry.width, geometry.width);
|
||||
geometry.height = MIN(wibox->geometry.height, geometry.height);
|
||||
|
||||
luaA_pusharea(globalconf.L, geometry);
|
||||
|
||||
|
@ -231,7 +231,7 @@ void
|
|||
widget_render(wibox_t *wibox)
|
||||
{
|
||||
lua_State *L = globalconf.L;
|
||||
draw_context_t *ctx = &wibox->sw.ctx;
|
||||
draw_context_t *ctx = &wibox->ctx;
|
||||
area_t rectangle = { 0, 0, 0, 0 };
|
||||
color_t col;
|
||||
|
||||
|
@ -243,7 +243,7 @@ widget_render(wibox_t *wibox)
|
|||
|
||||
if(ctx->bg.alpha != 0xffff)
|
||||
{
|
||||
int x = wibox->sw.geometry.x, y = wibox->sw.geometry.y;
|
||||
int x = wibox->geometry.x, y = wibox->geometry.y;
|
||||
xcb_get_property_reply_t *prop_r;
|
||||
char *data;
|
||||
xcb_pixmap_t rootpix;
|
||||
|
@ -256,7 +256,7 @@ widget_render(wibox_t *wibox)
|
|||
if(prop_r->value_len
|
||||
&& (data = xcb_get_property_value(prop_r))
|
||||
&& (rootpix = *(xcb_pixmap_t *) data))
|
||||
switch(wibox->sw.orientation)
|
||||
switch(wibox->orientation)
|
||||
{
|
||||
case North:
|
||||
draw_rotate(ctx,
|
||||
|
@ -278,7 +278,7 @@ widget_render(wibox_t *wibox)
|
|||
break;
|
||||
case East:
|
||||
xcb_copy_area(globalconf.connection, rootpix,
|
||||
wibox->sw.pixmap, wibox->sw.gc,
|
||||
wibox->pixmap, wibox->gc,
|
||||
x, y,
|
||||
0, 0,
|
||||
ctx->width, ctx->height);
|
||||
|
@ -306,8 +306,8 @@ widget_render(wibox_t *wibox)
|
|||
lua_pushnumber(L, i + 1);
|
||||
lua_gettable(L, -2);
|
||||
|
||||
widgets->tab[i].geometry.x = luaA_getopt_number(L, -1, "x", wibox->sw.geometry.x);
|
||||
widgets->tab[i].geometry.y = luaA_getopt_number(L, -1, "y", wibox->sw.geometry.y);
|
||||
widgets->tab[i].geometry.x = luaA_getopt_number(L, -1, "x", wibox->geometry.x);
|
||||
widgets->tab[i].geometry.y = luaA_getopt_number(L, -1, "y", wibox->geometry.y);
|
||||
widgets->tab[i].geometry.width = luaA_getopt_number(L, -1, "width", 1);
|
||||
widgets->tab[i].geometry.height = luaA_getopt_number(L, -1, "height", 1);
|
||||
|
||||
|
@ -329,16 +329,16 @@ widget_render(wibox_t *wibox)
|
|||
widgets->tab[i].widget->draw(widgets->tab[i].widget,
|
||||
ctx, widgets->tab[i].geometry, wibox);
|
||||
|
||||
switch(wibox->sw.orientation)
|
||||
switch(wibox->orientation)
|
||||
{
|
||||
case South:
|
||||
draw_rotate(ctx, ctx->pixmap, wibox->sw.pixmap,
|
||||
draw_rotate(ctx, ctx->pixmap, wibox->pixmap,
|
||||
ctx->width, ctx->height,
|
||||
ctx->height, ctx->width,
|
||||
M_PI_2, ctx->height, 0);
|
||||
break;
|
||||
case North:
|
||||
draw_rotate(ctx, ctx->pixmap, wibox->sw.pixmap,
|
||||
draw_rotate(ctx, ctx->pixmap, wibox->pixmap,
|
||||
ctx->width, ctx->height,
|
||||
ctx->height, ctx->width,
|
||||
- M_PI_2, 0, ctx->width);
|
||||
|
|
|
@ -83,12 +83,12 @@ systray_draw(widget_t *widget, draw_context_t *ctx,
|
|||
}
|
||||
|
||||
systray_data_t *d = widget->data;
|
||||
d->height = p->sw.geometry.height;
|
||||
d->height = p->geometry.height;
|
||||
|
||||
/* set wibox orientation */
|
||||
/** \todo stop setting that property on each redraw */
|
||||
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
|
||||
globalconf.screens.tab[p->sw.ctx.phys_screen].systray.window,
|
||||
globalconf.screens.tab[p->ctx.phys_screen].systray.window,
|
||||
_NET_SYSTEM_TRAY_ORIENTATION, CARDINAL, 32, 1, &orient);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
geometry.y += (geometry.height - textbox_geometry(widget, ctx->phys_screen).height - p->sw.border.width + 1) / 2;
|
||||
geometry.y += (geometry.height - textbox_geometry(widget, ctx->phys_screen).height - p->border.width + 1) / 2;
|
||||
draw_text(ctx, &d->data, d->ellip, d->wrap, d->align, &d->margin, geometry, &d->extents);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue