Wibox: Rename to drawin

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2010-10-06 13:35:14 +02:00
parent d213f19c5f
commit 5f5787d97b
16 changed files with 980 additions and 980 deletions

View File

@ -70,10 +70,10 @@ set(AWE_SRCS
${SOURCE_DIR}/common/xutil.c
${SOURCE_DIR}/objects/button.c
${SOURCE_DIR}/objects/client.c
${SOURCE_DIR}/objects/drawin.c
${SOURCE_DIR}/objects/key.c
${SOURCE_DIR}/objects/tag.c
${SOURCE_DIR}/objects/timer.c
${SOURCE_DIR}/objects/wibox.c
${SOURCE_DIR}/objects/window.c)
set(AWE_MAN_SRCS

41
event.c
View File

@ -29,6 +29,7 @@
#include "event.h"
#include "property.h"
#include "objects/tag.h"
#include "objects/drawin.h"
#include "xwindow.h"
#include "ewmh.h"
#include "objects/client.h"
@ -162,7 +163,7 @@ static void
event_handle_button(xcb_button_press_event_t *ev)
{
client_t *c;
wibox_t *wibox;
drawin_t *drawin;
globalconf.timestamp = ev->time;
@ -175,23 +176,23 @@ event_handle_button(xcb_button_press_event_t *ev)
* drop them */
ev->state &= 0x00ff;
if((wibox = wibox_getbywin(ev->event))
|| (wibox = wibox_getbywin(ev->child)))
if((drawin = drawin_getbywin(ev->event))
|| (drawin = drawin_getbywin(ev->child)))
{
/* If the wibox is child, then x,y are
/* If the drawin is child, then x,y are
* relative to root window */
if(wibox->window == ev->child)
if(drawin->window == ev->child)
{
ev->event_x -= wibox->geometry.x;
ev->event_y -= wibox->geometry.y;
ev->event_x -= drawin->geometry.x;
ev->event_y -= drawin->geometry.y;
}
/* Push the wibox */
luaA_object_push(globalconf.L, wibox);
/* Duplicate the wibox */
/* Push the drawin */
luaA_object_push(globalconf.L, drawin);
/* Duplicate the drawin */
lua_pushvalue(globalconf.L, -1);
/* Handle the button event on it */
event_button_callback(ev, &wibox->buttons, -1, 1, NULL);
event_button_callback(ev, &drawin->buttons, -1, 1, NULL);
/* And handle the button event on it again */
event_emit_button(ev);
@ -352,7 +353,7 @@ event_handle_motionnotify(xcb_motion_notify_event_t *ev)
static void
event_handle_leavenotify(xcb_leave_notify_event_t *ev)
{
wibox_t *wibox;
drawin_t *drawin;
client_t *c;
globalconf.timestamp = ev->time;
@ -367,9 +368,9 @@ event_handle_leavenotify(xcb_leave_notify_event_t *ev)
lua_pop(globalconf.L, 1);
}
if((wibox = wibox_getbywin(ev->event)))
if((drawin = drawin_getbywin(ev->event)))
{
luaA_object_push(globalconf.L, wibox);
luaA_object_push(globalconf.L, drawin);
luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0);
lua_pop(globalconf.L, 1);
}
@ -382,16 +383,16 @@ static void
event_handle_enternotify(xcb_enter_notify_event_t *ev)
{
client_t *c;
wibox_t *wibox;
drawin_t *drawin;
globalconf.timestamp = ev->time;
if(ev->mode != XCB_NOTIFY_MODE_NORMAL)
return;
if((wibox = wibox_getbywin(ev->event)))
if((drawin = drawin_getbywin(ev->event)))
{
luaA_object_push(globalconf.L, wibox);
luaA_object_push(globalconf.L, drawin);
luaA_object_emit_signal(globalconf.L, -1, "mouse::enter", 0);
lua_pop(globalconf.L, 1);
}
@ -441,10 +442,10 @@ event_handle_focusin(xcb_focus_in_event_t *ev)
static void
event_handle_expose(xcb_expose_event_t *ev)
{
wibox_t *wibox;
drawin_t *drawin;
if((wibox = wibox_getbywin(ev->window)))
wibox_refresh_pixmap_partial(wibox,
if((drawin = drawin_getbywin(ev->window)))
drawin_refresh_pixmap_partial(drawin,
ev->x, ev->y,
ev->width, ev->height);
}

View File

@ -23,7 +23,6 @@
#define AWESOME_EVENT_H
#include "systray.h"
#include "objects/wibox.h"
#include "objects/client.h"
static inline int

1
ewmh.c
View File

@ -29,7 +29,6 @@
#include "objects/tag.h"
#include "screen.h"
#include "objects/client.h"
#include "objects/wibox.h"
#include "luaa.h"
#include "common/atoms.h"
#include "common/buffer.h"

View File

@ -35,7 +35,7 @@
#include "font.h"
#include "common/xembed.h"
typedef struct wibox_t wibox_t;
typedef struct drawin_t drawin_t;
typedef struct a_screen screen_t;
typedef struct button_t button_t;
typedef struct widget_t widget_t;
@ -46,7 +46,7 @@ ARRAY_TYPE(button_t *, button)
ARRAY_TYPE(tag_t *, tag)
ARRAY_TYPE(screen_t, screen)
ARRAY_TYPE(client_t *, client)
ARRAY_TYPE(wibox_t *, wibox)
ARRAY_TYPE(drawin_t *, drawin)
/** Main configuration structure */
typedef struct
@ -92,8 +92,8 @@ typedef struct
client_t *prev_client_focus;
/** Focused client */
client_t *client_focus;
/** Wiboxes */
wibox_array_t wiboxes;
/** Drawins */
drawin_array_t drawins;
/** The startup notification display struct */
SnDisplay *sndisplay;
/** Latest timestamp we got from the X server */

5
luaa.c
View File

@ -41,6 +41,7 @@
#include "spawn.h"
#include "objects/tag.h"
#include "objects/client.h"
#include "objects/drawin.h"
#include "screen.h"
#include "event.h"
#include "selection.h"
@ -599,8 +600,8 @@ luaA_init(xdgHandle* xdg)
/* Export window */
window_class_setup(L);
/* Export wibox */
wibox_class_setup(L);
/* Export drawin */
drawin_class_setup(L);
/* Export client */
client_class_setup(L);

View File

@ -23,7 +23,7 @@
#include "screen.h"
#include "objects/client.h"
#include "globalconf.h"
#include "objects/wibox.h"
#include "objects/drawin.h"
#include "luaa.h"
#include "common/xutil.h"
@ -228,11 +228,11 @@ luaA_mouse_object_under_pointer(lua_State *L)
if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL))
return 0;
wibox_t *wibox;
drawin_t *drawin;
client_t *client;
if((wibox = wibox_getbywin(child)))
if((drawin = drawin_getbywin(child)))
{
luaA_object_push(L, wibox);
luaA_object_push(L, drawin);
return 1;
}

View File

@ -25,7 +25,6 @@
#include "objects/tag.h"
#include "ewmh.h"
#include "screen.h"
#include "wibox.h"
#include "systray.h"
#include "property.h"
#include "spawn.h"

903
objects/drawin.c Normal file
View File

@ -0,0 +1,903 @@
/*
* drawin.c - drawin functions
*
* Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
* Copyright © 2010 Uli Schlachter <psychon@znc.in>
*
* 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 "screen.h"
#include "drawin.h"
#include "objects/client.h"
#include "screen.h"
#include "xwindow.h"
#include "luaa.h"
#include "ewmh.h"
#include "common/xcursor.h"
#include "common/xutil.h"
LUA_OBJECT_FUNCS(drawin_class, drawin_t, drawin)
/** Kick out systray windows.
*/
static void
drawin_systray_kickout(void)
{
xcb_screen_t *s = globalconf.screen;
if(globalconf.systray.parent != s->root)
{
/* Who! Check that we're not deleting a drawin with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
xcb_reparent_window(globalconf.connection,
globalconf.systray.window,
s->root, -512, -512);
globalconf.systray.parent = s->root;
}
}
/** Destroy all X resources of a drawin.
* \param w The drawin to wipe.
*/
static void
drawin_wipe_resources(drawin_t *w)
{
if(w->window)
{
/* Activate BMA */
client_ignore_enterleave_events();
/* Make sure we don't accidentally kill the systray window */
if(globalconf.systray.parent == w->window)
drawin_systray_kickout();
xcb_destroy_window(globalconf.connection, w->window);
/* Deactivate BMA */
client_restore_enterleave_events();
w->window = XCB_NONE;
}
if(w->pixmap)
{
xcb_free_pixmap(globalconf.connection, w->pixmap);
w->pixmap = XCB_NONE;
}
draw_context_wipe(&w->ctx);
}
static void
drawin_wipe(drawin_t *drawin)
{
p_delete(&drawin->cursor);
drawin_wipe_resources(drawin);
if(drawin->bg_image)
cairo_surface_destroy(drawin->bg_image);
}
void
drawin_unref_simplified(drawin_t **item)
{
luaA_object_unref(globalconf.L, *item);
}
static void
drawin_draw_context_update(drawin_t *w)
{
xcb_screen_t *s = globalconf.screen;
xcolor_t fg = w->ctx.fg, bg = w->ctx.bg;
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,
globalconf.default_depth,
w->ctx.pixmap, s->root,
w->geometry.height,
w->geometry.width);
draw_context_init(&w->ctx,
w->geometry.height,
w->geometry.width,
w->ctx.pixmap, &fg, &bg);
break;
case East:
draw_context_init(&w->ctx,
w->geometry.width,
w->geometry.height,
w->pixmap, &fg, &bg);
break;
}
}
/** Initialize a drawin.
* \param w The drawin to initialize.
*/
static void
drawin_init(drawin_t *w)
{
xcb_screen_t *s = globalconf.screen;
w->window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth, w->window, s->root,
w->geometry.x, w->geometry.y,
w->geometry.width, w->geometry.height,
w->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
(const uint32_t [])
{
w->ctx.bg.pixel,
w->border_color.pixel,
XCB_GRAVITY_NORTH_WEST,
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_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_PROPERTY_CHANGE,
globalconf.default_cmap
});
/* Create a pixmap. */
w->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root,
w->geometry.width, w->geometry.height);
/* Update draw context physical screen, important for Zaphod. */
drawin_draw_context_update(w);
/* Set the right type property */
ewmh_update_window_type(w->window, window_translate_type(w->type));
}
/** Refresh the window content by copying its pixmap data to its window.
* \param w The drawin to refresh.
*/
static inline void
drawin_refresh_pixmap(drawin_t *w)
{
drawin_refresh_pixmap_partial(w, 0, 0, w->geometry.width, w->geometry.height);
}
/** Move and/or resize a drawin
* \param L The Lua VM state.
* \param udx The index of the drawin.
* \param geometry The new geometry.
*/
static void
drawin_moveresize(lua_State *L, int udx, area_t geometry)
{
drawin_t *w = luaA_checkudata(L, udx, &drawin_class);
if(w->window)
{
int number_of_vals = 0;
uint32_t moveresize_win_vals[4], mask_vals = 0;
if(w->geometry.x != geometry.x)
{
w->geometry.x = moveresize_win_vals[number_of_vals++] = geometry.x;
mask_vals |= XCB_CONFIG_WINDOW_X;
}
if(w->geometry.y != geometry.y)
{
w->geometry.y = moveresize_win_vals[number_of_vals++] = geometry.y;
mask_vals |= XCB_CONFIG_WINDOW_Y;
}
if(geometry.width > 0 && w->geometry.width != geometry.width)
{
w->geometry.width = moveresize_win_vals[number_of_vals++] = geometry.width;
mask_vals |= XCB_CONFIG_WINDOW_WIDTH;
}
if(geometry.height > 0 && w->geometry.height != geometry.height)
{
w->geometry.height = moveresize_win_vals[number_of_vals++] = geometry.height;
mask_vals |= XCB_CONFIG_WINDOW_HEIGHT;
}
if(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_screen_t *s = globalconf.screen;
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root,
w->geometry.width, w->geometry.height);
drawin_draw_context_update(w);
}
/* Activate BMA */
client_ignore_enterleave_events();
if(mask_vals)
xcb_configure_window(globalconf.connection, w->window, mask_vals, moveresize_win_vals);
/* Deactivate BMA */
client_restore_enterleave_events();
w->screen = screen_getbycoord(w->geometry.x, w->geometry.y);
if(mask_vals & XCB_CONFIG_WINDOW_X)
luaA_object_emit_signal(L, udx, "property::x", 0);
if(mask_vals & XCB_CONFIG_WINDOW_Y)
luaA_object_emit_signal(L, udx, "property::y", 0);
if(mask_vals & XCB_CONFIG_WINDOW_WIDTH)
luaA_object_emit_signal(L, udx, "property::width", 0);
if(mask_vals & XCB_CONFIG_WINDOW_HEIGHT)
luaA_object_emit_signal(L, udx, "property::height", 0);
}
else
{
#define DO_drawin_GEOMETRY_CHECK_AND_EMIT(prop) \
if(w->geometry.prop != geometry.prop) \
{ \
w->geometry.prop = geometry.prop; \
luaA_object_emit_signal(L, udx, "property::" #prop, 0); \
}
DO_drawin_GEOMETRY_CHECK_AND_EMIT(x)
DO_drawin_GEOMETRY_CHECK_AND_EMIT(y)
DO_drawin_GEOMETRY_CHECK_AND_EMIT(width)
DO_drawin_GEOMETRY_CHECK_AND_EMIT(height)
#undef DO_drawin_GEOMETRY_CHECK_AND_EMIT
}
}
/** Refresh the window content by copying its pixmap data to its window.
* \param drawin The drawin 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
drawin_refresh_pixmap_partial(drawin_t *drawin,
int16_t x, int16_t y,
uint16_t w, uint16_t h)
{
xcb_copy_area(globalconf.connection, drawin->pixmap,
drawin->window, globalconf.gc, x, y, x, y,
w, h);
}
/** Set drawin orientation.
* \param L The Lua VM state.
* \param udx The drawin to change orientation.
* \param o The new orientation.
*/
static void
drawin_set_orientation(lua_State *L, int udx, orientation_t o)
{
drawin_t *w = luaA_checkudata(L, udx, &drawin_class);
if(o != w->orientation)
{
w->orientation = o;
/* orientation != East */
if(w->pixmap != w->ctx.pixmap)
xcb_free_pixmap(globalconf.connection, w->ctx.pixmap);
drawin_draw_context_update(w);
luaA_object_emit_signal(L, udx, "property::orientation", 0);
}
}
static void
drawin_map(drawin_t *drawin)
{
/* Activate BMA */
client_ignore_enterleave_events();
/* Map the drawin */
xcb_map_window(globalconf.connection, drawin->window);
/* Deactivate BMA */
client_restore_enterleave_events();
/* Stack this drawin correctly */
stack_windows();
}
/** Get a drawin by its window.
* \param win The window id.
* \return A drawin if found, NULL otherwise.
*/
drawin_t *
drawin_getbywin(xcb_window_t win)
{
foreach(w, globalconf.drawins)
if((*w)->window == win)
return *w;
return NULL;
}
/** Set a drawin visible or not.
* \param L The Lua VM state.
* \param udx The drawin.
* \param v The visible value.
*/
static void
drawin_set_visible(lua_State *L, int udx, bool v)
{
drawin_t *drawin = luaA_checkudata(L, udx, &drawin_class);
if(v != drawin->visible)
{
drawin->visible = v;
if(drawin->screen)
{
if(drawin->visible)
drawin_map(drawin);
else
{
/* Active BMA */
client_ignore_enterleave_events();
/* Unmap window */
xcb_unmap_window(globalconf.connection, drawin->window);
/* Active BMA */
client_restore_enterleave_events();
}
}
luaA_object_emit_signal(L, udx, "property::visible", 0);
}
}
/** Remove a drawin from a screen.
* \param L The Lua VM state.
* \param udx drawin to detach from screen.
*/
static void
drawin_detach(lua_State *L, int udx)
{
drawin_t *drawin = luaA_checkudata(L, udx, &drawin_class);
if(drawin->screen)
{
bool v;
/* save visible state */
v = drawin->visible;
drawin->visible = false;
/* restore visibility */
drawin->visible = v;
drawin_wipe_resources(drawin);
foreach(item, globalconf.drawins)
if(*item == drawin)
{
drawin_array_remove(&globalconf.drawins, item);
break;
}
if(strut_has_value(&drawin->strut))
screen_emit_signal(L, drawin->screen, "property::workarea", 0);
drawin->screen = NULL;
luaA_object_emit_signal(L, udx, "property::screen", 0);
luaA_object_unref(globalconf.L, drawin);
}
}
/** Attach a drawin that is on top of the stack.
* \param L The Lua VM state.
* \param udx The drawin to attach.
* \param s The screen to attach the drawin to.
*/
static void
drawin_attach(lua_State *L, int udx, screen_t *s)
{
/* duplicate drawin */
lua_pushvalue(L, udx);
/* ref it */
drawin_t *drawin = luaA_object_ref_class(globalconf.L, -1, &drawin_class);
drawin_detach(L, udx);
/* Set the drawin screen */
drawin->screen = s;
/* Check that the drawin coordinates matches the screen. */
screen_t *cscreen =
screen_getbycoord(drawin->geometry.x, drawin->geometry.y);
/* If it does not match, move it to the screen coordinates */
if(cscreen != drawin->screen)
drawin_moveresize(L, udx, (area_t) { .x = s->geometry.x,
.y = s->geometry.y,
.width = drawin->geometry.width,
.height = drawin->geometry.height });
drawin_array_append(&globalconf.drawins, drawin);
drawin_init(drawin);
xwindow_set_cursor(drawin->window,
xcursor_new(globalconf.connection, xcursor_font_fromstr(drawin->cursor)));
if(drawin->opacity != -1)
xwindow_set_opacity(drawin->window, drawin->opacity);
ewmh_update_strut(drawin->window, &drawin->strut);
if(drawin->visible)
drawin_map(drawin);
luaA_object_emit_signal(L, udx, "property::screen", 0);
if(strut_has_value(&drawin->strut))
screen_emit_signal(L, drawin->screen, "property::workarea", 0);
}
/** Create a new drawin.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_new(lua_State *L)
{
luaA_class_new(L, &drawin_class);
drawin_t *w = luaA_checkudata(L, -1, &drawin_class);
if(!w->ctx.fg.initialized)
w->ctx.fg = globalconf.colors.fg;
if(!w->ctx.bg.initialized)
w->ctx.bg = globalconf.colors.bg;
w->visible = true;
if(!w->opacity)
w->opacity = -1;
if(!w->cursor)
w->cursor = a_strdup("left_ptr");
if(!w->geometry.width)
w->geometry.width = 1;
if(!w->geometry.height)
w->geometry.height = 1;
if(w->type == 0)
w->type = _NET_WM_WINDOW_TYPE_NORMAL;
return 1;
}
/* Set or get the drawin geometry.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam An optional table with drawin geometry.
* \lreturn The drawin geometry.
*/
static int
luaA_drawin_geometry(lua_State *L)
{
drawin_t *drawin = luaA_checkudata(L, 1, &drawin_class);
if(lua_gettop(L) == 2)
{
area_t wingeom;
luaA_checktable(L, 2);
wingeom.x = luaA_getopt_number(L, 2, "x", drawin->geometry.x);
wingeom.y = luaA_getopt_number(L, 2, "y", drawin->geometry.y);
wingeom.width = luaA_getopt_number(L, 2, "width", drawin->geometry.width);
wingeom.height = luaA_getopt_number(L, 2, "height", drawin->geometry.height);
if(wingeom.width > 0 && wingeom.height > 0)
drawin_moveresize(L, 1, wingeom);
}
return luaA_pusharea(L, drawin->geometry);
}
LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, ontop, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, cursor, lua_pushstring)
LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, visible, lua_pushboolean)
static int
luaA_drawin_set_x(lua_State *L, drawin_t *drawin)
{
drawin_moveresize(L, -3, (area_t) { .x = luaL_checknumber(L, -1),
.y = drawin->geometry.y,
.width = drawin->geometry.width,
.height = drawin->geometry.height });
return 0;
}
static int
luaA_drawin_get_x(lua_State *L, drawin_t *drawin)
{
lua_pushnumber(L, drawin->geometry.x);
return 1;
}
static int
luaA_drawin_set_y(lua_State *L, drawin_t *drawin)
{
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = luaL_checknumber(L, -1),
.width = drawin->geometry.width,
.height = drawin->geometry.height });
return 0;
}
static int
luaA_drawin_get_y(lua_State *L, drawin_t *drawin)
{
lua_pushnumber(L, drawin->geometry.y);
return 1;
}
static int
luaA_drawin_set_width(lua_State *L, drawin_t *drawin)
{
int width = luaL_checknumber(L, -1);
if(width <= 0)
luaL_error(L, "invalid width");
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = drawin->geometry.y,
.width = width,
.height = drawin->geometry.height });
return 0;
}
static int
luaA_drawin_get_width(lua_State *L, drawin_t *drawin)
{
lua_pushnumber(L, drawin->geometry.width);
return 1;
}
static int
luaA_drawin_set_height(lua_State *L, drawin_t *drawin)
{
int height = luaL_checknumber(L, -1);
if(height <= 0)
luaL_error(L, "invalid height");
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = drawin->geometry.y,
.width = drawin->geometry.width,
.height = height });
return 0;
}
static int
luaA_drawin_get_height(lua_State *L, drawin_t *drawin)
{
lua_pushnumber(L, drawin->geometry.height);
return 1;
}
/** Set the drawin foreground color.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_fg(lua_State *L, drawin_t *drawin)
{
size_t len;
const char *buf = luaL_checklstring(L, -1, &len);
xcolor_init_reply(xcolor_init_unchecked(&drawin->ctx.fg, buf, len));
luaA_object_emit_signal(L, -3, "property::fg", 0);
return 0;
}
/** Get the drawin foreground color.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_get_fg(lua_State *L, drawin_t *drawin)
{
return luaA_pushxcolor(L, drawin->ctx.fg);
}
/** Set the drawin background color.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_bg(lua_State *L, drawin_t *drawin)
{
size_t len;
const char *buf = luaL_checklstring(L, -1, &len);
if(xcolor_init_reply(xcolor_init_unchecked(&drawin->ctx.bg, buf, len)))
{
uint32_t mask = XCB_CW_BACK_PIXEL;
uint32_t values[] = { drawin->ctx.bg.pixel };
if (drawin->window != XCB_NONE)
xcb_change_window_attributes(globalconf.connection,
drawin->window,
mask,
values);
}
luaA_object_emit_signal(L, -3, "property::bg", 0);
return 0;
}
/** Get the drawin background color.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_get_bg(lua_State *L, drawin_t *drawin)
{
return luaA_pushxcolor(L, drawin->ctx.bg);
}
/** Set the drawin background image.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_bg_image(lua_State *L, drawin_t *drawin)
{
if(lua_isnil(L, -1))
{
if(drawin->bg_image)
cairo_surface_destroy(drawin->bg_image);
drawin->bg_image = NULL;
} else {
cairo_surface_t **cairo_surface = (cairo_surface_t **)luaL_checkudata(L, -1, OOCAIRO_MT_NAME_SURFACE);
if(drawin->bg_image)
cairo_surface_destroy(drawin->bg_image);
drawin->bg_image = draw_dup_image_surface(*cairo_surface);
}
luaA_object_emit_signal(L, -3, "property::bg_image", 0);
return 0;
}
/** Get the drawin background image.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_get_bg_image(lua_State *L, drawin_t *drawin)
{
if(drawin->bg_image)
return oocairo_surface_push(L, drawin->bg_image);
return 0;
}
/** Set the drawin on top status.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_ontop(lua_State *L, drawin_t *drawin)
{
bool b = luaA_checkboolean(L, -1);
if(b != drawin->ontop)
{
drawin->ontop = b;
stack_windows();
luaA_object_emit_signal(L, -3, "property::ontop", 0);
}
return 0;
}
/** Set the drawin cursor.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_cursor(lua_State *L, drawin_t *drawin)
{
const char *buf = luaL_checkstring(L, -1);
if(buf)
{
uint16_t cursor_font = xcursor_font_fromstr(buf);
if(cursor_font)
{
xcb_cursor_t cursor = xcursor_new(globalconf.connection, cursor_font);
p_delete(&drawin->cursor);
drawin->cursor = a_strdup(buf);
xwindow_set_cursor(drawin->window, cursor);
luaA_object_emit_signal(L, -3, "property::cursor", 0);
}
}
return 0;
}
/** Set the drawin screen.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_screen(lua_State *L, drawin_t *drawin)
{
if(lua_isnil(L, -1))
drawin_detach(L, -3);
else
{
int screen = luaL_checknumber(L, -1) - 1;
luaA_checkscreen(screen);
if(!drawin->screen || screen != screen_array_indexof(&globalconf.screens, drawin->screen))
drawin_attach(L, -3, &globalconf.screens.tab[screen]);
}
return 0;
}
/** Get the drawin screen.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_get_screen(lua_State *L, drawin_t *drawin)
{
if(!drawin->screen)
return 0;
lua_pushnumber(L, screen_array_indexof(&globalconf.screens, drawin->screen) + 1);
return 1;
}
/** Set the drawin orientation.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_orientation(lua_State *L, drawin_t *drawin)
{
const char *buf = luaL_checkstring(L, -1);
if(buf)
{
drawin_set_orientation(L, -3, orientation_fromstr(buf));
}
return 0;
}
/** Get the drawin orientation.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_get_orientation(lua_State *L, drawin_t *drawin)
{
lua_pushstring(L, orientation_tostr(drawin->orientation));
return 1;
}
/** Set the drawin visibility.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_visible(lua_State *L, drawin_t *drawin)
{
drawin_set_visible(L, -3, luaA_checkboolean(L, -1));
return 0;
}
void
drawin_class_setup(lua_State *L)
{
static const struct luaL_reg drawin_methods[] =
{
LUA_CLASS_METHODS(drawin)
{ "__call", luaA_drawin_new },
{ NULL, NULL }
};
static const struct luaL_reg drawin_meta[] =
{
LUA_OBJECT_META(drawin)
LUA_CLASS_META
{ "geometry", luaA_drawin_geometry },
{ NULL, NULL },
};
luaA_class_setup(L, &drawin_class, "drawin", &window_class,
(lua_class_allocator_t) drawin_new,
(lua_class_collector_t) drawin_wipe,
NULL,
luaA_class_index_miss_property, luaA_class_newindex_miss_property,
drawin_methods, drawin_meta);
luaA_class_add_property(&drawin_class, "visible",
(lua_class_propfunc_t) luaA_drawin_set_visible,
(lua_class_propfunc_t) luaA_drawin_get_visible,
(lua_class_propfunc_t) luaA_drawin_set_visible);
luaA_class_add_property(&drawin_class, "orientation",
(lua_class_propfunc_t) luaA_drawin_set_orientation,
(lua_class_propfunc_t) luaA_drawin_get_orientation,
(lua_class_propfunc_t) luaA_drawin_set_orientation);
luaA_class_add_property(&drawin_class, "ontop",
(lua_class_propfunc_t) luaA_drawin_set_ontop,
(lua_class_propfunc_t) luaA_drawin_get_ontop,
(lua_class_propfunc_t) luaA_drawin_set_ontop);
luaA_class_add_property(&drawin_class, "screen",
NULL,
(lua_class_propfunc_t) luaA_drawin_get_screen,
(lua_class_propfunc_t) luaA_drawin_set_screen);
luaA_class_add_property(&drawin_class, "cursor",
(lua_class_propfunc_t) luaA_drawin_set_cursor,
(lua_class_propfunc_t) luaA_drawin_get_cursor,
(lua_class_propfunc_t) luaA_drawin_set_cursor);
luaA_class_add_property(&drawin_class, "fg",
(lua_class_propfunc_t) luaA_drawin_set_fg,
(lua_class_propfunc_t) luaA_drawin_get_fg,
(lua_class_propfunc_t) luaA_drawin_set_fg);
luaA_class_add_property(&drawin_class, "bg",
(lua_class_propfunc_t) luaA_drawin_set_bg,
(lua_class_propfunc_t) luaA_drawin_get_bg,
(lua_class_propfunc_t) luaA_drawin_set_bg);
luaA_class_add_property(&drawin_class, "bg_image",
(lua_class_propfunc_t) luaA_drawin_set_bg_image,
(lua_class_propfunc_t) luaA_drawin_get_bg_image,
(lua_class_propfunc_t) luaA_drawin_set_bg_image);
luaA_class_add_property(&drawin_class, "x",
(lua_class_propfunc_t) luaA_drawin_set_x,
(lua_class_propfunc_t) luaA_drawin_get_x,
(lua_class_propfunc_t) luaA_drawin_set_x);
luaA_class_add_property(&drawin_class, "y",
(lua_class_propfunc_t) luaA_drawin_set_y,
(lua_class_propfunc_t) luaA_drawin_get_y,
(lua_class_propfunc_t) luaA_drawin_set_y);
luaA_class_add_property(&drawin_class, "width",
(lua_class_propfunc_t) luaA_drawin_set_width,
(lua_class_propfunc_t) luaA_drawin_get_width,
(lua_class_propfunc_t) luaA_drawin_set_width);
luaA_class_add_property(&drawin_class, "height",
(lua_class_propfunc_t) luaA_drawin_set_height,
(lua_class_propfunc_t) luaA_drawin_get_height,
(lua_class_propfunc_t) luaA_drawin_set_height);
luaA_class_add_property(&drawin_class, "type",
(lua_class_propfunc_t) luaA_window_set_type,
(lua_class_propfunc_t) luaA_window_get_type,
(lua_class_propfunc_t) luaA_window_set_type);
signal_add(&drawin_class.signals, "mouse::enter");
signal_add(&drawin_class.signals, "mouse::leave");
signal_add(&drawin_class.signals, "property::bg");
signal_add(&drawin_class.signals, "property::bg_image");
signal_add(&drawin_class.signals, "property::border_width");
signal_add(&drawin_class.signals, "property::cursor");
signal_add(&drawin_class.signals, "property::fg");
signal_add(&drawin_class.signals, "property::height");
signal_add(&drawin_class.signals, "property::ontop");
signal_add(&drawin_class.signals, "property::orientation");
signal_add(&drawin_class.signals, "property::screen");
signal_add(&drawin_class.signals, "property::visible");
signal_add(&drawin_class.signals, "property::widgets");
signal_add(&drawin_class.signals, "property::width");
signal_add(&drawin_class.signals, "property::x");
signal_add(&drawin_class.signals, "property::y");
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -1,7 +1,8 @@
/*
* wibox.h - wibox functions header
* drawin.h - drawin functions header
*
* Copyright © 2007-2009 Julien Danjou <julien@danjou.info>
* Copyright © 2010 Uli Schlachter <psychon@znc.in>
*
* 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,15 +20,15 @@
*
*/
#ifndef AWESOME_OBJECTS_WIBOX_H
#define AWESOME_OBJECTS_WIBOX_H
#ifndef AWESOME_OBJECTS_DRAWIN_H
#define AWESOME_OBJECTS_DRAWIN_H
#include "objects/window.h"
#include "common/luaobject.h"
#include "draw.h"
/** Wibox type */
struct wibox_t
/** Drawin type */
struct drawin_t
{
WINDOW_OBJECT_HEADER
/** Ontop */
@ -48,17 +49,17 @@ struct wibox_t
orientation_t orientation;
};
void wibox_unref_simplified(wibox_t **);
void drawin_unref_simplified(drawin_t **);
ARRAY_FUNCS(wibox_t *, wibox, wibox_unref_simplified)
ARRAY_FUNCS(drawin_t *, drawin, drawin_unref_simplified)
wibox_t * wibox_getbywin(xcb_window_t);
drawin_t * drawin_getbywin(xcb_window_t);
void wibox_refresh_pixmap_partial(wibox_t *, int16_t, int16_t, uint16_t, uint16_t);
void drawin_refresh_pixmap_partial(drawin_t *, int16_t, int16_t, uint16_t, uint16_t);
void wibox_class_setup(lua_State *);
void drawin_class_setup(lua_State *);
lua_class_t wibox_class;
lua_class_t drawin_class;
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -1,902 +0,0 @@
/*
* wibox.c - wibox functions
*
* 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
* 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 "screen.h"
#include "wibox.h"
#include "objects/client.h"
#include "screen.h"
#include "xwindow.h"
#include "luaa.h"
#include "ewmh.h"
#include "common/xcursor.h"
#include "common/xutil.h"
LUA_OBJECT_FUNCS(wibox_class, wibox_t, wibox)
/** Kick out systray windows.
*/
static void
wibox_systray_kickout(void)
{
xcb_screen_t *s = globalconf.screen;
if(globalconf.systray.parent != s->root)
{
/* Who! Check that we're not deleting a wibox with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
xcb_reparent_window(globalconf.connection,
globalconf.systray.window,
s->root, -512, -512);
globalconf.systray.parent = s->root;
}
}
/** Destroy all X resources of a wibox.
* \param w The wibox to wipe.
*/
static void
wibox_wipe_resources(wibox_t *w)
{
if(w->window)
{
/* Activate BMA */
client_ignore_enterleave_events();
/* Make sure we don't accidentally kill the systray window */
if(globalconf.systray.parent == w->window)
wibox_systray_kickout();
xcb_destroy_window(globalconf.connection, w->window);
/* Deactivate BMA */
client_restore_enterleave_events();
w->window = XCB_NONE;
}
if(w->pixmap)
{
xcb_free_pixmap(globalconf.connection, w->pixmap);
w->pixmap = XCB_NONE;
}
draw_context_wipe(&w->ctx);
}
static void
wibox_wipe(wibox_t *wibox)
{
p_delete(&wibox->cursor);
wibox_wipe_resources(wibox);
if(wibox->bg_image)
cairo_surface_destroy(wibox->bg_image);
}
void
wibox_unref_simplified(wibox_t **item)
{
luaA_object_unref(globalconf.L, *item);
}
static void
wibox_draw_context_update(wibox_t *w)
{
xcb_screen_t *s = globalconf.screen;
xcolor_t fg = w->ctx.fg, bg = w->ctx.bg;
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,
globalconf.default_depth,
w->ctx.pixmap, s->root,
w->geometry.height,
w->geometry.width);
draw_context_init(&w->ctx,
w->geometry.height,
w->geometry.width,
w->ctx.pixmap, &fg, &bg);
break;
case East:
draw_context_init(&w->ctx,
w->geometry.width,
w->geometry.height,
w->pixmap, &fg, &bg);
break;
}
}
/** Initialize a wibox.
* \param w The wibox to initialize.
*/
static void
wibox_init(wibox_t *w)
{
xcb_screen_t *s = globalconf.screen;
w->window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth, w->window, s->root,
w->geometry.x, w->geometry.y,
w->geometry.width, w->geometry.height,
w->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
(const uint32_t [])
{
w->ctx.bg.pixel,
w->border_color.pixel,
XCB_GRAVITY_NORTH_WEST,
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_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_PROPERTY_CHANGE,
globalconf.default_cmap
});
/* Create a pixmap. */
w->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root,
w->geometry.width, w->geometry.height);
/* Update draw context physical screen, important for Zaphod. */
wibox_draw_context_update(w);
/* Set the right type property */
ewmh_update_window_type(w->window, window_translate_type(w->type));
}
/** 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);
}
/** Move and/or resize a wibox
* \param L The Lua VM state.
* \param udx The index of the wibox.
* \param geometry The new geometry.
*/
static void
wibox_moveresize(lua_State *L, int udx, area_t geometry)
{
wibox_t *w = luaA_checkudata(L, udx, &wibox_class);
if(w->window)
{
int number_of_vals = 0;
uint32_t moveresize_win_vals[4], mask_vals = 0;
if(w->geometry.x != geometry.x)
{
w->geometry.x = moveresize_win_vals[number_of_vals++] = geometry.x;
mask_vals |= XCB_CONFIG_WINDOW_X;
}
if(w->geometry.y != geometry.y)
{
w->geometry.y = moveresize_win_vals[number_of_vals++] = geometry.y;
mask_vals |= XCB_CONFIG_WINDOW_Y;
}
if(geometry.width > 0 && w->geometry.width != geometry.width)
{
w->geometry.width = moveresize_win_vals[number_of_vals++] = geometry.width;
mask_vals |= XCB_CONFIG_WINDOW_WIDTH;
}
if(geometry.height > 0 && w->geometry.height != geometry.height)
{
w->geometry.height = moveresize_win_vals[number_of_vals++] = geometry.height;
mask_vals |= XCB_CONFIG_WINDOW_HEIGHT;
}
if(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_screen_t *s = globalconf.screen;
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root,
w->geometry.width, w->geometry.height);
wibox_draw_context_update(w);
}
/* Activate BMA */
client_ignore_enterleave_events();
if(mask_vals)
xcb_configure_window(globalconf.connection, w->window, mask_vals, moveresize_win_vals);
/* Deactivate BMA */
client_restore_enterleave_events();
w->screen = screen_getbycoord(w->geometry.x, w->geometry.y);
if(mask_vals & XCB_CONFIG_WINDOW_X)
luaA_object_emit_signal(L, udx, "property::x", 0);
if(mask_vals & XCB_CONFIG_WINDOW_Y)
luaA_object_emit_signal(L, udx, "property::y", 0);
if(mask_vals & XCB_CONFIG_WINDOW_WIDTH)
luaA_object_emit_signal(L, udx, "property::width", 0);
if(mask_vals & XCB_CONFIG_WINDOW_HEIGHT)
luaA_object_emit_signal(L, udx, "property::height", 0);
}
else
{
#define DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(prop) \
if(w->geometry.prop != geometry.prop) \
{ \
w->geometry.prop = geometry.prop; \
luaA_object_emit_signal(L, udx, "property::" #prop, 0); \
}
DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(x)
DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(y)
DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(width)
DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(height)
#undef DO_WIBOX_GEOMETRY_CHECK_AND_EMIT
}
}
/** 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, globalconf.gc, x, y, x, y,
w, h);
}
/** Set wibox orientation.
* \param L The Lua VM state.
* \param udx The wibox to change orientation.
* \param o The new orientation.
*/
static void
wibox_set_orientation(lua_State *L, int udx, orientation_t o)
{
wibox_t *w = luaA_checkudata(L, udx, &wibox_class);
if(o != w->orientation)
{
w->orientation = o;
/* orientation != East */
if(w->pixmap != w->ctx.pixmap)
xcb_free_pixmap(globalconf.connection, w->ctx.pixmap);
wibox_draw_context_update(w);
luaA_object_emit_signal(L, udx, "property::orientation", 0);
}
}
static void
wibox_map(wibox_t *wibox)
{
/* Activate BMA */
client_ignore_enterleave_events();
/* Map the wibox */
xcb_map_window(globalconf.connection, wibox->window);
/* Deactivate BMA */
client_restore_enterleave_events();
/* Stack this wibox correctly */
stack_windows();
}
/** Get a wibox by its window.
* \param win The window id.
* \return A wibox if found, NULL otherwise.
*/
wibox_t *
wibox_getbywin(xcb_window_t win)
{
foreach(w, globalconf.wiboxes)
if((*w)->window == win)
return *w;
return NULL;
}
/** Set a wibox visible or not.
* \param L The Lua VM state.
* \param udx The wibox.
* \param v The visible value.
*/
static void
wibox_set_visible(lua_State *L, int udx, bool v)
{
wibox_t *wibox = luaA_checkudata(L, udx, &wibox_class);
if(v != wibox->visible)
{
wibox->visible = v;
if(wibox->screen)
{
if(wibox->visible)
wibox_map(wibox);
else
{
/* Active BMA */
client_ignore_enterleave_events();
/* Unmap window */
xcb_unmap_window(globalconf.connection, wibox->window);
/* Active BMA */
client_restore_enterleave_events();
}
}
luaA_object_emit_signal(L, udx, "property::visible", 0);
}
}
/** Remove a wibox from a screen.
* \param L The Lua VM state.
* \param udx Wibox to detach from screen.
*/
static void
wibox_detach(lua_State *L, int udx)
{
wibox_t *wibox = luaA_checkudata(L, udx, &wibox_class);
if(wibox->screen)
{
bool v;
/* save visible state */
v = wibox->visible;
wibox->visible = false;
/* restore visibility */
wibox->visible = v;
wibox_wipe_resources(wibox);
foreach(item, globalconf.wiboxes)
if(*item == wibox)
{
wibox_array_remove(&globalconf.wiboxes, item);
break;
}
if(strut_has_value(&wibox->strut))
screen_emit_signal(L, wibox->screen, "property::workarea", 0);
wibox->screen = NULL;
luaA_object_emit_signal(L, udx, "property::screen", 0);
luaA_object_unref(globalconf.L, wibox);
}
}
/** Attach a wibox that is on top of the stack.
* \param L The Lua VM state.
* \param udx The wibox to attach.
* \param s The screen to attach the wibox to.
*/
static void
wibox_attach(lua_State *L, int udx, screen_t *s)
{
/* duplicate wibox */
lua_pushvalue(L, udx);
/* ref it */
wibox_t *wibox = luaA_object_ref_class(globalconf.L, -1, &wibox_class);
wibox_detach(L, udx);
/* Set the wibox screen */
wibox->screen = s;
/* Check that the wibox coordinates matches the screen. */
screen_t *cscreen =
screen_getbycoord(wibox->geometry.x, wibox->geometry.y);
/* If it does not match, move it to the screen coordinates */
if(cscreen != wibox->screen)
wibox_moveresize(L, udx, (area_t) { .x = s->geometry.x,
.y = s->geometry.y,
.width = wibox->geometry.width,
.height = wibox->geometry.height });
wibox_array_append(&globalconf.wiboxes, wibox);
wibox_init(wibox);
xwindow_set_cursor(wibox->window,
xcursor_new(globalconf.connection, xcursor_font_fromstr(wibox->cursor)));
if(wibox->opacity != -1)
xwindow_set_opacity(wibox->window, wibox->opacity);
ewmh_update_strut(wibox->window, &wibox->strut);
if(wibox->visible)
wibox_map(wibox);
luaA_object_emit_signal(L, udx, "property::screen", 0);
if(strut_has_value(&wibox->strut))
screen_emit_signal(L, wibox->screen, "property::workarea", 0);
}
/** Create a new wibox.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_new(lua_State *L)
{
luaA_class_new(L, &wibox_class);
wibox_t *w = luaA_checkudata(L, -1, &wibox_class);
if(!w->ctx.fg.initialized)
w->ctx.fg = globalconf.colors.fg;
if(!w->ctx.bg.initialized)
w->ctx.bg = globalconf.colors.bg;
w->visible = true;
if(!w->opacity)
w->opacity = -1;
if(!w->cursor)
w->cursor = a_strdup("left_ptr");
if(!w->geometry.width)
w->geometry.width = 1;
if(!w->geometry.height)
w->geometry.height = 1;
if(w->type == 0)
w->type = _NET_WM_WINDOW_TYPE_NORMAL;
return 1;
}
/* Set or get the wibox geometry.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam An optional table with wibox geometry.
* \lreturn The wibox geometry.
*/
static int
luaA_wibox_geometry(lua_State *L)
{
wibox_t *wibox = luaA_checkudata(L, 1, &wibox_class);
if(lua_gettop(L) == 2)
{
area_t wingeom;
luaA_checktable(L, 2);
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);
if(wingeom.width > 0 && wingeom.height > 0)
wibox_moveresize(L, 1, wingeom);
}
return luaA_pusharea(L, wibox->geometry);
}
LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, ontop, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, cursor, lua_pushstring)
LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, visible, lua_pushboolean)
static int
luaA_wibox_set_x(lua_State *L, wibox_t *wibox)
{
wibox_moveresize(L, -3, (area_t) { .x = luaL_checknumber(L, -1),
.y = wibox->geometry.y,
.width = wibox->geometry.width,
.height = wibox->geometry.height });
return 0;
}
static int
luaA_wibox_get_x(lua_State *L, wibox_t *wibox)
{
lua_pushnumber(L, wibox->geometry.x);
return 1;
}
static int
luaA_wibox_set_y(lua_State *L, wibox_t *wibox)
{
wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x,
.y = luaL_checknumber(L, -1),
.width = wibox->geometry.width,
.height = wibox->geometry.height });
return 0;
}
static int
luaA_wibox_get_y(lua_State *L, wibox_t *wibox)
{
lua_pushnumber(L, wibox->geometry.y);
return 1;
}
static int
luaA_wibox_set_width(lua_State *L, wibox_t *wibox)
{
int width = luaL_checknumber(L, -1);
if(width <= 0)
luaL_error(L, "invalid width");
wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x,
.y = wibox->geometry.y,
.width = width,
.height = wibox->geometry.height });
return 0;
}
static int
luaA_wibox_get_width(lua_State *L, wibox_t *wibox)
{
lua_pushnumber(L, wibox->geometry.width);
return 1;
}
static int
luaA_wibox_set_height(lua_State *L, wibox_t *wibox)
{
int height = luaL_checknumber(L, -1);
if(height <= 0)
luaL_error(L, "invalid height");
wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x,
.y = wibox->geometry.y,
.width = wibox->geometry.width,
.height = height });
return 0;
}
static int
luaA_wibox_get_height(lua_State *L, wibox_t *wibox)
{
lua_pushnumber(L, wibox->geometry.height);
return 1;
}
/** Set the wibox foreground color.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_fg(lua_State *L, wibox_t *wibox)
{
size_t len;
const char *buf = luaL_checklstring(L, -1, &len);
xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.fg, buf, len));
luaA_object_emit_signal(L, -3, "property::fg", 0);
return 0;
}
/** Get the wibox foreground color.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_get_fg(lua_State *L, wibox_t *wibox)
{
return luaA_pushxcolor(L, wibox->ctx.fg);
}
/** Set the wibox background color.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_bg(lua_State *L, wibox_t *wibox)
{
size_t len;
const char *buf = luaL_checklstring(L, -1, &len);
if(xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.bg, buf, len)))
{
uint32_t mask = XCB_CW_BACK_PIXEL;
uint32_t values[] = { wibox->ctx.bg.pixel };
if (wibox->window != XCB_NONE)
xcb_change_window_attributes(globalconf.connection,
wibox->window,
mask,
values);
}
luaA_object_emit_signal(L, -3, "property::bg", 0);
return 0;
}
/** Get the wibox background color.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_get_bg(lua_State *L, wibox_t *wibox)
{
return luaA_pushxcolor(L, wibox->ctx.bg);
}
/** Set the wibox background image.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_bg_image(lua_State *L, wibox_t *wibox)
{
if(lua_isnil(L, -1))
{
if(wibox->bg_image)
cairo_surface_destroy(wibox->bg_image);
wibox->bg_image = NULL;
} else {
cairo_surface_t **cairo_surface = (cairo_surface_t **)luaL_checkudata(L, -1, OOCAIRO_MT_NAME_SURFACE);
if(wibox->bg_image)
cairo_surface_destroy(wibox->bg_image);
wibox->bg_image = draw_dup_image_surface(*cairo_surface);
}
luaA_object_emit_signal(L, -3, "property::bg_image", 0);
return 0;
}
/** Get the wibox background image.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_get_bg_image(lua_State *L, wibox_t *wibox)
{
if(wibox->bg_image)
return oocairo_surface_push(L, wibox->bg_image);
return 0;
}
/** Set the wibox on top status.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_ontop(lua_State *L, wibox_t *wibox)
{
bool b = luaA_checkboolean(L, -1);
if(b != wibox->ontop)
{
wibox->ontop = b;
stack_windows();
luaA_object_emit_signal(L, -3, "property::ontop", 0);
}
return 0;
}
/** Set the wibox cursor.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_cursor(lua_State *L, wibox_t *wibox)
{
const char *buf = luaL_checkstring(L, -1);
if(buf)
{
uint16_t cursor_font = xcursor_font_fromstr(buf);
if(cursor_font)
{
xcb_cursor_t cursor = xcursor_new(globalconf.connection, cursor_font);
p_delete(&wibox->cursor);
wibox->cursor = a_strdup(buf);
xwindow_set_cursor(wibox->window, cursor);
luaA_object_emit_signal(L, -3, "property::cursor", 0);
}
}
return 0;
}
/** Set the wibox screen.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_screen(lua_State *L, wibox_t *wibox)
{
if(lua_isnil(L, -1))
wibox_detach(L, -3);
else
{
int screen = luaL_checknumber(L, -1) - 1;
luaA_checkscreen(screen);
if(!wibox->screen || screen != screen_array_indexof(&globalconf.screens, wibox->screen))
wibox_attach(L, -3, &globalconf.screens.tab[screen]);
}
return 0;
}
/** Get the wibox screen.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_get_screen(lua_State *L, wibox_t *wibox)
{
if(!wibox->screen)
return 0;
lua_pushnumber(L, screen_array_indexof(&globalconf.screens, wibox->screen) + 1);
return 1;
}
/** Set the wibox orientation.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_orientation(lua_State *L, wibox_t *wibox)
{
const char *buf = luaL_checkstring(L, -1);
if(buf)
{
wibox_set_orientation(L, -3, orientation_fromstr(buf));
}
return 0;
}
/** Get the wibox orientation.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_get_orientation(lua_State *L, wibox_t *wibox)
{
lua_pushstring(L, orientation_tostr(wibox->orientation));
return 1;
}
/** Set the wibox visibility.
* \param L The Lua VM state.
* \param wibox The wibox object.
* \return The number of elements pushed on stack.
*/
static int
luaA_wibox_set_visible(lua_State *L, wibox_t *wibox)
{
wibox_set_visible(L, -3, luaA_checkboolean(L, -1));
return 0;
}
void
wibox_class_setup(lua_State *L)
{
static const struct luaL_reg wibox_methods[] =
{
LUA_CLASS_METHODS(wibox)
{ "__call", luaA_wibox_new },
{ NULL, NULL }
};
static const struct luaL_reg wibox_meta[] =
{
LUA_OBJECT_META(wibox)
LUA_CLASS_META
{ "geometry", luaA_wibox_geometry },
{ NULL, NULL },
};
luaA_class_setup(L, &wibox_class, "wibox", &window_class,
(lua_class_allocator_t) wibox_new,
(lua_class_collector_t) wibox_wipe,
NULL,
luaA_class_index_miss_property, luaA_class_newindex_miss_property,
wibox_methods, wibox_meta);
luaA_class_add_property(&wibox_class, "visible",
(lua_class_propfunc_t) luaA_wibox_set_visible,
(lua_class_propfunc_t) luaA_wibox_get_visible,
(lua_class_propfunc_t) luaA_wibox_set_visible);
luaA_class_add_property(&wibox_class, "orientation",
(lua_class_propfunc_t) luaA_wibox_set_orientation,
(lua_class_propfunc_t) luaA_wibox_get_orientation,
(lua_class_propfunc_t) luaA_wibox_set_orientation);
luaA_class_add_property(&wibox_class, "ontop",
(lua_class_propfunc_t) luaA_wibox_set_ontop,
(lua_class_propfunc_t) luaA_wibox_get_ontop,
(lua_class_propfunc_t) luaA_wibox_set_ontop);
luaA_class_add_property(&wibox_class, "screen",
NULL,
(lua_class_propfunc_t) luaA_wibox_get_screen,
(lua_class_propfunc_t) luaA_wibox_set_screen);
luaA_class_add_property(&wibox_class, "cursor",
(lua_class_propfunc_t) luaA_wibox_set_cursor,
(lua_class_propfunc_t) luaA_wibox_get_cursor,
(lua_class_propfunc_t) luaA_wibox_set_cursor);
luaA_class_add_property(&wibox_class, "fg",
(lua_class_propfunc_t) luaA_wibox_set_fg,
(lua_class_propfunc_t) luaA_wibox_get_fg,
(lua_class_propfunc_t) luaA_wibox_set_fg);
luaA_class_add_property(&wibox_class, "bg",
(lua_class_propfunc_t) luaA_wibox_set_bg,
(lua_class_propfunc_t) luaA_wibox_get_bg,
(lua_class_propfunc_t) luaA_wibox_set_bg);
luaA_class_add_property(&wibox_class, "bg_image",
(lua_class_propfunc_t) luaA_wibox_set_bg_image,
(lua_class_propfunc_t) luaA_wibox_get_bg_image,
(lua_class_propfunc_t) luaA_wibox_set_bg_image);
luaA_class_add_property(&wibox_class, "x",
(lua_class_propfunc_t) luaA_wibox_set_x,
(lua_class_propfunc_t) luaA_wibox_get_x,
(lua_class_propfunc_t) luaA_wibox_set_x);
luaA_class_add_property(&wibox_class, "y",
(lua_class_propfunc_t) luaA_wibox_set_y,
(lua_class_propfunc_t) luaA_wibox_get_y,
(lua_class_propfunc_t) luaA_wibox_set_y);
luaA_class_add_property(&wibox_class, "width",
(lua_class_propfunc_t) luaA_wibox_set_width,
(lua_class_propfunc_t) luaA_wibox_get_width,
(lua_class_propfunc_t) luaA_wibox_set_width);
luaA_class_add_property(&wibox_class, "height",
(lua_class_propfunc_t) luaA_wibox_set_height,
(lua_class_propfunc_t) luaA_wibox_get_height,
(lua_class_propfunc_t) luaA_wibox_set_height);
luaA_class_add_property(&wibox_class, "type",
(lua_class_propfunc_t) luaA_window_set_type,
(lua_class_propfunc_t) luaA_window_get_type,
(lua_class_propfunc_t) luaA_window_set_type);
signal_add(&wibox_class.signals, "mouse::enter");
signal_add(&wibox_class.signals, "mouse::leave");
signal_add(&wibox_class.signals, "property::bg");
signal_add(&wibox_class.signals, "property::bg_image");
signal_add(&wibox_class.signals, "property::border_width");
signal_add(&wibox_class.signals, "property::cursor");
signal_add(&wibox_class.signals, "property::fg");
signal_add(&wibox_class.signals, "property::height");
signal_add(&wibox_class.signals, "property::ontop");
signal_add(&wibox_class.signals, "property::orientation");
signal_add(&wibox_class.signals, "property::screen");
signal_add(&wibox_class.signals, "property::visible");
signal_add(&wibox_class.signals, "property::widgets");
signal_add(&wibox_class.signals, "property::width");
signal_add(&wibox_class.signals, "property::x");
signal_add(&wibox_class.signals, "property::y");
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -25,7 +25,7 @@
#include "property.h"
#include "objects/client.h"
#include "ewmh.h"
#include "objects/wibox.h"
#include "objects/drawin.h"
#include "xwindow.h"
#include "luaa.h"
#include "common/atoms.h"
@ -334,7 +334,7 @@ property_handle_xrootpmap_id(uint8_t state,
{
#warning
#if 0
foreach(w, globalconf.wiboxes)
foreach(w, globalconf.drawins)
(*w)->need_update = true;
#endif
@ -345,12 +345,12 @@ static int
property_handle_net_wm_opacity(uint8_t state,
xcb_window_t window)
{
wibox_t *wibox = wibox_getbywin(window);
drawin_t *drawin = drawin_getbywin(window);
if(wibox)
if(drawin)
{
luaA_object_push(globalconf.L, wibox);
window_set_opacity(globalconf.L, -1, xwindow_get_opacity(wibox->window));
luaA_object_push(globalconf.L, drawin);
window_set_opacity(globalconf.L, -1, xwindow_get_opacity(drawin->window));
lua_pop(globalconf.L, -1);
}
else

16
root.c
View File

@ -23,7 +23,7 @@
#include "globalconf.h"
#include "objects/button.h"
#include "objects/wibox.h"
#include "objects/drawin.h"
#include "luaa.h"
#include "xwindow.h"
#include "common/xcursor.h"
@ -202,20 +202,20 @@ luaA_root_cursor(lua_State *L)
return 0;
}
/** Get the wiboxes attached to a screen.
/** Get the drawins attached to a screen.
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lreturn A table with all wiboxes.
* \lreturn A table with all drawins.
*/
static int
luaA_root_wiboxes(lua_State *L)
luaA_root_drawins(lua_State *L)
{
lua_createtable(L, globalconf.wiboxes.len, 0);
lua_createtable(L, globalconf.drawins.len, 0);
for(int i = 0; i < globalconf.wiboxes.len; i++)
for(int i = 0; i < globalconf.drawins.len; i++)
{
luaA_object_push(L, globalconf.wiboxes.tab[i]);
luaA_object_push(L, globalconf.drawins.tab[i]);
lua_rawseti(L, -2, i + 1);
}
@ -228,7 +228,7 @@ const struct luaL_reg awesome_root_lib[] =
{ "keys", luaA_root_keys },
{ "cursor", luaA_root_cursor },
{ "fake_input", luaA_root_fake_input },
{ "wiboxes", luaA_root_wiboxes },
{ "drawins", luaA_root_drawins },
{ NULL, NULL }
};

View File

@ -29,7 +29,7 @@
#include "ewmh.h"
#include "objects/tag.h"
#include "objects/client.h"
#include "objects/wibox.h"
#include "objects/drawin.h"
#include "luaa.h"
#include "common/xutil.h"
@ -298,10 +298,10 @@ screen_area_get(screen_t *screen, bool strut)
if(client_isvisible(*c, screen))
COMPUTE_STRUT(*c)
foreach(wibox, globalconf.wiboxes)
if((*wibox)->visible
&& (*wibox)->screen == screen)
COMPUTE_STRUT(*wibox)
foreach(drawin, globalconf.drawins)
if((*drawin)->visible
&& (*drawin)->screen == screen)
COMPUTE_STRUT(*drawin)
#undef COMPUTE_STRUT

22
stack.c
View File

@ -23,7 +23,7 @@
#include "screen.h"
#include "stack.h"
#include "objects/client.h"
#include "objects/wibox.h"
#include "objects/drawin.h"
void
stack_client_remove(client_t *c)
@ -174,12 +174,12 @@ stack_refresh()
if(client_layer_translator(*node) == layer)
next = stack_client_above(*node, next);
/* first stack not ontop wibox window */
foreach(wibox, globalconf.wiboxes)
if(!(*wibox)->ontop)
/* first stack not ontop drawin window */
foreach(drawin, globalconf.drawins)
if(!(*drawin)->ontop)
{
stack_window_above((*wibox)->window, next);
next = (*wibox)->window;
stack_window_above((*drawin)->window, next);
next = (*drawin)->window;
}
/* then stack clients */
@ -188,12 +188,12 @@ stack_refresh()
if(client_layer_translator(*node) == layer)
next = stack_client_above(*node, next);
/* then stack ontop wibox window */
foreach(wibox, globalconf.wiboxes)
if((*wibox)->ontop)
/* then stack ontop drawin window */
foreach(drawin, globalconf.drawins)
if((*drawin)->ontop)
{
stack_window_above((*wibox)->window, next);
next = (*wibox)->window;
stack_window_above((*drawin)->window, next);
next = (*drawin)->window;
}
need_stack_refresh = false;

View File

@ -26,7 +26,6 @@
#include "screen.h"
#include "systray.h"
#include "xwindow.h"
#include "objects/wibox.h"
#include "common/array.h"
#include "common/atoms.h"
#include "common/xutil.h"