From be2bfdcfc56242da5c1e15fa585118d3a39bcca2 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 11 Aug 2008 17:14:02 +0200 Subject: [PATCH] screen: introduce screen objects Signed-off-by: Julien Danjou --- awesome.c | 6 ++ awesomerc.lua.in | 2 +- common/tokenize.gperf | 2 + ewmh.c | 6 +- layouts/fibonacci.c | 2 +- layouts/magnifier.c | 2 +- layouts/max.c | 6 +- layouts/tile.c | 2 +- lib/awful.lua.in | 8 +-- lua.c | 111 ++----------------------------- mouse.c | 6 +- placement.c | 4 +- screen.c | 147 ++++++++++++++++++++++++++++++++++++++++-- screen.h | 2 +- statusbar.c | 2 +- structs.h | 4 ++ 16 files changed, 181 insertions(+), 131 deletions(-) diff --git a/awesome.c b/awesome.c index 52aff132..e83343a1 100644 --- a/awesome.c +++ b/awesome.c @@ -399,6 +399,12 @@ main(int argc, char **argv) /* init screens struct */ globalconf.screens_info = screensinfo_new(globalconf.connection); globalconf.screen_focus = globalconf.screens = p_new(screen_t, globalconf.screens_info->nscreen); + /* \todo stop duplicating this */ + for(screen_nbr = 0; screen_nbr < globalconf.screens_info->nscreen; screen_nbr++) + { + globalconf.screens[screen_nbr].index = screen_nbr; + globalconf.screens[screen_nbr].geometry = globalconf.screens_info->geometry[screen_nbr]; + } /* init default font and colors */ globalconf.font = draw_font_new(globalconf.connection, globalconf.default_screen, "sans 8"); diff --git a/awesomerc.lua.in b/awesomerc.lua.in index 9ae833a8..1e35e228 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -47,7 +47,7 @@ floatapps = } -- Applications to be moved to a pre-defined tag by class or instance. --- Use the screen and workspace indices. +-- Use the screen and tags indices. apptags = { -- ["Firefox"] = { screen = 1, tag = 2 }, diff --git a/common/tokenize.gperf b/common/tokenize.gperf index 3bf316f9..a06ab1c2 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -42,6 +42,7 @@ nmaster name on opacity +padding pid plot_data_add plot_properties_set @@ -71,4 +72,5 @@ visible vertical widgets width +workarea yes diff --git a/ewmh.c b/ewmh.c index 54607342..c9f1f772 100644 --- a/ewmh.c +++ b/ewmh.c @@ -213,7 +213,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, + area_t geom = screen_area_get(&globalconf.screens[phys_screen].geometry, globalconf.screens[phys_screen].statusbar, &globalconf.screens[phys_screen].padding); @@ -287,7 +287,9 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) } else if(set == _NET_WM_STATE_ADD) { - geometry = screen_area_get(c->screen, NULL, &globalconf.screens[c->screen].padding); + geometry = screen_area_get(&globalconf.screens[c->screen].geometry, + NULL, + &globalconf.screens[c->screen].padding); /* save geometry */ c->m_geometry = c->geometry; c->wasfloating = c->isfloating; diff --git a/layouts/fibonacci.c b/layouts/fibonacci.c index 87b25864..f206c635 100644 --- a/layouts/fibonacci.c +++ b/layouts/fibonacci.c @@ -32,7 +32,7 @@ layout_fibonacci(int screen, int shape) int n = 0, i = 0; client_t *c; area_t geometry, area; - geometry = area = screen_area_get(screen, + geometry = area = screen_area_get(&globalconf.screens[screen].geometry, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); diff --git a/layouts/magnifier.c b/layouts/magnifier.c index a1ce0f4a..97439086 100644 --- a/layouts/magnifier.c +++ b/layouts/magnifier.c @@ -32,7 +32,7 @@ layout_magnifier(int screen) int n = 0; client_t *c, *focus; tag_t **curtags = tags_get_current(screen); - area_t geometry, area = screen_area_get(screen, + area_t geometry, area = screen_area_get(&globalconf.screens[screen].geometry, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); diff --git a/layouts/max.c b/layouts/max.c index f8446c74..a26c1e4b 100644 --- a/layouts/max.c +++ b/layouts/max.c @@ -30,9 +30,9 @@ void layout_max(int screen) { client_t *c; - area_t area = screen_area_get(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); + area_t area = screen_area_get(&globalconf.screens[screen].geometry, + globalconf.screens[screen].statusbar, + &globalconf.screens[screen].padding); for(c = globalconf.clients; c; c = c->next) if(IS_TILED(c, screen)) diff --git a/layouts/tile.c b/layouts/tile.c index 165fc711..9088160b 100644 --- a/layouts/tile.c +++ b/layouts/tile.c @@ -42,7 +42,7 @@ _tile(int screen, const position_t position) client_t *c; tag_t **curtags = tags_get_current(screen); - area = screen_area_get(screen, + area = screen_area_get(&globalconf.screens[screen].geometry, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); diff --git a/lib/awful.lua.in b/lib/awful.lua.in index 2cb01d9f..5a547c21 100644 --- a/lib/awful.lua.in +++ b/lib/awful.lua.in @@ -278,13 +278,13 @@ function client.moveresize(x, y, w, h, c) sel.coords = coords end ---- Maximize a client to use the full workspace area. +--- Maximize a client to use the full workarea. -- @param c A client, or the focused one if nil. function client.maximize(c) local sel = c or capi.client.focus_get() if sel then sel.floating = true - local ws = capi.screen.workspace_get(sel.screen) + local ws = capi.screen[sel.screen].workarea ws.width = ws.width - 2 * sel.border_width ws.height = ws.height - 2 * sel.border_width sel.coords = ws @@ -305,7 +305,7 @@ function screen.focus(i) local c = client.focus.history.get(s, 0) if c then c:focus_set() end -- Move the mouse on the screen - capi.mouse.coords = capi.screen.coords_get(s) + capi.mouse.coords = capi.screen[s].coords end --- Compare 2 tables of tags. @@ -532,7 +532,7 @@ function client.movetoscreen(c, s) end if s > sc then s = 1 elseif s < 1 then s = sc end sel.screen = s - capi.mouse.coords = capi.screen.coords_get(s) + capi.mouse.coords = capi.screen[s].coords sel:focus_set() end end diff --git a/lua.c b/lua.c index 13c0144d..396bd52c 100644 --- a/lua.c +++ b/lua.c @@ -51,6 +51,8 @@ extern awesome_t globalconf; extern const struct luaL_reg awesome_keygrabber_lib[]; extern const struct luaL_reg awesome_mouse_methods[]; extern const struct luaL_reg awesome_mouse_meta[]; +extern const struct luaL_reg awesome_screen_methods[]; +extern const struct luaL_reg awesome_screen_meta[]; extern const struct luaL_reg awesome_client_methods[]; extern const struct luaL_reg awesome_client_meta[]; extern const struct luaL_reg awesome_titlebar_methods[]; @@ -126,101 +128,6 @@ luaA_restart(lua_State *L __attribute__ ((unused))) return 0; } -/** Set the screen padding. This can be used to define margin around the - * screen. awesome will not use this area. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * - * \luastack - * \lparam A screen number. - * \lparam A table with a list of margin for `right', `left', `top' and - * `bottom'. - */ -static int -luaA_screen_padding_set(lua_State *L) -{ - int screen = luaL_checknumber(L, 1) - 1; - - luaA_checkscreen(screen); - - luaA_checktable(L, 2); - - globalconf.screens[screen].padding.right = luaA_getopt_number(L, 2, "right", 0); - globalconf.screens[screen].padding.left = luaA_getopt_number(L, 2, "left", 0); - globalconf.screens[screen].padding.top = luaA_getopt_number(L, 2, "top", 0); - globalconf.screens[screen].padding.bottom = luaA_getopt_number(L, 2, "bottom", 0); - - ewmh_update_workarea(screen_virttophys(screen)); - - return 0; -} - -/** Get the screen count. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * - * \luastack - * \lreturn The screen count, at least 1. - */ -static int -luaA_screen_count(lua_State *L) -{ - lua_pushnumber(L, globalconf.screens_info->nscreen); - return 1; -} - -/** Return screen coordinates. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lparam A screen number. - * \lreturn A table with the screen geometry: x, y, width and height. - */ -static int -luaA_screen_coords_get(lua_State *L) -{ - int screen = luaL_checknumber(L, 1) - 1; - luaA_checkscreen(screen); - lua_newtable(L); - lua_pushnumber(L, globalconf.screens_info->geometry[screen].x); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, globalconf.screens_info->geometry[screen].y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, globalconf.screens_info->geometry[screen].width); - lua_setfield(L, -2, "width"); - lua_pushnumber(L, globalconf.screens_info->geometry[screen].height); - lua_setfield(L, -2, "height"); - return 1; -} - -/** Return the geometry of the workspace, i.e. where applications live. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lparam A screen number. - * \lreturn A table with the workspace geometry. - */ -static int -luaA_screen_workspace_get(lua_State *L) -{ - area_t g; - int screen = luaL_checknumber(L, 1) - 1; - luaA_checkscreen(screen); - g = screen_area_get(screen, - globalconf.screens[screen].statusbar, - &globalconf.screens[screen].padding); - lua_newtable(L); - lua_pushnumber(L, g.x); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, g.y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, g.width); - lua_setfield(L, -2, "width"); - lua_pushnumber(L, g.height); - lua_setfield(L, -2, "height"); - return 1; -} - /** Set the function called each time a client gets focus. This function is * called with the client object as argument. * \param L The Lua VM state. @@ -531,14 +438,6 @@ luaA_init(void) { "colors_set", luaA_colors_set }, { NULL, NULL } }; - static const struct luaL_reg awesome_screen_lib[] = - { - { "padding_set", luaA_screen_padding_set }, - { "coords_get", luaA_screen_coords_get }, - { "workspace_get", luaA_screen_workspace_get }, - { "count", luaA_screen_count }, - { NULL, NULL } - }; static const struct luaL_reg awesome_hooks_lib[] = { { "focus", luaA_hooks_focus }, @@ -562,9 +461,6 @@ luaA_init(void) /* Export awesome lib */ luaL_register(L, "awesome", awesome_lib); - /* Export screen lib */ - luaL_register(L, "screen", awesome_screen_lib); - /* Export hooks lib */ luaL_register(L, "hooks", awesome_hooks_lib); @@ -574,6 +470,9 @@ luaA_init(void) /* Export otable lib */ luaA_openlib(L, "otable", otable_methods, otable_meta); + /* Export screen */ + luaA_openlib(L, "screen", awesome_screen_methods, awesome_screen_meta); + /* Export mouse */ luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta); diff --git a/mouse.c b/mouse.c index f13fa75c..363d9a5d 100644 --- a/mouse.c +++ b/mouse.c @@ -130,7 +130,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap) client_t *snapper; area_t snapper_geometry; area_t screen_geometry = - screen_area_get(c->screen, + screen_area_get(&globalconf.screens[c->screen].geometry, globalconf.screens[c->screen].statusbar, &globalconf.screens[c->screen].padding); @@ -720,7 +720,7 @@ mouse_client_resize_tiled(client_t *c) tag = tags_get_current(c->screen)[0]; layout = tag->layout; - area = screen_area_get(tag->screen, + area = screen_area_get(&globalconf.screens[tag->screen].geometry, globalconf.screens[tag->screen].statusbar, &globalconf.screens[tag->screen].padding); @@ -823,7 +823,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, + area = screen_area_get(&globalconf.screens[tag->screen].geometry, globalconf.screens[tag->screen].statusbar, &globalconf.screens[tag->screen].padding); diff --git a/placement.c b/placement.c index 55f56e54..7cde51a5 100644 --- a/placement.c +++ b/placement.c @@ -39,7 +39,7 @@ placement_fix_offscreen(area_t geometry, int screen, int border) { area_t screen_geometry; - screen_geometry = screen_area_get(screen, + screen_geometry = screen_area_get(&globalconf.screens[screen].geometry, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); @@ -73,7 +73,7 @@ placement_smart(client_t *c) int i; area_array_init(&areas); - screen_geometry = screen_area_get(c->screen, + screen_geometry = screen_area_get(&globalconf.screens[c->screen].geometry, globalconf.screens[c->screen].statusbar, &globalconf.screens[c->screen].padding); diff --git a/screen.c b/screen.c index b10a8862..17ad2e27 100644 --- a/screen.c +++ b/screen.c @@ -25,9 +25,9 @@ #include #include "screen.h" +#include "ewmh.h" #include "tag.h" #include "client.h" -#include "layouts/floating.h" extern awesome_t globalconf; @@ -38,9 +38,9 @@ extern awesome_t globalconf; * \return The screen area. */ area_t -screen_area_get(int screen, statusbar_t *statusbar, padding_t *padding) +screen_area_get(area_t *geometry, statusbar_t *statusbar, padding_t *padding) { - area_t area = globalconf.screens_info->geometry[screen]; + area_t area = *geometry; statusbar_t *sb; /* make padding corrections */ @@ -149,8 +149,10 @@ screen_client_moveto(client_t *c, int new_screen, bool doresize) area_t new_geometry, new_f_geometry; new_f_geometry = c->f_geometry; - to = screen_area_get(c->screen, NULL, NULL); - from = screen_area_get(old_screen, NULL, NULL); + to = screen_area_get(&globalconf.screens[c->screen].geometry, + NULL, NULL); + from = screen_area_get(&globalconf.screens[old_screen].geometry, + NULL, NULL); /* compute new coords in new screen */ new_f_geometry.x = (c->f_geometry.x - from.x) + to.x; @@ -213,4 +215,139 @@ screen_client_moveto(client_t *c, int new_screen, bool doresize) } } +/** Screen module. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + * \lfield coords The screen coordinates. + * \lfield padding The screen padding. + */ +static int +luaA_screen_module_index(lua_State *L) +{ + int screen = luaL_checknumber(L, 2) - 1; + + luaA_checkscreen(screen); + lua_pushlightuserdata(L, &globalconf.screens[screen]); + return luaA_settype(L, "screen"); +} + +/** A screen. + * \param L The Lua VM state. + * \luastack + * \lfield padding The screen padding. A table with top, right, left and bottom + * keys and values in pixel. + * \lfield coords The screen coordinates. Immutable. + * \lfield workarea The screen workarea, i.e. without statusbar. + */ +static int +luaA_screen_index(lua_State *L) +{ + size_t len; + const char *buf = luaL_checklstring(L, 2, &len); + screen_t *s; + area_t g; + + s = lua_touserdata(L, 1); + + switch(a_tokenize(buf, len)) + { + case A_TK_PADDING: + lua_newtable(L); + lua_pushnumber(L, s->padding.right); + lua_setfield(L, -2, "right"); + lua_pushnumber(L, s->padding.left); + lua_setfield(L, -2, "left"); + lua_pushnumber(L, s->padding.top); + lua_setfield(L, -2, "top"); + lua_pushnumber(L, s->padding.bottom); + lua_setfield(L, -2, "bottom"); + break; + case A_TK_COORDS: + /* \todo lua_pushgeometry() ? */ + lua_newtable(L); + lua_pushnumber(L, s->geometry.x); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, s->geometry.y); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, s->geometry.width); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, s->geometry.height); + lua_setfield(L, -2, "height"); + break; + case A_TK_WORKAREA: + g = screen_area_get(&s->geometry, s->statusbar, &s->padding); + lua_newtable(L); + lua_pushnumber(L, g.x); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, g.y); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, g.width); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, g.height); + lua_setfield(L, -2, "height"); + break; + default: + return 0; + } + + return 1; +} + +static int +luaA_screen_newindex(lua_State *L) +{ + size_t len; + const char *buf = luaL_checklstring(L, 2, &len); + screen_t *s; + + s = lua_touserdata(L, 1); + + switch(a_tokenize(buf, len)) + { + case A_TK_PADDING: + luaA_checktable(L, 3); + s->padding.right = luaA_getopt_number(L, 2, "right", 0); + s->padding.left = luaA_getopt_number(L, 2, "left", 0); + s->padding.top = luaA_getopt_number(L, 2, "top", 0); + s->padding.bottom = luaA_getopt_number(L, 2, "bottom", 0); + + ewmh_update_workarea(screen_virttophys(s->index)); + + break; + default: + return 0; + } + + return 0; +} + +/** Get the screen count. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * + * \luastack + * \lreturn The screen count, at least 1. + */ +static int +luaA_screen_count(lua_State *L) +{ + lua_pushnumber(L, globalconf.screens_info->nscreen); + return 1; +} + +const struct luaL_reg awesome_screen_methods[] = +{ + { "count", luaA_screen_count }, + { "__index", luaA_screen_module_index }, + { NULL, NULL } +}; + +const struct luaL_reg awesome_screen_meta[] = +{ + { "__index", luaA_screen_index }, + { "__newindex", luaA_screen_newindex }, + { NULL, NULL } +}; + // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/screen.h b/screen.h index 4d6dda61..bad1b150 100644 --- a/screen.h +++ b/screen.h @@ -26,7 +26,7 @@ #define SCREEN_UNDEF (-1) -area_t screen_area_get(int, statusbar_t *, padding_t *); +area_t screen_area_get(area_t *, statusbar_t *, padding_t *); area_t display_area_get(int, statusbar_t *, padding_t *); int screen_virttophys(int); void screen_client_moveto(client_t *, int, bool); diff --git a/statusbar.c b/statusbar.c index 20c19b83..cdf4ce78 100644 --- a/statusbar.c +++ b/statusbar.c @@ -223,7 +223,7 @@ statusbar_position_update(statusbar_t *statusbar) if(statusbar->position == Off) return; - area = screen_area_get(statusbar->screen, + area = screen_area_get(&globalconf.screens[statusbar->screen].geometry, NULL, &globalconf.screens[statusbar->screen].padding); diff --git a/structs.h b/structs.h index da2df571..2597185b 100644 --- a/structs.h +++ b/structs.h @@ -358,6 +358,10 @@ typedef struct typedef struct { + /** Screen index */ + int index; + /** Screen geometry */ + area_t geometry; /** true if we need to arrange() */ bool need_arrange; /** Tag list */