diff --git a/awesome.1.txt b/awesome.1.txt index 14f7a195..a1961b52 100644 --- a/awesome.1.txt +++ b/awesome.1.txt @@ -29,7 +29,7 @@ former or as a rectangular fractal for the later. Windows are grouped by tags. Each window can be tagged with one or multiple tags. Selecting certain tags displays all windows with these tags. -*awesome* can contain small statusbars which can display anything you want: +*awesome* can contain small wiboxes which can display anything you want: all available tags, the layout, the title of the visible windows, a text, etc. OPTIONS diff --git a/awesomerc.lua.in b/awesomerc.lua.in index 1b5377c3..d4643f9b 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -91,7 +91,7 @@ for s = 1, screen.count() do end -- }}} --- {{{ Statusbar +-- {{{ Wibox -- Create a taglist widget mytaglist = widget({ type = "taglist", name = "mytaglist" }) mytaglist:buttons({ @@ -141,13 +141,13 @@ for s = 1, screen.count() do mylayoutbox[s].image = image("@AWESOME_ICON_PATH@/layouts/tilew.png") end --- Create a statusbar for each screen and add it -mystatusbar = {} +-- Create a wibox for each screen and add it +mywibox = {} for s = 1, screen.count() do - mystatusbar[s] = wibox({ position = "top", name = "mystatusbar" .. s, + mywibox[s] = wibox({ position = "top", name = "mywibox" .. s, fg = beautiful.fg_normal, bg = beautiful.bg_normal }) - -- Add widgets to the statusbar - order matters - mystatusbar[s]:widgets({ + -- Add widgets to the wibox - order matters + mywibox[s]:widgets({ mytaglist, mytasklist, mylauncher, @@ -156,7 +156,7 @@ for s = 1, screen.count() do mylayoutbox[s], s == 1 and mysystray or nil }) - mystatusbar[s].screen = s + mywibox[s].screen = s end -- }}} diff --git a/client.c b/client.c index 6e6850bf..bcb75ab3 100644 --- a/client.c +++ b/client.c @@ -35,7 +35,6 @@ #include "luaa.h" #include "mouse.h" #include "systray.h" -#include "statusbar.h" #include "wibox.h" #include "property.h" #include "layouts/floating.h" @@ -203,7 +202,7 @@ client_ban(client_t *c) window_state_set(c->win, XCB_WM_STATE_ICONIC); else window_state_set(c->win, XCB_WM_STATE_WITHDRAWN); - if(c->titlebar && c->titlebar->position) + if(c->titlebar) xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); } @@ -260,8 +259,7 @@ client_stack_below(client_t *c, xcb_window_t previous) config_win_vals[0] = previous; config_win_vals[1] = XCB_STACK_MODE_BELOW; - if(c->titlebar - && c->titlebar->position) + if(c->titlebar) { xcb_configure_window(globalconf.connection, c->titlebar->sw.window, @@ -314,7 +312,7 @@ client_layer_translator(client_t *c) * relatively to the first matching in the list. */ void -client_stack(void) +client_stack() { uint32_t config_win_vals[2]; client_node_t *node; @@ -330,11 +328,11 @@ client_stack(void) if(client_layer_translator(node->client) == layer) config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]); - /* then stack ontop statusbar window */ + /* then stack ontop wibox window */ for(screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *sb = globalconf.screens[screen].statusbars.tab[i]; + wibox_t *sb = globalconf.screens[screen].wiboxes.tab[i]; if(sb->ontop) { xcb_configure_window(globalconf.connection, @@ -351,11 +349,11 @@ client_stack(void) if(client_layer_translator(node->client) == layer) config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]); - /* then stack not ontop statusbar window */ + /* then stack not ontop wibox window */ for(screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *sb = globalconf.screens[screen].statusbars.tab[i]; + wibox_t *sb = globalconf.screens[screen].wiboxes.tab[i]; if(!sb->ontop) { xcb_configure_window(globalconf.connection, @@ -588,11 +586,10 @@ client_resize(client_t *c, area_t geometry, bool hints) * maximized */ if(c->ismoving || client_isfloating(c) || layout_get_current(new_screen) == layout_floating) - { - titlebar_update_geometry_floating(c); if(!c->isfullscreen) c->f_geometry = geometry; - } + + titlebar_update_geometry_floating(c); xcb_configure_window(globalconf.connection, c->win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | @@ -601,17 +598,12 @@ client_resize(client_t *c, area_t geometry, bool hints) values); window_configure(c->win, geometry, c->border); - /* execute hook */ - hooks_property(c, "geometry"); - if(c->screen != new_screen) screen_client_moveto(c, new_screen, true, false); - } - /* call it again like it was floating, - * we want it to be sticked to the window */ - if(!c->ismoving && !client_isfloating(c) && layout != layout_floating) - titlebar_update_geometry_floating(c); + /* execute hook */ + hooks_property(c, "geometry"); + } } /** Set a clinet floating. @@ -626,13 +618,8 @@ client_setfloating(client_t *c, bool floating) && (c->type == WINDOW_TYPE_NORMAL)) { if((c->isfloating = floating)) - { if(!c->isfullscreen) - { client_resize(c, c->f_geometry, false); - titlebar_update_geometry_floating(c); - } - } client_need_arrange(c); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); client_stack(); @@ -852,12 +839,7 @@ client_unmanage(client_t *c) for(int i = 0; i < tags->len; i++) untag_client(c, tags->tab[i]); - if(c->titlebar) - { - xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); - wibox_unref(&c->titlebar); - c->titlebar = NULL; - } + titlebar_client_detach(c); ewmh_update_net_client_list(c->phys_screen); @@ -866,12 +848,12 @@ client_unmanage(client_t *c) xcb_delete_property(globalconf.connection, c->win, _AWESOME_FLOATING); if(client_hasstrut(c)) - /* All the statusbars (may) need to be repositioned */ + /* All the wiboxes (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; - statusbar_position_update(s); + wibox_t *s = globalconf.screens[screen].wiboxes.tab[i]; + wibox_position_update(s); } /* set client as invalid */ diff --git a/common/tokenize.gperf b/common/tokenize.gperf index 471dd451..bed67de7 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -14,6 +14,7 @@ class client color coords +east fg flex floating @@ -45,6 +46,7 @@ name on ontop opacity +orientation pid plot_data_add plot_properties_set @@ -57,6 +59,7 @@ selected shadow shadow_offset show_icons +south sticky text ticks_count diff --git a/common/util.c b/common/util.c index fe653c3c..2116cfe8 100644 --- a/common/util.c +++ b/common/util.c @@ -113,6 +113,8 @@ position_fromstr(const char *pos, ssize_t len) return Right; case A_TK_LEFT: return Left; + case A_TK_FLOATING: + return Floating; } } @@ -125,11 +127,47 @@ position_tostr(position_t p) { switch(p) { - case Top: return "top"; - case Bottom: return "bottom"; - case Right: return "right"; - case Left: return "left"; - default: return NULL; + case Top: return "top"; + case Bottom: return "bottom"; + case Right: return "right"; + case Left: return "left"; + case Floating: return "floating"; + default: return NULL; + } +} + +/** Get a orientation type from a string. + * \param pos The orientation. + * \param len The string length, -1 if unknown. + * \return A orientation. + */ +orientation_t +orientation_fromstr(const char *pos, ssize_t len) +{ + switch(a_tokenize(pos, len)) + { + default: + return North; + case A_TK_SOUTH: + return South; + case A_TK_EAST: + return East; + } +} + +/** Convert a orientation type to a string. + * \param p The orientation. + * \return A orientation string. + */ +const char * +orientation_tostr(orientation_t p) +{ + switch(p) + { + case North: return "north"; + case South: return "south"; + case East: return "east"; + default: return NULL; } } diff --git a/common/util.h b/common/util.h index 50aeffa4..2c345489 100644 --- a/common/util.h +++ b/common/util.h @@ -37,8 +37,9 @@ typedef enum { - Horizontal, - Vertical + East, + South, + North, } orientation_t; /** A list of possible position, not sex related */ @@ -47,7 +48,8 @@ typedef enum Top, Bottom, Right, - Left + Left, + Floating } position_t; /** Link a name to a function */ @@ -338,6 +340,8 @@ void _warn(int, const char *, const char *, ...) position_t position_fromstr(const char *, ssize_t); const char * position_tostr(position_t); +orientation_t orientation_fromstr(const char *, ssize_t); +const char * orientation_tostr(orientation_t); void *name_func_lookup(const char *, const name_func_link_t *); const char * name_func_rlookup(void *, const name_func_link_t *); void a_exec(const char *); diff --git a/draw.h b/draw.h index b2ed3666..6f0b09af 100644 --- a/draw.h +++ b/draw.h @@ -110,9 +110,21 @@ void draw_context_init(draw_context_t *, int, int, int, static inline void draw_context_wipe(draw_context_t *ctx) { - g_object_unref(ctx->layout); - cairo_surface_destroy(ctx->surface); - cairo_destroy(ctx->cr); + if(ctx->layout) + { + g_object_unref(ctx->layout); + ctx->layout = NULL; + } + if(ctx->surface) + { + cairo_surface_destroy(ctx->surface); + ctx->surface = NULL; + } + if(ctx->cr) + { + cairo_destroy(ctx->cr); + ctx->cr = NULL; + } } font_t *draw_font_new(int, const char *); diff --git a/event.c b/event.c index ebc0406a..42a0abbe 100644 --- a/event.c +++ b/event.c @@ -37,7 +37,6 @@ #include "keygrabber.h" #include "luaa.h" #include "systray.h" -#include "statusbar.h" #include "screen.h" #include "layouts/floating.h" #include "common/atoms.h" @@ -78,7 +77,7 @@ event_handle_mouse_button(client_t *c, } } -/** Get a widget node from a statusbar by coords. +/** Get a widget node from a wibox by coords. * \param Container position. * \param widgets The widget list. * \param width The container width. @@ -130,6 +129,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); client_t *c; widget_node_t *w; + wibox_t *wibox; /* ev->state is * button status (8 bits) + modifiers status (8 bits) @@ -137,35 +137,21 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e * drop them */ ev->state &= 0x00ff; - for(screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) - { - wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; - if(statusbar->sw.window == ev->event || statusbar->sw.window == ev->child) - { - /* If the statusbar is child, then x,y are - * relative to root window */ - if(statusbar->sw.window == ev->child) - { - ev->event_x -= statusbar->sw.geometry.x; - ev->event_y -= statusbar->sw.geometry.y; - } - if((w = widget_getbycoords(statusbar->position, statusbar->widgets, - statusbar->sw.geometry.width, - statusbar->sw.geometry.height, - &ev->event_x, &ev->event_y))) - w->widget->button(w, ev, statusbar->screen, statusbar); - /* return even if no widget match */ - return 0; - } - } - - if((c = client_getbytitlebarwin(ev->event))) + if((wibox = wibox_getbywin(ev->event)) + || (wibox = wibox_getbywin(ev->child))) { - if((w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets, - c->titlebar->geometry.width, c->titlebar->geometry.height, + /* If the wibox is child, then x,y are + * relative to root window */ + if(wibox->sw.window == ev->child) + { + ev->event_x -= wibox->sw.geometry.x; + ev->event_y -= wibox->sw.geometry.y; + } + if((w = widget_getbycoords(wibox->position, wibox->widgets, + wibox->sw.geometry.width, + wibox->sw.geometry.height, &ev->event_x, &ev->event_y))) - w->widget->button(w, ev, c->screen, c->titlebar); + w->widget->button(w, ev, wibox->screen, wibox); /* return even if no widget match */ return 0; } @@ -219,14 +205,13 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), if(client_isfloating(c) || layout_get_current(c->screen) == layout_floating) { client_resize(c, geometry, false); - titlebar_draw(c); if(client_hasstrut(c)) - /* All the statusbars (may) need to be repositioned */ + /* All the wiboxes (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; - statusbar_position_update(s); + wibox_t *s = globalconf.screens[screen].wiboxes.tab[i]; + wibox_position_update(s); } } else @@ -239,10 +224,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), } } else - { - titlebar_update_geometry_floating(c); window_configure(c->win, geometry, c->border); - } } else { @@ -379,27 +361,16 @@ event_handle_motionnotify(void *data __attribute__ ((unused)), xcb_connection_t *connection, xcb_motion_notify_event_t *ev) { - wibox_t *statusbar = statusbar_getbywin(ev->event); - client_t *c; + wibox_t *wibox = wibox_getbywin(ev->event); widget_node_t *w; - if(statusbar) + if(wibox) { - w = widget_getbycoords(statusbar->position, statusbar->widgets, - statusbar->sw.geometry.width, - statusbar->sw.geometry.height, + w = widget_getbycoords(wibox->position, wibox->widgets, + wibox->sw.geometry.width, + wibox->sw.geometry.height, &ev->event_x, &ev->event_y); - event_handle_widget_motionnotify(statusbar, - &statusbar->mouse_over, w); - } - else if((c = client_getbytitlebarwin(ev->event))) - { - w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets, - c->titlebar->sw.geometry.width, - c->titlebar->sw.geometry.height, - &ev->event_x, &ev->event_y); - event_handle_widget_motionnotify(c->titlebar, - &c->titlebar->mouse_over, w); + event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w); } return 0; @@ -415,26 +386,13 @@ event_handle_leavenotify(void *data __attribute__ ((unused)), xcb_connection_t *connection, xcb_leave_notify_event_t *ev) { - wibox_t *statusbar = statusbar_getbywin(ev->event); - client_t *c; + wibox_t *wibox = wibox_getbywin(ev->event); - if(statusbar) + if(wibox && wibox->mouse_over) { - if(statusbar->mouse_over) - { - /* call mouse leave function on widget the mouse was over */ - luaA_wibox_userdata_new(globalconf.L, statusbar); - luaA_dofunction(globalconf.L, statusbar->mouse_over->widget->mouse_leave, 1, 0); - } - } - else if((c = client_getbytitlebarwin(ev->event))) - { - if(c->titlebar->mouse_over) - { - /* call mouse leave function on widget the mouse was over */ - luaA_wibox_userdata_new(globalconf.L, c->titlebar); - luaA_dofunction(globalconf.L, c->titlebar->mouse_over->widget->mouse_leave, 1, 0); - } + /* call mouse leave function on widget the mouse was over */ + luaA_wibox_userdata_new(globalconf.L, wibox); + luaA_dofunction(globalconf.L, wibox->mouse_over->widget->mouse_leave, 1, 0); } return 0; @@ -491,25 +449,12 @@ event_handle_expose(void *data __attribute__ ((unused)), xcb_connection_t *connection __attribute__ ((unused)), xcb_expose_event_t *ev) { - client_t *c; + wibox_t *wibox = wibox_getbywin(ev->window); - for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) - { - wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; - if(statusbar->sw.window == ev->window) - { - simplewindow_refresh_pixmap_partial(&statusbar->sw, - ev->x, ev->y, - ev->width, ev->height); - return 0; - } - } - - if((c = client_getbytitlebarwin(ev->window))) - simplewindow_refresh_pixmap_partial(&c->titlebar->sw, - ev->x, ev->y, - ev->width, ev->height); + if(wibox) + simplewindow_refresh_pixmap_partial(&wibox->sw, + ev->x, ev->y, + ev->width, ev->height); return 0; } diff --git a/ewmh.c b/ewmh.c index ddb46a3c..ebeeae6e 100644 --- a/ewmh.c +++ b/ewmh.c @@ -31,8 +31,7 @@ #include "client.h" #include "widget.h" #include "cnode.h" -#include "titlebar.h" -#include "statusbar.h" +#include "wibox.h" #include "common/atoms.h" extern awesome_t globalconf; @@ -212,7 +211,7 @@ ewmh_update_workarea(int phys_screen) tag_array_t *tags = &globalconf.screens[phys_screen].tags; uint32_t *area = p_alloca(uint32_t, tags->len * 4); area_t geom = screen_area_get(phys_screen, - &globalconf.screens[phys_screen].statusbars, + &globalconf.screens[phys_screen].wiboxes, &globalconf.screens[phys_screen].padding, true); @@ -533,12 +532,12 @@ ewmh_client_strut_update(client_t *c, xcb_get_property_reply_t *strut_r) c->strut.bottom_end_x = strut[11]; client_need_arrange(c); - /* All the statusbars (may) need to be repositioned */ + /* All the wiboxes (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; - statusbar_position_update(s); + wibox_t *s = globalconf.screens[screen].wiboxes.tab[i]; + wibox_position_update(s); } } } diff --git a/layouts/fair.c b/layouts/fair.c index 2b19b770..0bc2c1b8 100644 --- a/layouts/fair.c +++ b/layouts/fair.c @@ -36,7 +36,7 @@ layout_fair(int screen, const orientation_t orientation) area_t geometry, area; area = screen_area_get(screen, - &globalconf.screens[screen].statusbars, + &globalconf.screens[screen].wiboxes, &globalconf.screens[screen].padding, true); @@ -54,7 +54,7 @@ layout_fair(int screen, const orientation_t orientation) for(c = globalconf.clients; c; c = c->next) if(IS_TILED(c, screen)) { - if (orientation == Horizontal) + if (orientation == East) { geometry.width = area.width / u_divisions; geometry.height = area.height / v_divisions; @@ -86,13 +86,13 @@ layout_fair(int screen, const orientation_t orientation) void layout_fairh(int screen) { - layout_fair(screen, Horizontal); + layout_fair(screen, East); } void layout_fairv(int screen) { - layout_fair(screen, Vertical); + layout_fair(screen, South); } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/layouts/fibonacci.c b/layouts/fibonacci.c index cd783e73..577c1928 100644 --- a/layouts/fibonacci.c +++ b/layouts/fibonacci.c @@ -33,7 +33,7 @@ layout_fibonacci(int screen, int shape) client_t *c; area_t geometry, area; geometry = area = screen_area_get(screen, - &globalconf.screens[screen].statusbars, + &globalconf.screens[screen].wiboxes, &globalconf.screens[screen].padding, true); diff --git a/layouts/magnifier.c b/layouts/magnifier.c index 8fecc969..10c0d928 100644 --- a/layouts/magnifier.c +++ b/layouts/magnifier.c @@ -35,7 +35,7 @@ layout_magnifier(int screen) client_t *c, *focus; tag_t **curtags = tags_get_current(screen); area_t geometry, area = screen_area_get(screen, - &globalconf.screens[screen].statusbars, + &globalconf.screens[screen].wiboxes, &globalconf.screens[screen].padding, true); diff --git a/layouts/max.c b/layouts/max.c index 31e0787a..0c245414 100644 --- a/layouts/max.c +++ b/layouts/max.c @@ -31,7 +31,7 @@ layout_max(int screen) { client_t *c; area_t area = screen_area_get(screen, - &globalconf.screens[screen].statusbars, + &globalconf.screens[screen].wiboxes, &globalconf.screens[screen].padding, true); diff --git a/layouts/tile.c b/layouts/tile.c index 96ebd128..6fb6d3b6 100644 --- a/layouts/tile.c +++ b/layouts/tile.c @@ -43,7 +43,7 @@ _tile(int screen, const position_t position) tag_t **curtags = tags_get_current(screen); area = screen_area_get(screen, - &globalconf.screens[screen].statusbars, + &globalconf.screens[screen].wiboxes, &globalconf.screens[screen].padding, true); diff --git a/lib/awful.lua.in b/lib/awful.lua.in index 0136c268..b755cbc6 100644 --- a/lib/awful.lua.in +++ b/lib/awful.lua.in @@ -1515,6 +1515,7 @@ end -- bg: the background color. -- fg_focus: the foreground color for focused window. -- fg_focus: the background color for focused window. +-- width: the titlebar width function titlebar.add(c, args) if not c or c.type ~= "normal" then return end if not args then args = {} end @@ -1524,6 +1525,7 @@ function titlebar.add(c, args) titlebar.data[c].bg = args.bg or theme.titlebar_bg_normal or theme.bg_normal titlebar.data[c].fg_focus = args.fg_focus or theme.titlebar_fg_focus or theme.fg_focus titlebar.data[c].bg_focus = args.bg_focus or theme.titlebar_bg_focus or theme.bg_focus + titlebar.data[c].width = args.width -- Built args local targs = {} @@ -1578,6 +1580,7 @@ function titlebar.add(c, args) c.titlebar = tb titlebar.update(c) + titlebar.update(c, "geometry") end --- Update a titlebar. This should be called in some hooks. @@ -1602,6 +1605,17 @@ function titlebar.update(c, prop) if appicon then appicon.image = c.icon end + elseif prop == "geometry" then + if titlebar.data[c].width then + if c.titlebar.position == "top" + or c.titlebar.position == "bottom" then + local w = math.min(titlebar.data[c].width, c:coords().width + 2 * c.border_width) + c.titlebar:geometry({ width = w }) + else + local w = math.min(titlebar.data[c].width, c:coords().height + 2 * c.border_width) + c.titlebar:geometry({ height = w }) + end + end end if capi.client.focus == c then c.titlebar.fg = titlebar.data[c].fg_focus diff --git a/luaa.c b/luaa.c index 38037940..b9c5f5bb 100644 --- a/luaa.c +++ b/luaa.c @@ -46,7 +46,6 @@ #include "client.h" #include "screen.h" #include "event.h" -#include "statusbar.h" #include "titlebar.h" #include "mouse.h" #include "layouts/tile.h" diff --git a/mouse.c b/mouse.c index 7b23cc0e..8a60e2d2 100644 --- a/mouse.c +++ b/mouse.c @@ -27,7 +27,7 @@ #include "tag.h" #include "client.h" #include "titlebar.h" -#include "statusbar.h" +#include "wibox.h" #include "layouts/floating.h" #include "layouts/tile.h" #include "layouts/magnifier.h" @@ -132,7 +132,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap) area_t snapper_geometry; area_t screen_geometry = screen_area_get(c->screen, - &globalconf.screens[c->screen].statusbars, + &globalconf.screens[c->screen].wiboxes, &globalconf.screens[c->screen].padding, false); @@ -239,8 +239,7 @@ mouse_snap_to_corner(area_t a, int *x, int *y, corner_t corner) * \param border The client border size. */ static void -mouse_infobox_draw(simple_window_t *sw, - area_t geometry, int border) +mouse_infobox_draw(simple_window_t *sw, area_t geometry, int border) { area_t draw_geometry = { 0, 0, sw->ctx.width, sw->ctx.height }; char size[64]; @@ -282,10 +281,9 @@ mouse_infobox_new(simple_window_t *sw, int phys_screen, int border, area_t geome geom.x = geometry.x + ((2 * border + geometry.width) - geom.width) / 2; geom.y = geometry.y + ((2 * border + geometry.height) - geom.height) / 2; - simplewindow_init(sw, phys_screen, - geom.x, geom.y, - geom.width, geom.height, 0, - Top, &globalconf.colors.fg, &globalconf.colors.bg); + p_clear(sw, 1); + simplewindow_init(sw, phys_screen, geom, 0, East, + &globalconf.colors.fg, &globalconf.colors.bg); xcb_map_window(globalconf.connection, sw->window); mouse_infobox_draw(sw, geometry, border); @@ -520,7 +518,9 @@ mouse_client_move(client_t *c, int snap, bool infobox) if(infobox) mouse_infobox_draw(&sw, c->geometry, c->border); - statusbar_refresh(); + /* refresh live */ + wibox_refresh(); + xcb_flush(globalconf.connection); /* keep track */ last_x = mouse_x; @@ -539,8 +539,8 @@ mouse_client_move(client_t *c, int snap, bool infobox) globalconf.screens[c->screen].need_arrange = true; globalconf.screens[newscreen].need_arrange = true; layout_refresh(); - titlebar_refresh(); - statusbar_refresh(); + wibox_refresh(); + xcb_flush(globalconf.connection); } /* find client to swap with */ @@ -552,7 +552,8 @@ mouse_client_move(client_t *c, int snap, bool infobox) client_list_swap(&globalconf.clients, c, target); globalconf.screens[c->screen].need_arrange = true; layout_refresh(); - titlebar_refresh(); + wibox_refresh(); + xcb_flush(globalconf.connection); } } @@ -695,8 +696,10 @@ mouse_client_resize_floating(client_t *c, corner_t corner, bool infobox) /* resize the client */ client_resize(c, geo, false); - /* redaw titlebar live */ - titlebar_draw(c); + + /* refresh live */ + wibox_refresh(); + xcb_flush(globalconf.connection); /* draw the infobox */ if(infobox) @@ -718,7 +721,7 @@ static void mouse_client_resize_tiled(client_t *c) { xcb_screen_t *screen; - /* screen area modulo statusbar */ + /* screen area modulo wibox */ area_t area; /* current tag */ tag_t *tag; @@ -733,7 +736,7 @@ mouse_client_resize_tiled(client_t *c) layout = tag->layout; area = screen_area_get(tag->screen, - &globalconf.screens[tag->screen].statusbars, + &globalconf.screens[tag->screen].wiboxes, &globalconf.screens[tag->screen].padding, true); @@ -799,7 +802,8 @@ mouse_client_resize_tiled(client_t *c) tag->mwfact = mwfact; globalconf.screens[tag->screen].need_arrange = true; layout_refresh(); - titlebar_refresh(); + wibox_refresh(); + xcb_flush(globalconf.connection); } } @@ -814,7 +818,7 @@ mouse_client_resize_tiled(client_t *c) static void mouse_client_resize_magnified(client_t *c, bool infobox) { - /* screen area modulo statusbar */ + /* screen area modulo wibox */ area_t area; /* center of area */ int center_x, center_y; @@ -836,7 +840,7 @@ mouse_client_resize_magnified(client_t *c, bool infobox) root = xutil_screen_get(globalconf.connection, c->phys_screen)->root; area = screen_area_get(tag->screen, - &globalconf.screens[tag->screen].statusbars, + &globalconf.screens[tag->screen].wiboxes, &globalconf.screens[tag->screen].padding, true); @@ -904,7 +908,8 @@ mouse_client_resize_magnified(client_t *c, bool infobox) tag->mwfact = mwfact; globalconf.screens[tag->screen].need_arrange = true; layout_refresh(); - titlebar_refresh(); + wibox_refresh(); + xcb_flush(globalconf.connection); } /* draw the infobox */ diff --git a/screen.c b/screen.c index a25bb171..22826b78 100644 --- a/screen.c +++ b/screen.c @@ -28,8 +28,8 @@ #include "ewmh.h" #include "tag.h" #include "client.h" -#include "statusbar.h" #include "widget.h" +#include "wibox.h" #include "layouts/tile.h" extern awesome_t globalconf; @@ -156,13 +156,13 @@ screen_getbycoord(int screen, int x, int y) /** Get screens info. * \param screen Screen number. - * \param statusbars Statusbar list to remove. + * \param wiboxes Wiboxes list to remove. * \param padding Padding. * \param strut Honor windows strut. * \return The screen area. */ area_t -screen_area_get(int screen, wibox_array_t *statusbars, +screen_area_get(int screen, wibox_array_t *wiboxes, padding_t *padding, bool strut) { area_t area = globalconf.screens[screen].geometry; @@ -215,24 +215,24 @@ screen_area_get(int screen, wibox_array_t *statusbars, } - if(statusbars) - for(int i = 0; i < statusbars->len; i++) + if(wiboxes) + for(int i = 0; i < wiboxes->len; i++) { - wibox_t *sb = statusbars->tab[i]; - if(sb->isvisible) - switch(sb->position) + wibox_t *w = wiboxes->tab[i]; + if(w->isvisible) + switch(w->position) { case Top: - top = MAX(top, (uint16_t) (sb->sw.geometry.y - area.y) + sb->sw.geometry.height); + top = MAX(top, (uint16_t) (w->sw.geometry.y - area.y) + w->sw.geometry.height); break; case Bottom: - bottom = MAX(bottom, (uint16_t) (area.y + area.height) - sb->sw.geometry.y); + bottom = MAX(bottom, (uint16_t) (area.y + area.height) - w->sw.geometry.y); break; case Left: - left = MAX(left, (uint16_t) (sb->sw.geometry.x - area.x) + sb->sw.geometry.width); + left = MAX(left, (uint16_t) (w->sw.geometry.x - area.x) + w->sw.geometry.width); break; case Right: - right = MAX(right, (uint16_t) (area.x + area.width) - sb->sw.geometry.x); + right = MAX(right, (uint16_t) (area.x + area.width) - w->sw.geometry.x); break; default: break; @@ -249,12 +249,12 @@ screen_area_get(int screen, wibox_array_t *statusbars, /** Get display info. * \param phys_screen Physical screen number. - * \param statusbars The statusbars. + * \param wiboxes The wiboxes. * \param padding Padding. * \return The display area. */ area_t -display_area_get(int phys_screen, wibox_array_t *statusbars, padding_t *padding) +display_area_get(int phys_screen, wibox_array_t *wiboxes, padding_t *padding) { xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); area_t area = { .x = 0, @@ -262,12 +262,12 @@ display_area_get(int phys_screen, wibox_array_t *statusbars, padding_t *padding) .width = s->width_in_pixels, .height = s->height_in_pixels }; - if(statusbars) - for(int i = 0; i < statusbars->len; i++) + if(wiboxes) + for(int i = 0; i < wiboxes->len; i++) { - wibox_t *sb = statusbars->tab[i]; - area.y += sb->position == Top ? sb->geometry.height : 0; - area.height -= (sb->position == Top || sb->position == Bottom) ? sb->geometry.height : 0; + wibox_t *w = wiboxes->tab[i]; + area.y += w->position == Top ? w->sw.geometry.height : 0; + area.height -= (w->position == Top || w->position == Bottom) ? w->sw.geometry.height : 0; } /* make padding corrections */ @@ -312,6 +312,9 @@ screen_client_moveto(client_t *c, int new_screen, bool dotag, bool doresize) c->screen = new_screen; + if(c->titlebar) + c->titlebar->screen = new_screen; + widget_invalidate_cache(old_screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(new_screen, WIDGET_CACHE_CLIENTS); @@ -482,7 +485,7 @@ luaA_screen_tags(lua_State *L) * \return The number of elements pushed on stack. * \luastack * \lfield coords The screen coordinates. Immutable. - * \lfield workarea The screen workarea, i.e. without statusbar. + * \lfield workarea The screen workarea, i.e. without wiboxes. */ static int luaA_screen_index(lua_State *L) @@ -503,7 +506,7 @@ luaA_screen_index(lua_State *L) luaA_pusharea(L, s->geometry); break; case A_TK_WORKAREA: - luaA_pusharea(L, screen_area_get(s->index, &s->statusbars, &s->padding, true)); + luaA_pusharea(L, screen_area_get(s->index, &s->wiboxes, &s->padding, true)); break; default: return 0; @@ -539,9 +542,9 @@ luaA_screen_padding(lua_State *L) s->need_arrange = true; - /* All the statusbar repositioned */ - for(int i = 0; i < s->statusbars.len; i++) - statusbar_position_update(s->statusbars.tab[i]); + /* All the wiboxes repositioned */ + for(int i = 0; i < s->wiboxes.len; i++) + wibox_position_update(s->wiboxes.tab[i]); ewmh_update_workarea(screen_virttophys(s->index)); } diff --git a/statusbar.c b/statusbar.c index a4dc0ed4..df18ba73 100644 --- a/statusbar.c +++ b/statusbar.c @@ -19,440 +19,8 @@ * */ -#include - -#include "client.h" -#include "statusbar.h" -#include "screen.h" -#include "widget.h" +#include "luaa.h" #include "wibox.h" -#include "ewmh.h" - -extern awesome_t globalconf; - -/** Kick out systray windows. - * \param phys_screen Physical screen number. - */ -static void -statusbar_systray_kickout(int phys_screen) -{ - xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); - - /* Who! Check that we're not deleting a statusbar 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.screens[phys_screen].systray.window, - s->root, -512, -512); - - globalconf.screens[phys_screen].systray.parent = s->root; -} - -static void -statusbar_systray_refresh(wibox_t *statusbar) -{ - widget_node_t *systray; - - if(statusbar->screen == SCREEN_UNDEF) - return; - - for(systray = statusbar->widgets; systray; systray = systray->next) - if(systray->widget->type == systray_new) - { - uint32_t config_back[] = { statusbar->colors.bg.pixel }; - uint32_t config_win_vals[4]; - uint32_t config_win_vals_off[2] = { -512, -512 }; - xembed_window_t *em; - position_t pos; - int phys_screen = statusbar->sw.ctx.phys_screen; - - if(statusbar->isvisible - && systray->widget->isvisible - && systray->area.width) - { - pos = statusbar->position; - - /* Set background of the systray window. */ - xcb_change_window_attributes(globalconf.connection, - globalconf.screens[phys_screen].systray.window, - XCB_CW_BACK_PIXEL, config_back); - /* Map it. */ - xcb_map_window(globalconf.connection, globalconf.screens[phys_screen].systray.window); - /* Move it. */ - switch(statusbar->position) - { - case Left: - config_win_vals[0] = systray->area.y; - config_win_vals[1] = statusbar->sw.geometry.height - systray->area.x - systray->area.width; - config_win_vals[2] = systray->area.height; - config_win_vals[3] = systray->area.width; - break; - case Right: - config_win_vals[0] = systray->area.y; - config_win_vals[1] = systray->area.x; - config_win_vals[2] = systray->area.height; - config_win_vals[3] = systray->area.width; - break; - default: - config_win_vals[0] = systray->area.x; - config_win_vals[1] = systray->area.y; - config_win_vals[2] = systray->area.width; - config_win_vals[3] = systray->area.height; - break; - } - /* reparent */ - if(globalconf.screens[phys_screen].systray.parent != statusbar->sw.window) - { - xcb_reparent_window(globalconf.connection, - globalconf.screens[phys_screen].systray.window, - statusbar->sw.window, - config_win_vals[0], config_win_vals[1]); - globalconf.screens[phys_screen].systray.parent = statusbar->sw.window; - } - xcb_configure_window(globalconf.connection, - globalconf.screens[phys_screen].systray.window, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y - | XCB_CONFIG_WINDOW_WIDTH - | XCB_CONFIG_WINDOW_HEIGHT, - config_win_vals); - /* width = height = systray height */ - config_win_vals[2] = config_win_vals[3] = systray->area.height; - config_win_vals[0] = 0; - } - else - { - xcb_unmap_window(globalconf.connection, globalconf.screens[phys_screen].systray.window); - statusbar_systray_kickout(phys_screen); - break; - } - - switch(pos) - { - case Left: - config_win_vals[1] = systray->area.width - config_win_vals[3]; - for(em = globalconf.embedded; em; em = em->next) - if(em->phys_screen == phys_screen) - { - if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) statusbar->sw.geometry.y) - { - xcb_map_window(globalconf.connection, em->win); - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y - | XCB_CONFIG_WINDOW_WIDTH - | XCB_CONFIG_WINDOW_HEIGHT, - config_win_vals); - config_win_vals[1] -= config_win_vals[3]; - } - else - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y, - config_win_vals_off); - } - break; - case Right: - config_win_vals[1] = 0; - for(em = globalconf.embedded; em; em = em->next) - if(em->phys_screen == phys_screen) - { - if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) statusbar->sw.geometry.y + statusbar->sw.geometry.width) - { - xcb_map_window(globalconf.connection, em->win); - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y - | XCB_CONFIG_WINDOW_WIDTH - | XCB_CONFIG_WINDOW_HEIGHT, - config_win_vals); - config_win_vals[1] += config_win_vals[3]; - } - else - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y, - config_win_vals_off); - } - break; - case Top: - case Bottom: - config_win_vals[1] = 0; - for(em = globalconf.embedded; em; em = em->next) - 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->area) + statusbar->sw.geometry.x) - { - xcb_map_window(globalconf.connection, em->win); - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y - | XCB_CONFIG_WINDOW_WIDTH - | XCB_CONFIG_WINDOW_HEIGHT, - config_win_vals); - config_win_vals[0] += config_win_vals[2]; - } - else - xcb_configure_window(globalconf.connection, em->win, - XCB_CONFIG_WINDOW_X - | XCB_CONFIG_WINDOW_Y, - config_win_vals_off); - } - break; - } - break; - } -} - -/** Draw a statusbar. - * \param statusbar The statusbar to draw. - */ -static void -statusbar_draw(wibox_t *statusbar) -{ - statusbar->need_update = false; - - if(statusbar->isvisible) - { - widget_render(statusbar->widgets, &statusbar->sw.ctx, statusbar->sw.gc, - statusbar->sw.pixmap, - statusbar->screen, statusbar->position, - statusbar->sw.geometry.x, statusbar->sw.geometry.y, - statusbar); - simplewindow_refresh_pixmap(&statusbar->sw); - } - - statusbar_systray_refresh(statusbar); -} - -/** Get a statusbar by its window. - * \param w The window id. - * \return A statusbar if found, NULL otherwise. - */ -wibox_t * -statusbar_getbywin(xcb_window_t w) -{ - for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) - { - wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; - if(s->sw.window == w) - return s; - } - return NULL; -} - -/** Statusbar refresh function. - */ -void -statusbar_refresh(void) -{ - for(int screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) - { - wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; - if(s->need_update) - statusbar_draw(s); - } -} - -/** Update the statusbar position. It deletes every statusbar resources and - * create them back. - * \param statusbar The statusbar. - */ -void -statusbar_position_update(wibox_t *statusbar) -{ - area_t area; - bool ignore = false; - - globalconf.screens[statusbar->screen].need_arrange = true; - - if(!statusbar->isvisible) - { - xcb_unmap_window(globalconf.connection, statusbar->sw.window); - /* kick out systray if needed */ - statusbar_systray_refresh(statusbar); - return; - } - - area = screen_area_get(statusbar->screen, NULL, - &globalconf.screens[statusbar->screen].padding, true); - - /* Top and Bottom wibox_t have prio */ - for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) - { - wibox_t *sb = globalconf.screens[statusbar->screen].statusbars.tab[i]; - /* Ignore every statusbar after me that is in the same position */ - if(statusbar == sb) - { - ignore = true; - continue; - } - else if(ignore && statusbar->position == sb->position) - continue; - switch(sb->position) - { - case Left: - switch(statusbar->position) - { - case Left: - area.x += statusbar->geometry.height; - break; - default: - break; - } - break; - case Right: - switch(statusbar->position) - { - case Right: - area.x -= statusbar->geometry.height; - break; - default: - break; - } - break; - case Top: - switch(statusbar->position) - { - case Top: - area.y += sb->geometry.height; - break; - case Left: - case Right: - area.height -= sb->geometry.height; - area.y += sb->geometry.height; - break; - default: - break; - } - break; - case Bottom: - switch(statusbar->position) - { - case Bottom: - area.y -= sb->geometry.height; - break; - case Left: - case Right: - area.height -= sb->geometry.height; - break; - default: - break; - } - break; - } - } - - switch(statusbar->position) - { - case Right: - statusbar->geometry.height = area.height; - statusbar->geometry.width = 1.5 * globalconf.font->height; - switch(statusbar->align) - { - default: - statusbar->geometry.x = area.x + area.width - statusbar->geometry.width; - statusbar->geometry.y = area.y; - break; - case AlignRight: - statusbar->geometry.x = area.x + area.width - statusbar->geometry.width; - statusbar->geometry.y = area.y + area.height - statusbar->geometry.height; - break; - case AlignCenter: - statusbar->geometry.x = area.x + area.width - statusbar->geometry.width; - statusbar->geometry.y = (area.y + area.height - statusbar->geometry.height) / 2; - break; - } - break; - case Left: - statusbar->geometry.height = area.height; - statusbar->geometry.width = 1.5 * globalconf.font->height; - switch(statusbar->align) - { - default: - statusbar->geometry.x = area.x; - statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height; - break; - case AlignRight: - statusbar->geometry.x = area.x; - statusbar->geometry.y = area.y; - break; - case AlignCenter: - statusbar->geometry.x = area.x; - statusbar->geometry.y = (area.y + area.height - statusbar->geometry.height) / 2; - } - break; - case Bottom: - statusbar->geometry.width = area.width; - statusbar->geometry.height = 1.5 * globalconf.font->height; - switch(statusbar->align) - { - default: - statusbar->geometry.x = area.x; - statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height; - break; - case AlignRight: - statusbar->geometry.x = area.x + area.width - statusbar->geometry.width; - statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height; - break; - case AlignCenter: - statusbar->geometry.x = area.x + (area.width - statusbar->geometry.width) / 2; - statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height; - break; - } - break; - default: - statusbar->geometry.width = area.width; - statusbar->geometry.height = 1.5 * globalconf.font->height; - switch(statusbar->align) - { - default: - statusbar->geometry.x = area.x; - statusbar->geometry.y = area.y; - break; - case AlignRight: - statusbar->geometry.x = area.x + area.width - statusbar->geometry.width; - statusbar->geometry.y = area.y; - break; - case AlignCenter: - statusbar->geometry.x = area.x + (area.width - statusbar->geometry.width) / 2; - statusbar->geometry.y = area.y; - break; - } - break; - } - - if(!statusbar->sw.window) - { - int phys_screen = screen_virttophys(statusbar->screen); - - simplewindow_init(&statusbar->sw, phys_screen, - statusbar->geometry.x, statusbar->geometry.y, - statusbar->geometry.width, statusbar->geometry.height, - 0, statusbar->position, - &statusbar->colors.fg, &statusbar->colors.bg); - statusbar->need_update = true; - } - /* same window size and position ? */ - else - { - if(statusbar->geometry.width != statusbar->sw.geometry.width - || statusbar->geometry.height != statusbar->sw.geometry.height) - { - simplewindow_resize(&statusbar->sw, statusbar->geometry.width, statusbar->geometry.height); - statusbar->need_update = true; - } - - if(statusbar->geometry.x != statusbar->sw.geometry.x - || statusbar->geometry.y != statusbar->sw.geometry.y) - simplewindow_move(&statusbar->sw, statusbar->geometry.x, statusbar->geometry.y); - } - - xcb_map_window(globalconf.connection, statusbar->sw.window); -} /** Create a new statusbar (DEPRECATED). * \param L The Lua VM state. @@ -470,106 +38,6 @@ luaA_statusbar_new(lua_State *L) return luaA_wibox_new(L); } -/** Remove a statubar from a screen. - * \param statusbar Statusbar to detach from screen. - */ -void -statusbar_detach(wibox_t *statusbar) -{ - if(statusbar->screen != SCREEN_UNDEF) - { - bool v; - - /* save visible state */ - v = statusbar->isvisible; - statusbar->isvisible = false; - statusbar_position_update(statusbar); - /* restore position */ - statusbar->isvisible = v; - - simplewindow_wipe(&statusbar->sw); - - for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) - if(globalconf.screens[statusbar->screen].statusbars.tab[i] == statusbar) - { - wibox_array_take(&globalconf.screens[statusbar->screen].statusbars, i); - break; - } - globalconf.screens[statusbar->screen].need_arrange = true; - statusbar->screen = SCREEN_UNDEF; - statusbar->type = WIBOX_TYPE_NONE; - wibox_unref(&statusbar); - } -} - -/** Attach a statusbar. - * \param statusbar The statusbar to attach. - * \param s The screen to attach the statusbar to. - */ -void -statusbar_attach(wibox_t *statusbar, screen_t *s) -{ - statusbar_detach(statusbar); - - statusbar->screen = s->index; - - wibox_array_append(&s->statusbars, wibox_ref(&statusbar)); - - statusbar->type = WIBOX_TYPE_STATUSBAR; - - /* All the other statusbar and ourselves need to be repositioned */ - for(int i = 0; i < s->statusbars.len; i++) - statusbar_position_update(s->statusbars.tab[i]); - - ewmh_update_workarea(screen_virttophys(s->index)); -} - -/** Statusbar newindex. - * \param L The Lua VM state. - * \param statusbar The wibox statusbar. - * \param tok The token for property. - * \return The number of elements pushed on stack. - */ -int -luaA_statusbar_newindex(lua_State *L, wibox_t *statusbar, awesome_token_t tok) -{ - size_t len; - const char *buf; - position_t p; - - switch(tok) - { - case A_TK_ALIGN: - buf = luaL_checklstring(L, 3, &len); - statusbar->align = draw_align_fromstr(buf, len); - statusbar_position_update(statusbar); - break; - case A_TK_POSITION: - buf = luaL_checklstring(L, 3, &len); - p = position_fromstr(buf, len); - if(p != statusbar->position) - { - statusbar->position = p; - simplewindow_wipe(&statusbar->sw); - statusbar->sw.window = 0; - if(statusbar->screen != SCREEN_UNDEF) - { - for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) - { - wibox_t *s = globalconf.screens[statusbar->screen].statusbars.tab[i]; - statusbar_position_update(s); - } - ewmh_update_workarea(screen_virttophys(statusbar->screen)); - } - } - break; - default: - return 0; - } - - return 0; -} - const struct luaL_reg awesome_statusbar_methods[] = { { "__call", luaA_statusbar_new }, diff --git a/statusbar.h b/statusbar.h deleted file mode 100644 index abf8b890..00000000 --- a/statusbar.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * wibox.h - wibox functions header - * - * Copyright © 2007-2008 Julien Danjou - * - * 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_WIBOX_H -#define AWESOME_WIBOX_H - -#include "structs.h" -#include "swindow.h" -#include "common/refcount.h" - -wibox_t * statusbar_getbywin(xcb_window_t); -void statusbar_refresh(void); -void statusbar_position_update(wibox_t *); -void statusbar_detach(wibox_t *); -void statusbar_attach(wibox_t *, screen_t *); - -int luaA_statusbar_newindex(lua_State *, wibox_t *, awesome_token_t); - -#endif -// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/structs.h b/structs.h index d9b80f3b..1c4f486e 100644 --- a/structs.h +++ b/structs.h @@ -62,8 +62,7 @@ typedef enum /** Wibox types */ typedef enum { - WIBOX_TYPE_NONE = 0, - WIBOX_TYPE_STATUSBAR, + WIBOX_TYPE_NORMAL = 0, WIBOX_TYPE_TITLEBAR } wibox_type_t; @@ -94,14 +93,12 @@ typedef struct bool ontop; /** Visible */ bool isvisible; + /** Position */ + position_t position; /** Wibox type */ wibox_type_t type; /** Window */ simple_window_t sw; - /** Box geometry */ - area_t geometry; - /** Box position */ - position_t position; /** Alignment */ alignment_t align; /** Screen */ @@ -112,16 +109,6 @@ typedef struct widget_node_t *mouse_over; /** Need update */ bool need_update; - /** Default colors */ - struct - { - xcolor_t fg, bg; - } colors; - struct - { - xcolor_t color; - uint16_t width; - } border; } wibox_t; ARRAY_TYPE(wibox_t *, wibox) @@ -367,8 +354,8 @@ typedef struct bool need_arrange; /** Tag list */ tag_array_t tags; - /** Statusbars */ - wibox_array_t statusbars; + /** Wiboxes */ + wibox_array_t wiboxes; /** Padding */ padding_t padding; /** Window that contains the systray */ diff --git a/swindow.c b/swindow.c index 1ae45ae1..c1926ce7 100644 --- a/swindow.c +++ b/swindow.c @@ -30,25 +30,52 @@ extern awesome_t globalconf; +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->geometry.height, sw->geometry.width); + draw_context_init(&sw->ctx, phys_screen, + sw->geometry.height, sw->geometry.width, + sw->ctx.pixmap, &fg, &bg); + break; + case East: + draw_context_init(&sw->ctx, phys_screen, + sw->geometry.width, sw->geometry.height, + sw->pixmap, &fg, &bg); + break; + } +} + /** Initialize a simple window. * \param sw The simple window to initialize. * \param phys_screen Physical screen number. - * \param x x coordinate. - * \param y y coordinate. - * \param w Width. - * \param h Height. + * \param geometry Window geometry. * \param border_width Window border width. - * \param position The rendering position. + * \param orientation The rendering orientation. * \param bg Default foreground color. * \param bg Default background color. */ void simplewindow_init(simple_window_t *sw, int phys_screen, - int16_t x, int16_t y, - uint16_t w, uint16_t h, + area_t geometry, uint16_t border_width, - position_t position, + orientation_t orientation, const xcolor_t *fg, const xcolor_t *bg) { xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); @@ -56,10 +83,14 @@ simplewindow_init(simple_window_t *sw, 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 = x; - sw->geometry.y = y; - sw->geometry.width = w; - sw->geometry.height = h; + 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; + sw->orientation = orientation; + sw->ctx.fg = *fg; + sw->ctx.bg = *bg; create_win_val[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE; create_win_val[1] = 1; @@ -70,39 +101,21 @@ simplewindow_init(simple_window_t *sw, | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE; sw->window = xcb_generate_id(globalconf.connection); - xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root, x, y, w, h, + xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root, + geometry.x, geometry.y, geometry.width, geometry.height, border_width, XCB_COPY_FROM_PARENT, s->root_visual, XCB_CW_BACK_PIXMAP | 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, w, h); + xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, + geometry.width, geometry.height); - switch(position) - { - xcb_pixmap_t pixmap; - case Left: - case Right: - /* we need a new pixmap this way [ ] to render */ - pixmap = xcb_generate_id(globalconf.connection); - xcb_create_pixmap(globalconf.connection, - s->root_depth, - pixmap, s->root, h, w); - draw_context_init(&sw->ctx, phys_screen, - h, w, pixmap, fg, bg); - break; - default: - draw_context_init(&sw->ctx, phys_screen, - w, h, sw->pixmap, fg, bg); - break; - } + 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); - - sw->border.width = border_width; - sw->position = position; } /** Destroy all resources of a simple window. @@ -111,12 +124,21 @@ simplewindow_init(simple_window_t *sw, void simplewindow_wipe(simple_window_t *sw) { - xcb_destroy_window(globalconf.connection, sw->window); - sw->window = XCB_NONE; - xcb_free_pixmap(globalconf.connection, sw->pixmap); - sw->pixmap = XCB_NONE; - xcb_free_gc(globalconf.connection, sw->gc); - sw->gc = XCB_NONE; + 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); } @@ -130,41 +152,13 @@ simplewindow_move(simple_window_t *sw, int x, int y) { const uint32_t move_win_vals[] = { x, y }; - sw->geometry.x = x; - sw->geometry.y = y; - xcb_configure_window(globalconf.connection, sw->window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, - move_win_vals); -} - -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->position) + if(x != sw->geometry.x || y != sw->geometry.y) { - case Left: - case Right: - /* 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->geometry.height, sw->geometry.width); - draw_context_init(&sw->ctx, phys_screen, - sw->geometry.height, sw->geometry.width, - sw->ctx.pixmap, &fg, &bg); - break; - default: - draw_context_init(&sw->ctx, phys_screen, - sw->geometry.width, sw->geometry.height, - sw->pixmap, &fg, &bg); - break; + sw->geometry.x = x; + sw->geometry.y = y; + xcb_configure_window(globalconf.connection, sw->window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, + move_win_vals); } } @@ -184,6 +178,9 @@ simplewindow_resize(simple_window_t *sw, int w, int h) sw->geometry.width = resize_win_vals[0] = w; sw->geometry.height = resize_win_vals[1] = 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, w, h); xcb_configure_window(globalconf.connection, sw->window, @@ -195,40 +192,40 @@ simplewindow_resize(simple_window_t *sw, int w, int h) /** Move and resize a window in one call. * \param sw The simple window to move and resize. - * \param x The new x coordinate. - * \param y The new y coordinate. - * \param w The new width. - * \param h The new height. + * \param geom The new gometry. */ void -simplewindow_moveresize(simple_window_t *sw, int x, int y, int w, int h) +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); - if(sw->geometry.x != x || sw->geometry.y != y) + if(sw->geometry.x != geom.x || sw->geometry.y != geom.y) { - sw->geometry.x = moveresize_win_vals[0] = x; - sw->geometry.y = moveresize_win_vals[1] = y; + sw->geometry.x = moveresize_win_vals[0] = geom.x; + sw->geometry.y = moveresize_win_vals[1] = geom.y; mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; } - if(sw->geometry.width != w || sw->geometry.height != h) + if(sw->geometry.width != geom.width || sw->geometry.height != geom.height) { if(mask_vals) { - sw->geometry.width = moveresize_win_vals[2] = w; - sw->geometry.height = moveresize_win_vals[3] = h; + sw->geometry.width = moveresize_win_vals[2] = geom.width; + sw->geometry.height = moveresize_win_vals[3] = geom.height; } else { - sw->geometry.width = moveresize_win_vals[0] = w; - sw->geometry.height = moveresize_win_vals[1] = h; + sw->geometry.width = moveresize_win_vals[0] = geom.width; + sw->geometry.height = moveresize_win_vals[1] = geom.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, w, h); + xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, geom.width, geom.height); simplewindow_draw_context_update(sw, s); } @@ -272,4 +269,22 @@ simplewindow_border_color_set(simple_window_t *sw, const xcolor_t *color) 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); + } +} + // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/swindow.h b/swindow.h index 74daa8b0..ca558cd6 100644 --- a/swindow.h +++ b/swindow.h @@ -46,22 +46,23 @@ typedef struct simple_window_t } border; /** Draw context */ draw_context_t ctx; - /** Position */ - position_t position; + /** Orientation */ + orientation_t orientation; } simple_window_t; void simplewindow_init(simple_window_t *s, - int, int16_t, int16_t, uint16_t, uint16_t, uint16_t, - position_t, const xcolor_t *, const xcolor_t *); + int, area_t, uint16_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 *, int, int, 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); /** Refresh the window content by copying its pixmap data to its window. * \param sw The simple window to refresh. @@ -72,6 +73,5 @@ simplewindow_refresh_pixmap(simple_window_t *sw) simplewindow_refresh_pixmap_partial(sw, 0, 0, sw->geometry.width, sw->geometry.height); } - #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/titlebar.c b/titlebar.c index c353e6dc..bc96f734 100644 --- a/titlebar.c +++ b/titlebar.c @@ -25,6 +25,7 @@ #include "client.h" #include "widget.h" #include "wibox.h" +#include "screen.h" extern awesome_t globalconf; @@ -60,38 +61,6 @@ client_getbytitlebarwin(xcb_window_t win) return NULL; } -/** Draw the titlebar content. - * \param c The client. - */ -void -titlebar_draw(client_t *c) -{ - if(!c || !c->titlebar || !c->titlebar->isvisible) - return; - - widget_render(c->titlebar->widgets, &c->titlebar->sw.ctx, - c->titlebar->sw.gc, c->titlebar->sw.pixmap, - c->screen, c->titlebar->position, - c->titlebar->sw.geometry.x, c->titlebar->sw.geometry.y, - c->titlebar); - - simplewindow_refresh_pixmap(&c->titlebar->sw); - - c->titlebar->need_update = false; -} - -/** Titlebar refresh function. - */ -void -titlebar_refresh(void) -{ - client_t *c; - - for(c = globalconf.clients; c; c = c->next) - if(c->titlebar && c->titlebar->need_update) - titlebar_draw(c); -} - void titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) { @@ -102,10 +71,7 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) default: return; case Top: - if(c->titlebar->geometry.width) - width = MAX(1, MIN(c->titlebar->geometry.width, geometry.width - 2 * c->titlebar->sw.border.width)); - else - width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); + width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: @@ -118,15 +84,12 @@ 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->geometry.height - 2 * c->titlebar->sw.border.width + c->border; + res->y = geometry.y - c->titlebar->sw.geometry.height - 2 * c->titlebar->sw.border.width + c->border; res->width = width; - res->height = c->titlebar->geometry.height; + res->height = c->titlebar->sw.geometry.height; break; case Bottom: - if(c->titlebar->geometry.width) - width = MAX(1, MIN(c->titlebar->geometry.width, geometry.width - 2 * c->titlebar->sw.border.width)); - else - width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); + width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: @@ -141,13 +104,10 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) res->x = geometry.x + x_offset; res->y = geometry.y + geometry.height + c->border; res->width = width; - res->height = c->titlebar->geometry.height; + res->height = c->titlebar->sw.geometry.height; break; case Left: - if(c->titlebar->geometry.width) - width = MAX(1, MIN(c->titlebar->geometry.width, geometry.height - 2 * c->titlebar->sw.border.width)); - else - width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); + width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: @@ -159,16 +119,13 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) y_offset = (geometry.height - width) / 2; break; } - res->x = geometry.x - c->titlebar->geometry.height + c->border; + res->x = geometry.x - c->titlebar->sw.geometry.width + c->border; res->y = geometry.y + y_offset; - res->width = c->titlebar->geometry.height; + res->width = c->titlebar->sw.geometry.width; res->height = width; break; case Right: - if(c->titlebar->geometry.width) - width = MAX(1, MIN(c->titlebar->geometry.width, geometry.height - 2 * c->titlebar->sw.border.width)); - else - width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); + width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: @@ -182,59 +139,12 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) } res->x = geometry.x + geometry.width + c->border; res->y = geometry.y + y_offset; - res->width = c->titlebar->geometry.height; + res->width = c->titlebar->sw.geometry.width; res->height = width; break; } } -/** Set client titlebar position. - * \param c The client. - */ -void -titlebar_init(client_t *c) -{ - int width = 0, height = 0; - area_t geom; - - /* already had a window? */ - if(c->titlebar->sw.window) - simplewindow_wipe(&c->titlebar->sw); - - switch(c->titlebar->position) - { - case Top: - case Bottom: - if(c->titlebar->geometry.width) - width = MIN(c->titlebar->geometry.width, c->geometry.width - 2 * c->titlebar->sw.border.width); - else - width = c->geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width; - height = c->titlebar->geometry.height; - break; - case Left: - case Right: - if(c->titlebar->geometry.width) - height = MIN(c->titlebar->geometry.width, c->geometry.height - 2 * c->titlebar->sw.border.width); - else - height = c->geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width; - width = c->titlebar->geometry.height; - break; - } - - titlebar_geometry_compute(c, c->geometry, &geom); - - simplewindow_init(&c->titlebar->sw, c->phys_screen, - geom.x, geom.y, geom.width, geom.height, - c->titlebar->border.width, c->titlebar->position, - &c->titlebar->colors.fg, &c->titlebar->colors.bg); - - simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color); - - client_need_arrange(c); - - c->titlebar->need_update = true; -} - /** Create a new titlebar (DEPRECATED). * \param L The Lua VM state. * \return The number of value pushed. @@ -263,7 +173,8 @@ titlebar_client_detach(client_t *c) { wibox_unref(&c->titlebar); simplewindow_wipe(&c->titlebar->sw); - c->titlebar->type = WIBOX_TYPE_NONE; + c->titlebar->type = WIBOX_TYPE_NORMAL; + c->titlebar->screen = SCREEN_UNDEF; c->titlebar = NULL; client_need_arrange(c); client_stack(); @@ -281,11 +192,44 @@ titlebar_client_attach(client_t *c, wibox_t *t) if(c && t) { + area_t wingeom; + /* check if titlebar is already on a client */ titlebar_client_detach(client_getbytitlebar(t)); + c->titlebar = wibox_ref(&t); t->type = WIBOX_TYPE_TITLEBAR; - titlebar_init(c); + t->screen = c->screen; + + switch(t->position) + { + case Floating: + t->position = Top; + case Top: + case Bottom: + if(!t->sw.geometry.height) + t->sw.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; + break; + } + + + titlebar_geometry_compute(c, c->geometry, &wingeom); + + simplewindow_init(&t->sw, c->phys_screen, + wingeom, 0, t->sw.orientation, + &t->sw.ctx.fg, &t->sw.ctx.bg); + simplewindow_border_color_set(&t->sw, &t->sw.border.color); + + t->need_update = true; + + if(t->isvisible) + xcb_map_window(globalconf.connection, t->sw.window); + client_need_arrange(c); client_stack(); } @@ -300,14 +244,15 @@ titlebar_client_attach(client_t *c, wibox_t *t) int luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok) { - size_t len; - const char *buf; client_t *c = NULL; - int i; - position_t position; switch(tok) { + position_t position; + int i; + size_t len; + const char *buf; + case A_TK_ALIGN: if((buf = luaL_checklstring(L, 3, &len))) titlebar->align = draw_align_fromstr(buf, len); @@ -316,23 +261,84 @@ 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) - titlebar->border.width = i; + simplewindow_border_width_set(&titlebar->sw, 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->border.color, buf, len))) - simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color); + if(xcolor_init_reply(xcolor_init_unchecked(&titlebar->sw.border.color, buf, len))) + simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->sw.border.color); return 0; case A_TK_POSITION: buf = luaL_checklstring(L, 3, &len); position = position_fromstr(buf, len); if(position != titlebar->position) { + switch(position) + { + case Left: + switch(titlebar->position) + { + int tmp; + case Left: + case Right: + break; + case Top: + case Bottom: + case Floating: + tmp = titlebar->sw.geometry.width; + titlebar->sw.geometry.width = titlebar->sw.geometry.height; + titlebar->sw.geometry.height = tmp; + break; + } + simplewindow_orientation_set(&titlebar->sw, North); + break; + case Right: + switch(titlebar->position) + { + int tmp; + case Left: + case Right: + break; + case Top: + case Bottom: + case Floating: + tmp = titlebar->sw.geometry.width; + titlebar->sw.geometry.width = titlebar->sw.geometry.height; + titlebar->sw.geometry.height = tmp; + break; + } + simplewindow_orientation_set(&titlebar->sw, South); + break; + case Top: + case Bottom: + case Floating: + switch(titlebar->position) + { + int tmp; + case Left: + case Right: + tmp = titlebar->sw.geometry.width; + titlebar->sw.geometry.width = titlebar->sw.geometry.height; + titlebar->sw.geometry.height = tmp; + break; + case Top: + case Bottom: + case Floating: + break; + } + simplewindow_orientation_set(&titlebar->sw, East); + break; + } titlebar->position = position; - c = client_getbytitlebar(titlebar); - titlebar_init(c); + if((c = client_getbytitlebar(titlebar))) + { + titlebar_update_geometry_floating(c); + /* call geometry hook for client because some like to + * set titlebar width in that hook, which make sense */ + hooks_property(c, "geometry"); + } } break; default: diff --git a/titlebar.h b/titlebar.h index 55288a9c..ec23ddaa 100644 --- a/titlebar.h +++ b/titlebar.h @@ -23,13 +23,12 @@ #define AWESOME_TITLEBAR_H #include "structs.h" +#include "wibox.h" client_t * client_getbytitlebar(wibox_t *); client_t * client_getbytitlebarwin(xcb_window_t); void titlebar_geometry_compute(client_t *, area_t, area_t *); -void titlebar_draw(client_t *); void titlebar_init(client_t *); -void titlebar_refresh(void); void titlebar_client_detach(client_t *); void titlebar_client_attach(client_t *, wibox_t *); @@ -119,22 +118,6 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t geometry) return geometry; } -/** Update the titlebar geometry for a floating client. - * \param c The client. - */ -static inline void -titlebar_update_geometry_floating(client_t *c) -{ - area_t geom; - - if(!c->titlebar) - return; - - titlebar_geometry_compute(c, c->geometry, &geom); - simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); - c->titlebar->need_update = true; -} - /** Update the titlebar geometry for a tiled client. * \param c The client. * \param geometry The geometry the client will receive. @@ -148,8 +131,16 @@ titlebar_update_geometry_tiled(client_t *c, area_t geometry) return; titlebar_geometry_compute(c, geometry, &geom); - simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); - c->titlebar->need_update = true; + wibox_moveresize(c->titlebar, geom); +} + +/** Update the titlebar geometry for a floating client. + * \param c The client. + */ +static inline void +titlebar_update_geometry_floating(client_t *c) +{ + return titlebar_update_geometry_tiled(c, c->geometry); } #endif diff --git a/wibox.c b/wibox.c index 6160066d..3788848d 100644 --- a/wibox.c +++ b/wibox.c @@ -1,5 +1,5 @@ /* - * wibox.c - statusbar functions + * wibox.c - wibox functions * * Copyright © 2008 Julien Danjou * @@ -21,9 +21,9 @@ #include "screen.h" #include "wibox.h" -#include "statusbar.h" #include "titlebar.h" #include "client.h" +#include "ewmh.h" extern awesome_t globalconf; @@ -31,15 +31,564 @@ DO_LUA_NEW(extern, wibox_t, wibox, "wibox", wibox_ref) DO_LUA_GC(wibox_t, wibox, "wibox", wibox_unref) DO_LUA_EQ(wibox_t, wibox, "wibox") +static void +wibox_move(wibox_t *wibox, int16_t x, int16_t y) +{ + if(wibox->sw.window) + simplewindow_move(&wibox->sw, 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) +{ + if(wibox->sw.window) + simplewindow_resize(&wibox->sw, width, height); + else + { + wibox->sw.geometry.width = width; + wibox->sw.geometry.height = height; + } + wibox->need_update = true; +} + +static void +wibox_setposition(wibox_t *wibox, position_t p) +{ + if(p != wibox->position) + { + switch((wibox->position = p)) + { + case Bottom: + case Top: + case Floating: + simplewindow_orientation_set(&wibox->sw, East); + break; + case Left: + simplewindow_orientation_set(&wibox->sw, North); + break; + case Right: + simplewindow_orientation_set(&wibox->sw, South); + break; + } + /* reset width/height to 0 */ + if(wibox->position != Floating) + wibox->sw.geometry.width = wibox->sw.geometry.height = 0; + + /* recompute position */ + wibox_position_update(wibox); + + /* reset all wibox position */ + wibox_array_t *w = &globalconf.screens[wibox->screen].wiboxes; + for(int i = 0; i < w->len; i++) + wibox_position_update(w->tab[i]); + + ewmh_update_workarea(screen_virttophys(wibox->screen)); + + wibox->need_update = true; + } +} + +/** Kick out systray windows. + * \param phys_screen Physical screen number. + */ +static void +wibox_systray_kickout(int phys_screen) +{ + xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); + + /* 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.screens[phys_screen].systray.window, + s->root, -512, -512); + + globalconf.screens[phys_screen].systray.parent = s->root; +} + +static void +wibox_systray_refresh(wibox_t *wibox) +{ + widget_node_t *systray; + + if(wibox->screen == SCREEN_UNDEF) + return; + + for(systray = wibox->widgets; systray; systray = systray->next) + if(systray->widget->type == systray_new) + { + uint32_t config_back[] = { wibox->sw.ctx.bg.pixel }; + uint32_t config_win_vals[4]; + uint32_t config_win_vals_off[2] = { -512, -512 }; + xembed_window_t *em; + position_t pos; + int phys_screen = wibox->sw.ctx.phys_screen; + + if(wibox->isvisible + && systray->widget->isvisible + && systray->area.width) + { + pos = wibox->position; + + /* Set background of the systray window. */ + xcb_change_window_attributes(globalconf.connection, + globalconf.screens[phys_screen].systray.window, + XCB_CW_BACK_PIXEL, config_back); + /* Map it. */ + xcb_map_window(globalconf.connection, globalconf.screens[phys_screen].systray.window); + /* Move it. */ + switch(wibox->position) + { + case Left: + config_win_vals[0] = systray->area.y; + config_win_vals[1] = wibox->sw.geometry.height - systray->area.x - systray->area.width; + config_win_vals[2] = systray->area.height; + config_win_vals[3] = systray->area.width; + break; + case Right: + config_win_vals[0] = systray->area.y; + config_win_vals[1] = systray->area.x; + config_win_vals[2] = systray->area.height; + config_win_vals[3] = systray->area.width; + break; + default: + config_win_vals[0] = systray->area.x; + config_win_vals[1] = systray->area.y; + config_win_vals[2] = systray->area.width; + config_win_vals[3] = systray->area.height; + break; + } + /* reparent */ + if(globalconf.screens[phys_screen].systray.parent != wibox->sw.window) + { + xcb_reparent_window(globalconf.connection, + globalconf.screens[phys_screen].systray.window, + wibox->sw.window, + config_win_vals[0], config_win_vals[1]); + globalconf.screens[phys_screen].systray.parent = wibox->sw.window; + } + xcb_configure_window(globalconf.connection, + globalconf.screens[phys_screen].systray.window, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH + | XCB_CONFIG_WINDOW_HEIGHT, + config_win_vals); + /* width = height = systray height */ + config_win_vals[2] = config_win_vals[3] = systray->area.height; + config_win_vals[0] = 0; + } + else + return wibox_systray_kickout(phys_screen); + + switch(pos) + { + case Left: + config_win_vals[1] = systray->area.width - config_win_vals[3]; + for(em = globalconf.embedded; em; em = em->next) + if(em->phys_screen == phys_screen) + { + if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) wibox->sw.geometry.y) + { + xcb_map_window(globalconf.connection, em->win); + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH + | XCB_CONFIG_WINDOW_HEIGHT, + config_win_vals); + config_win_vals[1] -= config_win_vals[3]; + } + else + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y, + config_win_vals_off); + } + break; + case Right: + config_win_vals[1] = 0; + for(em = globalconf.embedded; em; em = em->next) + if(em->phys_screen == phys_screen) + { + if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) wibox->sw.geometry.y + wibox->sw.geometry.width) + { + xcb_map_window(globalconf.connection, em->win); + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH + | XCB_CONFIG_WINDOW_HEIGHT, + config_win_vals); + config_win_vals[1] += config_win_vals[3]; + } + else + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y, + config_win_vals_off); + } + break; + case Floating: + case Top: + case Bottom: + config_win_vals[1] = 0; + for(em = globalconf.embedded; em; em = em->next) + 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->area) + wibox->sw.geometry.x) + { + xcb_map_window(globalconf.connection, em->win); + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH + | XCB_CONFIG_WINDOW_HEIGHT, + config_win_vals); + config_win_vals[0] += config_win_vals[2]; + } + else + xcb_configure_window(globalconf.connection, em->win, + XCB_CONFIG_WINDOW_X + | XCB_CONFIG_WINDOW_Y, + config_win_vals_off); + } + break; + } + break; + } +} + +/** Update the wibox position. It deletes every wibox resources and + * create them back. + * \param wibox The wibox. + */ +void +wibox_position_update(wibox_t *wibox) +{ + area_t area, wingeom = wibox->sw.geometry; + bool ignore = false; + + globalconf.screens[wibox->screen].need_arrange = true; + + area = screen_area_get(wibox->screen, NULL, + &globalconf.screens[wibox->screen].padding, true); + + /* Top and Bottom wibox_t have prio */ + for(int i = 0; i < globalconf.screens[wibox->screen].wiboxes.len; i++) + { + wibox_t *w = globalconf.screens[wibox->screen].wiboxes.tab[i]; + /* Ignore every wibox after me that is in the same position */ + if(wibox == w) + { + ignore = true; + continue; + } + else if((ignore && wibox->position == w->position) || !w->isvisible) + continue; + switch(w->position) + { + case Floating: + break; + case Left: + switch(wibox->position) + { + case Left: + area.x += wibox->sw.geometry.height; + break; + default: + break; + } + break; + case Right: + switch(wibox->position) + { + case Right: + area.x -= wibox->sw.geometry.height; + break; + default: + break; + } + break; + case Top: + switch(wibox->position) + { + case Top: + area.y += w->sw.geometry.height; + break; + case Left: + case Right: + area.height -= w->sw.geometry.height; + area.y += w->sw.geometry.height; + break; + default: + break; + } + break; + case Bottom: + switch(wibox->position) + { + case Bottom: + area.y -= w->sw.geometry.height; + break; + case Left: + case Right: + area.height -= w->sw.geometry.height; + break; + default: + break; + } + break; + } + } + + switch(wibox->position) + { + case Right: + wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : area.height; + wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : 1.5 * globalconf.font->height; + switch(wibox->align) + { + default: + wingeom.x = area.x + area.width - wingeom.width; + wingeom.y = area.y; + break; + case AlignRight: + wingeom.x = area.x + area.width - wingeom.width; + wingeom.y = area.y + area.height - wingeom.height; + break; + case AlignCenter: + wingeom.x = area.x + area.width - wingeom.width; + wingeom.y = (area.y + area.height - wingeom.height) / 2; + break; + } + break; + case Left: + wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : area.height; + wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : 1.5 * globalconf.font->height; + switch(wibox->align) + { + default: + wingeom.x = area.x; + wingeom.y = (area.y + area.height) - wingeom.height; + break; + case AlignRight: + wingeom.x = area.x; + wingeom.y = area.y; + break; + case AlignCenter: + wingeom.x = area.x; + wingeom.y = (area.y + area.height - wingeom.height) / 2; + } + break; + case Bottom: + wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height; + wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : area.width; + switch(wibox->align) + { + default: + wingeom.x = area.x; + wingeom.y = (area.y + area.height) - wingeom.height; + break; + case AlignRight: + wingeom.x = area.x + area.width - wingeom.width; + wingeom.y = (area.y + area.height) - wingeom.height; + break; + case AlignCenter: + wingeom.x = area.x + (area.width - wingeom.width) / 2; + wingeom.y = (area.y + area.height) - wingeom.height; + break; + } + break; + case Top: + wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height; + wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : area.width; + switch(wibox->align) + { + default: + wingeom.x = area.x; + wingeom.y = area.y; + break; + case AlignRight: + wingeom.x = area.x + area.width - wingeom.width; + wingeom.y = area.y; + break; + case AlignCenter: + wingeom.x = area.x + (area.width - wingeom.width) / 2; + wingeom.y = area.y; + break; + } + break; + case Floating: + break; + } + + /* same window size and position ? */ + if(wingeom.width != wibox->sw.geometry.width + || wingeom.height != wibox->sw.geometry.height) + wibox_resize(wibox, wingeom.width, wingeom.height); + + if(wingeom.x != wibox->sw.geometry.x + || wingeom.y != wibox->sw.geometry.y) + wibox_move(wibox, wingeom.x, wingeom.y); +} + +/** Get a wibox by its window. + * \param w The window id. + * \return A wibox if found, NULL otherwise. + */ +wibox_t * +wibox_getbywin(xcb_window_t w) +{ + for(int screen = 0; screen < globalconf.nscreen; screen++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) + { + wibox_t *s = globalconf.screens[screen].wiboxes.tab[i]; + if(s->sw.window == w) + return s; + } + + for(client_t *c = globalconf.clients; c; c = c->next) + if(c->titlebar && c->titlebar->sw.window == w) + return c->titlebar; + + return NULL; +} + +/** Draw a wibox. + * \param wibox The wibox to draw. + */ +static void +wibox_draw(wibox_t *wibox) +{ + if(wibox->isvisible) + { + widget_render(wibox->widgets, &wibox->sw.ctx, wibox->sw.gc, + wibox->sw.pixmap, + wibox->screen, wibox->sw.orientation, + wibox->sw.geometry.x, wibox->sw.geometry.y, + wibox); + simplewindow_refresh_pixmap(&wibox->sw); + + wibox->need_update = false; + } + + wibox_systray_refresh(wibox); +} + /** Refresh all wiboxes. */ void wibox_refresh(void) { - statusbar_refresh(); - titlebar_refresh(); + for(int screen = 0; screen < globalconf.nscreen; screen++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) + { + wibox_t *s = globalconf.screens[screen].wiboxes.tab[i]; + if(s->need_update) + wibox_draw(s); + } + + for(client_t *c = globalconf.clients; c; c = c->next) + if(c->titlebar && c->titlebar->need_update) + wibox_draw(c->titlebar); } +/** Set a wibox visible or not. + * \param wibox The wibox. + * \param v The visible value. + */ +static void +wibox_setvisible(wibox_t *wibox, bool v) +{ + if(v != wibox->isvisible) + { + if((wibox->isvisible = v)) + xcb_map_window(globalconf.connection, wibox->sw.window); + else + xcb_unmap_window(globalconf.connection, wibox->sw.window); + /* kick out systray if needed */ + wibox_systray_refresh(wibox); + + /* All the other wibox and ourselves need to be repositioned */ + wibox_array_t *w = &globalconf.screens[wibox->screen].wiboxes; + for(int i = 0; i < w->len; i++) + wibox_position_update(w->tab[i]); + } +} + +/** Remove a wibox from a screen. + * \param wibox Wibox to detach from screen. + */ +void +wibox_detach(wibox_t *wibox) +{ + if(wibox->screen != SCREEN_UNDEF) + { + bool v; + + /* save visible state */ + v = wibox->isvisible; + wibox->isvisible = false; + wibox_position_update(wibox); + /* restore position */ + wibox->isvisible = v; + + simplewindow_wipe(&wibox->sw); + + for(int i = 0; i < globalconf.screens[wibox->screen].wiboxes.len; i++) + if(globalconf.screens[wibox->screen].wiboxes.tab[i] == wibox) + { + wibox_array_take(&globalconf.screens[wibox->screen].wiboxes, i); + break; + } + globalconf.screens[wibox->screen].need_arrange = true; + wibox->screen = SCREEN_UNDEF; + wibox_unref(&wibox); + } +} + +/** Attach a wibox. + * \param wibox The wibox to attach. + * \param s The screen to attach the wibox to. + */ +void +wibox_attach(wibox_t *wibox, screen_t *s) +{ + int phys_screen = screen_virttophys(wibox->screen); + + wibox_detach(wibox); + + wibox->screen = s->index; + + wibox_array_append(&s->wiboxes, wibox_ref(&wibox)); + + /* compute x/y/width/height if not set */ + wibox_position_update(wibox); + + simplewindow_init(&wibox->sw, phys_screen, + wibox->sw.geometry, 0, wibox->sw.orientation, + &wibox->sw.ctx.fg, &wibox->sw.ctx.bg); + + wibox->need_update = true; + + if(wibox->isvisible) + xcb_map_window(globalconf.connection, wibox->sw.window); + + /* All the other wibox and ourselves need to be repositioned */ + for(int i = 0; i < s->wiboxes.len; i++) + wibox_position_update(s->wiboxes.tab[i]); + + ewmh_update_workarea(screen_virttophys(s->index)); +} + + /** Convert a wibox to a printable string. * \param L The Lua VM state. * @@ -59,7 +608,7 @@ luaA_wibox_tostring(lua_State *L) * * \luastack * \lparam A table with optionaly defined values: - * position, align, fg, bg, border_widht, border_color, width and height. + * position, align, fg, bg, border_width, border_color, width and height. * \lreturn A brand new wibox. */ int @@ -75,29 +624,28 @@ luaA_wibox_new(lua_State *L) w = p_new(wibox_t, 1); - w->colors.fg = globalconf.colors.fg; + w->sw.ctx.fg = globalconf.colors.fg; if((buf = luaA_getopt_lstring(L, 2, "fg", NULL, &len))) - reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.fg, buf, len); + reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.fg, buf, len); - w->colors.bg = globalconf.colors.bg; + w->sw.ctx.bg = globalconf.colors.bg; if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len))) - reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.bg, buf, len); + reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.bg, buf, len); - w->colors.bg = globalconf.colors.bg; - if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len))) - reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.bg, buf, len); + w->sw.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); buf = luaA_getopt_lstring(L, 2, "align", "left", &len); w->align = draw_align_fromstr(buf, len); - w->geometry.width = luaA_getopt_number(L, 2, "width", 0); - w->geometry.height = luaA_getopt_number(L, 2, "height", 0); - if(w->geometry.height <= 0) - /* 1.5 as default factor, it fits nice but no one knows why */ - w->geometry.height = 1.5 * globalconf.font->height; + w->sw.border.width = luaA_getopt_number(L, 2, "border_width", 0); + + w->sw.geometry.width = luaA_getopt_number(L, 2, "width", 0); + w->sw.geometry.height = luaA_getopt_number(L, 2, "height", 0); buf = luaA_getopt_lstring(L, 2, "position", "top", &len); - w->position = position_fromstr(buf, len); + wibox_setposition(w, position_fromstr(buf, len)); w->screen = SCREEN_UNDEF; w->isvisible = true; @@ -112,7 +660,6 @@ luaA_wibox_new(lua_State *L) * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack - * \lfield geometry Geometry table. * \lfield screen Screen number. * \lfield client The client attached to this titlebar. * \lfield border_width Border width. @@ -137,9 +684,6 @@ luaA_wibox_index(lua_State *L) { client_t *c; - case A_TK_GEOMETRY: - luaA_pusharea(L, (*wibox)->geometry); - break; case A_TK_VISIBLE: lua_pushboolean(L, (*wibox)->isvisible); break; @@ -154,19 +698,19 @@ luaA_wibox_index(lua_State *L) lua_pushnumber(L, (*wibox)->screen + 1); break; case A_TK_BORDER_WIDTH: - lua_pushnumber(L, (*wibox)->border.width); + lua_pushnumber(L, (*wibox)->sw.border.width); break; case A_TK_BORDER_COLOR: - luaA_pushcolor(L, &(*wibox)->border.color); + luaA_pushcolor(L, &(*wibox)->sw.border.color); break; case A_TK_ALIGN: lua_pushstring(L, draw_align_tostr((*wibox)->align)); break; case A_TK_FG: - luaA_pushcolor(L, &(*wibox)->colors.fg); + luaA_pushcolor(L, &(*wibox)->sw.ctx.fg); break; case A_TK_BG: - luaA_pushcolor(L, &(*wibox)->colors.bg); + luaA_pushcolor(L, &(*wibox)->sw.ctx.bg); break; case A_TK_POSITION: lua_pushstring(L, position_tostr((*wibox)->position)); @@ -174,6 +718,9 @@ luaA_wibox_index(lua_State *L) case A_TK_ONTOP: lua_pushboolean(L, (*wibox)->ontop); break; + case A_TK_ORIENTATION: + lua_pushstring(L, orientation_tostr((*wibox)->sw.orientation)); + break; default: return 0; } @@ -203,6 +750,49 @@ luaA_wibox_widgets(lua_State *L) return luaA_widget_get(L, (*wibox)->widgets); } +/* 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"); + + if(lua_gettop(L) == 2) + { + 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); + + switch((*wibox)->type) + { + case WIBOX_TYPE_TITLEBAR: + wibox_resize(*wibox, wingeom.width, wingeom.height); + break; + case WIBOX_TYPE_NORMAL: + if((*wibox)->position == Floating) + wibox_moveresize(*wibox, wingeom); + else if(wingeom.width != (*wibox)->sw.geometry.width + || wingeom.height != (*wibox)->sw.geometry.height) + { + wibox_resize(*wibox, wingeom.width, wingeom.height); + globalconf.screens[(*wibox)->screen].need_arrange = true; + } + break; + } + } + + return luaA_pusharea(L, (*wibox)->sw.geometry); +} + /** Wibox newindex. * \param L The Lua VM state. * \return The number of elements pushed on stack. @@ -221,44 +811,32 @@ 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)->colors.fg, buf, len))) - { - (*wibox)->sw.ctx.fg = (*wibox)->colors.fg; + if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->sw.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)->colors.bg, buf, len))) - { - (*wibox)->sw.ctx.bg = (*wibox)->colors.bg; + if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->sw.ctx.bg, buf, len))) (*wibox)->need_update = true; - } + break; + case A_TK_ALIGN: + buf = luaL_checklstring(L, 3, &len); + (*wibox)->align = draw_align_fromstr(buf, len); + wibox_position_update(*wibox); break; case A_TK_POSITION: switch((*wibox)->type) { case WIBOX_TYPE_TITLEBAR: return luaA_titlebar_newindex(L, *wibox, tok); - case WIBOX_TYPE_STATUSBAR: - return luaA_statusbar_newindex(L, *wibox, tok); - case WIBOX_TYPE_NONE: + case WIBOX_TYPE_NORMAL: if((buf = luaL_checklstring(L, 3, &len))) - (*wibox)->position = position_fromstr(buf, len); + wibox_setposition(*wibox, position_fromstr(buf, len)); break; } break; case A_TK_CLIENT: /* first detach */ - switch((*wibox)->type) - { - case WIBOX_TYPE_NONE: - case WIBOX_TYPE_TITLEBAR: - break; - case WIBOX_TYPE_STATUSBAR: - statusbar_detach(*wibox); - break; - } if(lua_isnil(L, 3)) titlebar_client_detach(client_getbytitlebar(*wibox)); else @@ -268,22 +846,20 @@ luaA_wibox_newindex(lua_State *L) } break; case A_TK_SCREEN: - switch((*wibox)->type) - { - case WIBOX_TYPE_NONE: - case WIBOX_TYPE_STATUSBAR: - break; - case WIBOX_TYPE_TITLEBAR: - titlebar_client_detach(client_getbytitlebar(*wibox)); - break; - } if(lua_isnil(L, 3)) - statusbar_detach(*wibox); + { + wibox_detach(*wibox); + titlebar_client_detach(client_getbytitlebar(*wibox)); + } else { int screen = luaL_checknumber(L, 3) - 1; luaA_checkscreen(screen); - statusbar_attach(*wibox, &globalconf.screens[screen]); + if(screen != (*wibox)->screen) + { + titlebar_client_detach(client_getbytitlebar(*wibox)); + wibox_attach(*wibox, &globalconf.screens[screen]); + } } break; case A_TK_ONTOP: @@ -294,30 +870,35 @@ luaA_wibox_newindex(lua_State *L) client_stack(); } break; + case A_TK_ORIENTATION: + if((buf = luaL_checklstring(L, 3, &len))) + { + simplewindow_orientation_set(&(*wibox)->sw, orientation_fromstr(buf, len)); + (*wibox)->need_update = true; + } + break; case A_TK_VISIBLE: b = luaA_checkboolean(L, 3); if(b != (*wibox)->isvisible) - { - (*wibox)->isvisible = b; switch((*wibox)->type) { - case WIBOX_TYPE_STATUSBAR: - statusbar_position_update(*wibox); + case WIBOX_TYPE_NORMAL: + wibox_setvisible(*wibox, b); break; - case WIBOX_TYPE_NONE: case WIBOX_TYPE_TITLEBAR: + (*wibox)->isvisible = b; + globalconf.screens[(*wibox)->screen].need_arrange = true; break; } - } + break; + case A_TK_GEOMETRY: break; default: switch((*wibox)->type) { case WIBOX_TYPE_TITLEBAR: return luaA_titlebar_newindex(L, *wibox, tok); - case WIBOX_TYPE_STATUSBAR: - return luaA_statusbar_newindex(L, *wibox, tok); - case WIBOX_TYPE_NONE: + case WIBOX_TYPE_NORMAL: break; } } @@ -333,6 +914,7 @@ const struct luaL_reg awesome_wibox_methods[] = const struct luaL_reg awesome_wibox_meta[] = { { "widgets", luaA_wibox_widgets }, + { "geometry", luaA_wibox_geometry }, { "__index", luaA_wibox_index }, { "__newindex", luaA_wibox_newindex }, { "__gc", luaA_wibox_gc }, diff --git a/wibox.h b/wibox.h index 3c59aa1e..d736c7e9 100644 --- a/wibox.h +++ b/wibox.h @@ -1,5 +1,5 @@ /* - * statusbar.h - statusbar functions header + * wibox.h - wibox functions header * * Copyright © 2007-2008 Julien Danjou * @@ -32,6 +32,10 @@ void wibox_refresh(void); int luaA_wibox_new(lua_State *); int luaA_wibox_userdata_new(lua_State *, wibox_t *); +void wibox_position_update(wibox_t *); +wibox_t * wibox_getbywin(xcb_window_t); +void wibox_detach(wibox_t *); +void wibox_attach(wibox_t *, screen_t *); static inline void wibox_delete(wibox_t **wibox) @@ -41,6 +45,16 @@ wibox_delete(wibox_t **wibox) p_delete(wibox); } +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; +} + DO_RCNT(wibox_t, wibox, wibox_delete) ARRAY_FUNCS(wibox_t *, wibox, wibox_unref) diff --git a/widget.c b/widget.c index e3f2b78d..d7b24af4 100644 --- a/widget.c +++ b/widget.c @@ -38,9 +38,9 @@ DO_LUA_EQ(widget_t, widget, "widget") #include "widgetgen.h" /** Compute offset for drawing the first pixel of a widget. - * \param barwidth The statusbar width. + * \param barwidth The wibox width. * \param widgetwidth The widget width. - * \param alignment The widget alignment on statusbar. + * \param alignment The widget alignment on wibox. * \return The x coordinate to draw at. */ int @@ -86,17 +86,17 @@ widget_common_button(widget_node_t *w, * \param wnode The list of widgets. * \param ctx The draw context where to render. * \param rotate_px The rotate pixmap: where to rotate and render the final + * pixmap when the object oritation is not east. * \param screen The logical screen used to render. - * \param position The object position. + * \param orientation The object orientation. * \param x The x coordinates of the object. * \param y The y coordinates of the object. - * pixmap when the object position is right or left. * \param object The wibox. * \todo Remove GC. */ void widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_pixmap_t rotate_px, - int screen, position_t position, + int screen, orientation_t orientation, int x, int y, wibox_t *object) { xcb_pixmap_t rootpix; @@ -121,9 +121,9 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_ if(prop_r->value_len && (data = xcb_get_property_value(prop_r)) && (rootpix = *(xcb_pixmap_t *) data)) - switch(position) + switch(orientation) { - case Left: + case North: draw_rotate(ctx, rootpix, ctx->pixmap, s->width_in_pixels, s->height_in_pixels, @@ -132,7 +132,7 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_ y + ctx->width, - x); break; - case Right: + case South: draw_rotate(ctx, rootpix, ctx->pixmap, s->width_in_pixels, s->height_in_pixels, @@ -141,7 +141,7 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_ - y, x + ctx->height); break; - default: + case East: xcb_copy_area(globalconf.connection, rootpix, rotate_px, gc, x, y, @@ -168,21 +168,21 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_ if(w->widget->align == AlignFlex && w->widget->isvisible) left += w->widget->draw(ctx, screen, w, left, (left + right), object); - switch(position) + switch(orientation) { - case Right: + case South: draw_rotate(ctx, ctx->pixmap, rotate_px, ctx->width, ctx->height, ctx->height, ctx->width, M_PI_2, ctx->height, 0); break; - case Left: + case North: draw_rotate(ctx, ctx->pixmap, rotate_px, ctx->width, ctx->height, ctx->height, ctx->width, - M_PI_2, 0, ctx->width); break; - default: + case East: break; } } @@ -207,21 +207,21 @@ widget_common_new(widget_t *widget) void widget_invalidate_cache(int screen, int flags) { - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; + wibox_t *wibox = globalconf.screens[screen].wiboxes.tab[i]; widget_node_t *widget; - for(widget = statusbar->widgets; widget; widget = widget->next) + for(widget = wibox->widgets; widget; widget = widget->next) if(widget->widget->cache_flags & flags) { - statusbar->need_update = true; + wibox->need_update = true; break; } } } -/** Set a statusbar needs update because it has widget, or redraw a titlebar. +/** Set a wibox needs update because it has widget, or redraw a titlebar. * \todo Probably needs more optimization. * \param widget The widget to look for. */ @@ -233,15 +233,15 @@ widget_invalidate_bywidget(widget_t *widget) client_t *c; for(screen = 0; screen < globalconf.nscreen; screen++) - for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++) { - wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; + wibox_t *wibox = globalconf.screens[screen].wiboxes.tab[i]; - if(!statusbar->need_update) - for(witer = statusbar->widgets; witer; witer = witer->next) + if(!wibox->need_update) + for(witer = wibox->widgets; witer; witer = witer->next) if(witer->widget == widget) { - statusbar->need_update = true; + wibox->need_update = true; break; } } diff --git a/widget.h b/widget.h index d842484d..3d9b2ced 100644 --- a/widget.h +++ b/widget.h @@ -31,7 +31,7 @@ void widget_invalidate_cache(int, int); int widget_calculate_offset(int, int, int, int); void widget_common_new(widget_t *); -void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, position_t, int, int, wibox_t *); +void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, orientation_t, int, int, wibox_t *); void luaA_widget_set(lua_State *, int, wibox_t *, widget_node_t **); int luaA_widget_get(lua_State *, widget_node_t *); diff --git a/widgets/systray.c b/widgets/systray.c index 35bebd9e..073373d6 100644 --- a/widgets/systray.c +++ b/widgets/systray.c @@ -73,7 +73,7 @@ systray_draw(draw_context_t *ctx, break; } - /* set statusbar orientation */ + /* set wibox orientation */ /** \todo stop setting that property on each redraw */ xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, globalconf.screens[p->sw.ctx.phys_screen].systray.window, diff --git a/widgets/tasklist.c b/widgets/tasklist.c index b04fe4f0..9d14d375 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -123,7 +123,7 @@ tasklist_draw_item(draw_context_t *ctx, draw_parser_data_init(&pdata); /* Actually look for the proper background color, since - * otherwise the background statusbar color is used instead */ + * otherwise the background wibox color is used instead */ if(draw_text_markup_expand(&pdata, odata->client_labels.tab[i].label, odata->client_labels.tab[i].label_len))