From c3c20c4f8e8e76e4108e83f71bebdec135784c84 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 1 Dec 2008 16:26:41 +0100 Subject: [PATCH] client: move floating state handling to Lua Signed-off-by: Julien Danjou --- awesomerc.lua.in | 6 +-- client.c | 70 ++++---------------------------- client.h | 16 -------- event.c | 30 +++++--------- lib/awful/client.lua.in | 61 +++++++++++++++++++++++----- lib/awful/layout/suit/max.lua.in | 2 +- lib/awful/mouse.lua.in | 10 ++--- lib/awful/placement.lua.in | 2 +- lib/awful/widget.lua.in | 3 +- property.c | 2 +- screen.c | 15 +++---- structs.h | 4 -- 12 files changed, 87 insertions(+), 134 deletions(-) diff --git a/awesomerc.lua.in b/awesomerc.lua.in index e196aeaec..b3958e9bb 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -229,7 +229,7 @@ keybinding({ modkey, "Shift" }, "j", function () awful.client.swap.byidx(1) end) keybinding({ modkey, "Shift" }, "k", function () awful.client.swap.byidx(-1) end):add() keybinding({ modkey, "Control" }, "j", function () awful.screen.focus(1) end):add() keybinding({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end):add() -keybinding({ modkey, "Control" }, "space", awful.client.togglefloating):add() +keybinding({ modkey, "Control" }, "space", awful.client.floating.toggle):add() keybinding({ modkey, "Control" }, "Return", function () if client.focus then client.focus:swap(awful.client.getmaster()) end end):add() keybinding({ modkey }, "o", awful.client.movetoscreen):add() keybinding({ modkey }, "Tab", awful.client.focus.history.previous):add() @@ -345,9 +345,9 @@ awful.hooks.manage.register(function (c) local cls = c.class local inst = c.instance if floatapps[cls] then - c.floating = floatapps[cls] + awful.client.floating.set(cls, floatapps[cls]) elseif floatapps[inst] then - c.floating = floatapps[inst] + awful.client.floating.set(cls, floatapps[inst]) end -- Check application->screen/tag mappings. diff --git a/client.c b/client.c index 243da82ff..fc9f59cbb 100644 --- a/client.c +++ b/client.c @@ -51,7 +51,7 @@ client_loadprops(client_t * c, screen_t *screen) ssize_t len; tag_array_t *tags = &screen->tags; char *prop = NULL; - xcb_get_property_cookie_t floating_q, fullscreen_q; + xcb_get_property_cookie_t fullscreen_q; xcb_get_property_reply_t *reply; void *data; @@ -60,9 +60,6 @@ client_loadprops(client_t * c, screen_t *screen) return false; /* Send the GetProperty requests which will be processed later */ - floating_q = xcb_get_property_unchecked(globalconf.connection, false, c->win, - _AWESOME_FLOATING, CARDINAL, 0, 1); - fullscreen_q = xcb_get_property_unchecked(globalconf.connection, false, c->win, _AWESOME_FULLSCREEN, CARDINAL, 0, 1); @@ -76,13 +73,6 @@ client_loadprops(client_t * c, screen_t *screen) p_delete(&prop); - /* check for floating */ - reply = xcb_get_property_reply(globalconf.connection, floating_q, NULL); - - if(reply && reply->value_len && (data = xcb_get_property_value(reply))) - client_setfloating(c, *(bool *) data); - p_delete(&reply); - /* check for fullscreen */ reply = xcb_get_property_reply(globalconf.connection, fullscreen_q, NULL); @@ -308,8 +298,7 @@ typedef enum LAYER_IGNORE, LAYER_DESKTOP, LAYER_BELOW, - LAYER_TILE, - LAYER_FLOAT, + LAYER_NORMAL, LAYER_ABOVE, LAYER_FULLSCREEN, LAYER_ONTOP, @@ -332,8 +321,6 @@ client_layer_translator(client_t *c) return LAYER_ABOVE; else if(c->isbelow) return LAYER_BELOW; - else if(c->isfloating || c->ismaxhoriz || c->ismaxvert) - return LAYER_FLOAT; /* check for transient attr */ if(c->transient_for) @@ -350,15 +337,12 @@ client_layer_translator(client_t *c) case WINDOW_TYPE_MENU: case WINDOW_TYPE_TOOLBAR: case WINDOW_TYPE_UTILITY: - return LAYER_FLOAT; + return LAYER_ABOVE; default: break; } - if(client_isfixed(c)) - return LAYER_FLOAT; - - return LAYER_TILE; + return LAYER_NORMAL; } /** Restack clients. @@ -466,10 +450,10 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, /* Initial values */ c->win = w; - c->geometry.x = c->geometries.floating.x = wgeom->x; - c->geometry.y = c->geometries.floating.y = wgeom->y; - c->geometry.width = c->geometries.floating.width = wgeom->width; - c->geometry.height = c->geometries.floating.height = wgeom->height; + c->geometry.x = wgeom->x; + c->geometry.y = wgeom->y; + c->geometry.width = wgeom->width; + c->geometry.height = wgeom->height; client_setborder(c, wgeom->border_width); if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie))) c->icon = image_ref(&icon); @@ -662,12 +646,6 @@ client_resize(client_t *c, area_t geometry, bool hints) c->geometry.width = values[2] = geometry.width; c->geometry.height = values[3] = geometry.height; - /* save the floating geometry if the window is floating but not - * maximized */ - if(client_isfloating(c) - && !(c->isfullscreen || c->ismaxvert || c->ismaxhoriz)) - c->geometries.floating = geometry; - titlebar_update_geometry(c); /* The idea is to give a client a resize even when banned. */ @@ -693,31 +671,6 @@ client_resize(client_t *c, area_t geometry, bool hints) } } -/** Set a client floating. - * \param c The client. - * \param floating Set floating, or not. - * \param layer Layer to put the floating window onto. - */ -void -client_setfloating(client_t *c, bool floating) -{ - if(c->isfloating != floating - && (c->type == WINDOW_TYPE_NORMAL)) - { - if((c->isfloating = floating)) - if(!c->isfullscreen) - client_resize(c, c->geometries.floating, false); - client_need_arrange(c); - client_stack(); - xcb_change_property(globalconf.connection, - XCB_PROP_MODE_REPLACE, - c->win, _AWESOME_FLOATING, CARDINAL, 8, 1, - &c->isfloating); - /* execute hook */ - hooks_property(c, "floating"); - } -} - /** Set a client minimized, or not. * \param c The client. * \param s Set or not the client minimized. @@ -1458,9 +1411,6 @@ luaA_client_newindex(lua_State *L) window_opacity_set((*c)->win, d); } break; - case A_TK_FLOATING: - client_setfloating(*c, luaA_checkboolean(L, 3)); - break; case A_TK_STICKY: client_setsticky(*c, luaA_checkboolean(L, 3)); break; @@ -1515,7 +1465,6 @@ luaA_client_newindex(lua_State *L) * \lfield minimize Define it the client must be iconify, i.e. only visible in * taskbar. * \lfield icon_path Path to the icon used to identify. - * \lfield floating True always floating. * \lfield honorsizehints Honor size hints, i.e. respect size ratio. * \lfield border_width The client border width. * \lfield border_color The client border color. @@ -1669,9 +1618,6 @@ luaA_client_index(lua_State *L) else return 0; break; - case A_TK_FLOATING: - lua_pushboolean(L, client_isfloating(*c)); - break; case A_TK_ONTOP: lua_pushboolean(L, (*c)->isontop); break; diff --git a/client.h b/client.h index 70702ea18..daef52242 100644 --- a/client.h +++ b/client.h @@ -55,7 +55,6 @@ void client_resize(client_t *, area_t, bool); void client_unmanage(client_t *); void client_saveprops_tags(client_t *); void client_kill(client_t *); -void client_setfloating(client_t *, bool); void client_setsticky(client_t *, bool); void client_setabove(client_t *, bool); void client_setbelow(client_t *, bool); @@ -109,21 +108,6 @@ client_isfixed(client_t *c) && c->maxw == c->minw && c->maxh == c->minh); } -/** Check if a client is floating. - * \param c A client. - * \return A boolean value, true if the client is floating. - */ -static inline bool -client_isfloating(client_t *c) -{ - return (c->type != WINDOW_TYPE_NORMAL - || c->isfloating - || c->isfullscreen - || c->ismaxhoriz - || c->ismaxvert - || client_isfixed(c)); -} - /** Returns true if a client is tagged * with one of the tags of the specified screen and is not hidden. * \param c The client to check. diff --git a/event.c b/event.c index 17ce7a7b9..899e2b351 100644 --- a/event.c +++ b/event.c @@ -266,26 +266,16 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), if(geometry.x != c->geometry.x || geometry.y != c->geometry.y || geometry.width != c->geometry.width || geometry.height != c->geometry.height) { - if(client_isfloating(c)) - { - client_resize(c, geometry, false); - if(client_hasstrut(c)) - /* All the wiboxes (may) need to be repositioned */ - 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]; - wibox_position_update(s); - } - } - else - { - client_need_arrange(c); - /* If we do not resize the client, at least tell it that it - * has its new configuration. That fixes at least - * gnome-terminal */ - window_configure(c->win, c->geometry, c->border); - } + client_resize(c, geometry, false); + if(client_hasstrut(c)) + /* All the wiboxes (may) need to be repositioned */ + 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]; + wibox_position_update(s); + } + client_need_arrange(c); } else window_configure(c->win, geometry, c->border); diff --git a/lib/awful/client.lua.in b/lib/awful/client.lua.in index 4139d7d44..5ad971f23 100644 --- a/lib/awful/client.lua.in +++ b/lib/awful/client.lua.in @@ -5,7 +5,6 @@ --------------------------------------------------------------------------- -- Grab environment we need -local hooks = require("awful.hooks") local util = require("awful.util") local tag = require("awful.tag") local pairs = pairs @@ -19,7 +18,9 @@ local capi = client = client, mouse = mouse, screen = screen, + hooks = hooks } +local hooks = require("awful.hooks") --- Client module for awful module("awful.client") @@ -29,12 +30,14 @@ local data = {} data.focus = {} data.urgent = {} data.marked = {} +data.floating = otable() -- Urgent functions urgent = {} focus = {} focus.history = {} swap = {} +floating = {} -- User hooks hooks.user.create('marked') @@ -193,7 +196,7 @@ function tiled(screen) local tclients = {} -- Remove floating clients for k, c in pairs(clients) do - if not c.floating then + if not floating.get(c) then table.insert(tclients, c) end end @@ -426,15 +429,6 @@ function toggletag(target, c) end end ---- Toggle the floating status of a client. --- @param c Optional client, the focused one if not set. -function togglefloating(c) - local sel = c or capi.client.focus - if sel then - sel.floating = not sel.floating - end -end - --- Move a client to a screen. Default is next screen, cycling. -- @param c The client to move. -- @param s The screen number, default to current + 1. @@ -525,6 +519,49 @@ function getmarked() return t end +--- Set a client floating state. +-- Floating client are not handled by tiling layouts. +-- @param c A client. +-- @param state True or false. +function floating.set(c, s) + local c = c or capi.client.focus + if c and data.floating[c] ~= s then + data.floating[c] = s + capi.hooks.arrange()(c.screen) + capi.hooks.property()(c, "floating") + end +end + +--- Get a client floating state. +-- @param c A client. +-- @return True or false. Note that some windows might be floating even if you +-- did not set them manually. For example, windows with a type different than +-- normal. +function floating.get(c) + local c = c or capi.client.focus + if c then + if data.floating[c] ~= nil then + return data.floating[c] + end + return (c.type ~= "normal" + or c.fullscreen + or c.maximized_vertical + or c.maximized_horizontal) + end +end + +--- Toggle the floating state of a client. +-- @param c A client. +function floating.toggle(c) + floating.set(c, not floating.get(c)) +end + +--- Remove the floating information on a client. +-- @param c The client. +function floating.delete(c) + data.floating[c] = nil +end + -- Register standards hooks hooks.focus.register(focus.history.add) hooks.unmanage.register(focus.history.delete) @@ -533,4 +570,6 @@ hooks.property.register(urgent.add) hooks.focus.register(urgent.delete) hooks.unmanage.register(urgent.delete) +hooks.unmanage.register(floating.delete) + -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/lib/awful/layout/suit/max.lua.in b/lib/awful/layout/suit/max.lua.in index 73c40e031..cc95cf582 100644 --- a/lib/awful/layout/suit/max.lua.in +++ b/lib/awful/layout/suit/max.lua.in @@ -26,7 +26,7 @@ local function fmax(screen, fs) end for k, c in pairs(client.visible(screen)) do - if not c.floating then + if not client.floating.get(c) then area.width = area.width - 2 * c.border_width area.height = area.height - 2 * c.border_width c:fullgeometry(area) diff --git a/lib/awful/mouse.lua.in b/lib/awful/mouse.lua.in index 85a08235f..217f90831 100644 --- a/lib/awful/mouse.lua.in +++ b/lib/awful/mouse.lua.in @@ -109,18 +109,18 @@ function client.move(c, snap) for k, v in ipairs(mouse.buttons) do if v then local lay = layout.get(c.screen) - if lay == layout.suit.floating or c.floating then + if lay == layout.suit.floating or aclient.floating.get(c) then local x = mouse.x - dist_x local y = mouse.y - dist_y c:fullgeometry(client.snap(c, snap, x, y)) - if layout.get(c.screen) ~= layout.suit.floating and not c.floating then + if layout.get(c.screen) ~= layout.suit.floating and not aclient.floating.get(c) then hooks.property.register(ug) end elseif lay ~= layout.suit.magnifier then c.screen = capi.mouse.screen if layout.get(c.screen) ~= layout.suit.floating then local c_u_m = capi.mouse.client_under_pointer() - if c_u_m and not c_u_m.floating then + if c_u_m and not aclient.floating.get(c_u_m) then if c_u_m ~= c then c:swap(c_u_m) end @@ -265,7 +265,7 @@ local function client_resize_floating(c, corner) for k, v in ipairs(mouse.buttons) do if v then -- Ignore screen changes - if not c.floating + if not aclient.floating.get(c) and capi.mouse.screen ~= c.screen then return true end @@ -332,7 +332,7 @@ function client.resize(c, corner) local lay = layout.get(c.screen) - if lay == layout.suit.floating or c.floating then + if lay == layout.suit.floating or aclient.floating.get(c) then return client_resize_floating(c, corner) elseif lay == layout.suit.tile or lay == layout.suit.tile.left diff --git a/lib/awful/placement.lua.in b/lib/awful/placement.lua.in index 3ef70bd7f..f75fed58e 100644 --- a/lib/awful/placement.lua.in +++ b/lib/awful/placement.lua.in @@ -128,7 +128,7 @@ function no_overlap(c) local geometry = c:geometry() local fullgeometry = c:fullgeometry() for i, cl in pairs(cls) do - if cl ~= c and (cl.floating or layout == layout.suit.floating) then + if cl ~= c and (client.get.floating(cl) or layout == layout.suit.floating) then areas = area_remove(areas, cl:fullgeometry()) end end diff --git a/lib/awful/widget.lua.in b/lib/awful/widget.lua.in index ff848302b..6c280c925 100644 --- a/lib/awful/widget.lua.in +++ b/lib/awful/widget.lua.in @@ -21,6 +21,7 @@ local util = require("awful.util") local hooks = require("awful.hooks") local beautiful = require("beautiful") local menu = require("awful.menu") +local client = require("awful.client") --- Widget module for awful module("awful.widget") @@ -277,7 +278,7 @@ local function widget_tasklist_label_common(c, args) local bg = nil local text = "" local name - if c.floating and floating_icon then + if client.floating.get(c) and floating_icon then text = text.."" end if c.minimized then diff --git a/property.c b/property.c index be41b9c26..a10c88209 100644 --- a/property.c +++ b/property.c @@ -63,7 +63,7 @@ property_handle_wm_transient_for(void *data, { client_t *c = client_getbywin(window); - if(c && !client_isfloating(c)) + if(c) property_update_wm_transient_for(c, reply); return 0; diff --git a/screen.c b/screen.c index d6ff24abd..2e7cdd929 100644 --- a/screen.c +++ b/screen.c @@ -326,11 +326,11 @@ screen_client_moveto(client_t *c, int new_screen, bool dotag, bool doresize) tag_client(c, new_tags->tab[i]); } - /* resize the windows if it's floating */ + /* move and resize the windows */ if(doresize && old_screen != c->screen) { area_t new_geometry, new_f_geometry; - new_f_geometry = c->geometries.floating; + new_f_geometry = c->geometry; to = screen_area_get(c->screen, NULL, NULL, false); @@ -338,8 +338,8 @@ screen_client_moveto(client_t *c, int new_screen, bool dotag, bool doresize) NULL, NULL, false); /* compute new coords in new screen */ - new_f_geometry.x = (c->geometries.floating.x - from.x) + to.x; - new_f_geometry.y = (c->geometries.floating.y - from.y) + to.y; + new_f_geometry.x = (c->geometry.x - from.x) + to.x; + new_f_geometry.y = (c->geometry.y - from.y) + to.y; /* check that new coords are still in the screen */ if(new_f_geometry.width > to.width) @@ -385,13 +385,10 @@ screen_client_moveto(client_t *c, int new_screen, bool dotag, bool doresize) client_resize(c, new_geometry, false); } - /* if floating, move to this new coords */ - else if(client_isfloating(c)) - client_resize(c, new_f_geometry, false); - /* otherwise just register them */ + /* move to this new coords */ else { - c->geometries.floating = new_f_geometry; + client_resize(c, new_f_geometry, false); if(wasvisible) globalconf.screens[old_screen].need_arrange = true; client_need_arrange(c); diff --git a/structs.h b/structs.h index f23b78727..5dcb93b21 100644 --- a/structs.h +++ b/structs.h @@ -155,8 +155,6 @@ struct client_t area_t geometry; struct { - /** Client floating geometry. */ - area_t floating; /** Client geometry when (un)fullscreen */ area_t fullscreen; /** Client geometry when (un)-max */ @@ -175,8 +173,6 @@ struct client_t bool issticky; /** Has urgency hint */ bool isurgent; - /** true if the window is floating */ - bool isfloating; /** True if the client is hidden */ bool ishidden; /** True if the client is minimized */