From 04c757322c079a8b9f13a51d0dc4c37e5a5b7965 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 10 Nov 2019 20:47:43 -0500 Subject: [PATCH] client: Turn `rc.lua` logic into a new `request::border` signal. The default `rc.lua` was using the focus/unfocus signals to set the border color along with `awful.rules`. This logic block was no longer aligned with the rest of `rc.lua` since it was the only place where `beautiful` variables where only used by `rc.lua`. On top of this, the new request handler also has extra contexts for the urgent and floating/maximixed use cases. So it can be used by themes to implement much smarter borders than just focus based ones. They were previously limited by the fact most of the (un-monkey-patchable) logic was in `rc.lua`. Note that this commit also shuffle the awful.rules order between the titlebar and the border and changes the tests accordignly. After some consideration, I came to the conclusion the previous behavior was bogus and the fact that the placement tests required to know about the titlebar height is simply a proof of that. The change was required in this commit because since the border is no longer in the default rules, a new buggy edge case surfaced. --- awesomerc.lua | 9 +- docs/05-awesomerc.md.lua | 5 - docs/89-NEWS.md | 8 + docs/common/client_theme.ldoc | 492 ++++++++++++++++++++++++++++ lib/awful/client.lua | 52 ++- lib/awful/client/urgent.lua | 17 +- lib/awful/ewmh.lua | 153 +++++++++ lib/awful/menu.lua | 4 +- lib/awful/placement.lua | 2 +- lib/awful/rules.lua | 12 +- lib/awful/tooltip.lua | 2 +- lib/awful/widget/calendar_popup.lua | 2 +- lib/beautiful/init.lua | 17 +- lib/naughty/core.lua | 2 +- lib/naughty/notification.lua | 2 +- lib/wibox/init.lua | 23 +- objects/client.c | 42 +-- objects/window.c | 6 +- tests/examples/shims/client.lua | 2 +- tests/examples/shims/drawin.lua | 2 +- tests/test-awful-placement.lua | 20 +- tests/test-awful-rules.lua | 4 +- tests/test-focus.lua | 4 +- tests/test-geometry.lua | 4 +- themes/default/theme.lua | 10 +- themes/gtk/theme.lua | 6 +- themes/sky/theme.lua | 6 +- themes/xresources/theme.lua | 6 +- themes/zenburn/theme.lua | 6 +- 29 files changed, 810 insertions(+), 110 deletions(-) create mode 100644 docs/common/client_theme.ldoc diff --git a/awesomerc.lua b/awesomerc.lua index f60186497..13959fb10 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -441,9 +441,7 @@ awful.rules.rules = { -- @DOC_GLOBAL_RULE@ -- All clients will match this rule. { rule = { }, - properties = { border_width = beautiful.border_width, - border_color = beautiful.border_normal, - focus = awful.client.focus.filter, + properties = { focus = awful.client.focus.filter, raise = true, screen = awful.screen.preferred, placement = awful.placement.no_overlap+awful.placement.no_offscreen @@ -540,8 +538,3 @@ end) client.connect_signal("mouse::enter", function(c) c:activate { context = "mouse_enter", raise = false } end) - --- @DOC_BORDER@ -client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) -client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) - diff --git a/docs/05-awesomerc.md.lua b/docs/05-awesomerc.md.lua index a1d0c5bd0..dee0ab161 100644 --- a/docs/05-awesomerc.md.lua +++ b/docs/05-awesomerc.md.lua @@ -221,11 +221,6 @@ sections.DOC_CSD_TITLEBARS = [[ See `client.requests_no_titlebar` for more details. ]] - -sections.DOC_BORDER = [[ -   -]] - -- Ask ldoc to generate links local function add_links(line) diff --git a/docs/89-NEWS.md b/docs/89-NEWS.md index 73595bf79..7089f99fa 100644 --- a/docs/89-NEWS.md +++ b/docs/89-NEWS.md @@ -62,6 +62,14 @@ This document was last updated at commit v4.3-197-g9085ed631. objects. If you used these low level APIs to add keys and buttons dynamically, please migrate your code to the corresponding `:append_` and `:remove_` client methods. + * `beautiful.border_width` and `beautiful.border_color` are now honored even + when the part related to borders is removed from `rc.lua`. Set them + appropriately in your theme or disconnect the default `request::border` + handler. + * The order by which the client rules compute the geometry have changed + slightly. The border is now applied before the titlebar offset. This should + not affect most users unless you had mitigated the bug it fixes by adding + the titlebar offset in your rules. # Awesome window manager framework version 4.3 changes diff --git a/docs/common/client_theme.ldoc b/docs/common/client_theme.ldoc new file mode 100644 index 000000000..762138577 --- /dev/null +++ b/docs/common/client_theme.ldoc @@ -0,0 +1,492 @@ +*/ + + +/** + * The fallback border color when the client is floating. + * + * @beautiful beautiful.border_color_floating + * @param color + * @see request::border + * @see beautiful.border_color_floating_active + * @see beautiful.border_color_floating_normal + * @see beautiful.border_color_floating_urgent + * @see beautiful.border_color_floating_new + */ + +/** + * The fallback border color when the client is mazimized. + * + * @beautiful beautiful.border_color_mazimized + * @param color + * @see request::border + * @see beautiful.border_color_maximized_active + * @see beautiful.border_color_maximized_normal + * @see beautiful.border_color_maximized_urgent + * @see beautiful.border_color_maximized_new + */ + +/** + * The border color when the client is active. + * + * @beautiful beautiful.border_color_active + * @param color + * @see request::border + */ + +/** + * The border color when the client is not active. + * + * @beautiful beautiful.border_color_normal + * @param color + * @see request::border + */ + +/** + * The border color when the client has the urgent property set. + * + * @beautiful beautiful.border_color_urgent + * @param color + * @see request::border + */ + +/** + * The border color when the client is not active and new. + * + * @beautiful beautiful.border_color_new + * @param color + * @see request::border + */ + +/** + * The border color when the (floating) client is active. + * + * @beautiful beautiful.border_color_floating_active + * @param color + * @see request::border + */ + +/** + * The border color when the (floating) client is not active. + * + * @beautiful beautiful.border_color_floating_normal + * @param color + * @see request::border + */ + +/** + * The border color when the (floating) client has the urgent property set. + * + * @beautiful beautiful.border_color_floating_urgent + * @param color + * @see request::border + */ + +/** + * The border color when the (floating) client is not active and new. + * + * @beautiful beautiful.border_color_floating_new + * @param color + * @see request::border + */ + +/** + * The border color when the (maximized) client is active. + * + * @beautiful beautiful.border_color_maximized_active + * @param color + * @see request::border + */ + +/** + * The border color when the (maximized) client is not active. + * + * @beautiful beautiful.border_color_maximized_normal + * @param color + * @see request::border + */ + +/** + * The border color when the (maximized) client has the urgent property set. + * + * @beautiful beautiful.border_color_maximized_urgent + * @param color + * @see request::border + */ + +/** + * The border color when the (maximized) client is not active and new. + * + * @beautiful beautiful.border_color_maximized_new + * @param color + * @see request::border + */ + +/** + * The border color when the (fullscreen) client is active. + * + * @beautiful beautiful.border_color_fullscreen_active + * @param color + * @see request::border + */ + +/** + * The border color when the (fullscreen) client is not active. + * + * @beautiful beautiful.border_color_fullscreen_normal + * @param color + * @see request::border + */ + +/** + * The border color when the (fullscreen) client has the urgent property set. + * + * @beautiful beautiful.border_color_fullscreen_urgent + * @param color + * @see request::border + */ + +/** + * The border color when the (fullscreen) client is not active and new. + * + * @beautiful beautiful.border_color_fullscreen_new + * @param color + * @see request::border + */ + +/** + * The fallback border width when nothing else is set. + * + * @beautiful beautiful.border_width + * @param integer + * @see request::border + * @see beautiful.border_width_floating + * @see beautiful.border_width_mazimized + * @see beautiful.border_width_floating_active + * @see beautiful.border_width_floating_normal + * @see beautiful.border_width_floating_urgent + * @see beautiful.border_width_floating_new + * @see beautiful.border_width_maximized_active + * @see beautiful.border_width_maximized_normal + * @see beautiful.border_width_maximized_urgent + * @see beautiful.border_width_maximized_new + */ + +/** + * The fallback border width when the client is floating. + * + * @beautiful beautiful.border_width_floating + * @param integer + * @see request::border + * @see beautiful.border_width_floating_active + * @see beautiful.border_width_floating_normal + * @see beautiful.border_width_floating_urgent + * @see beautiful.border_width_floating_new + */ + +/** + * The fallback border width when the client is mazimized. + * + * @beautiful beautiful.border_width_mazimized + * @param integer + * @see request::border + * @see beautiful.border_width_maximized_active + * @see beautiful.border_width_maximized_normal + * @see beautiful.border_width_maximized_urgent + * @see beautiful.border_width_maximized_new + */ + +/** + * The client border width for the normal clients. + * + * @beautiful beautiful.border_width_normal + * @param integer + * @see request::border + */ + +/** + * The client border width for the active client. + * + * @beautiful beautiful.border_width_active + * @param integer + * @see request::border + */ + +/** + * The client border width for the urgent clients. + * + * @beautiful beautiful.border_width_urgent + * @param integer + * @see request::border + */ + +/** + * The client border width for the new clients. + * + * @beautiful beautiful.border_width_new + * @param integer + * @see request::border + */ + +/** + * The client border width for the normal floating clients. + * + * @beautiful beautiful.border_width_floating_normal + * @param integer + * @see request::border + */ + +/** + * The client border width for the active floating client. + * + * @beautiful beautiful.border_width_floating_active + * @param integer + * @see request::border + */ + +/** + * The client border width for the urgent floating clients. + * + * @beautiful beautiful.border_width_floating_urgent + * @param integer + * @see request::border + */ + +/** + * The client border width for the new floating clients. + * + * @beautiful beautiful.border_width_floating_new + * @param integer + * @see request::border + */ + +/** + * The client border width for the normal maximized clients. + * + * @beautiful beautiful.border_width_maximized_normal + * @param integer + * @see request::border + */ + +/** + * The client border width for the active maximized client. + * + * @beautiful beautiful.border_width_maximized_active + * @param integer + * @see request::border + */ + +/** + * The client border width for the urgent maximized clients. + * + * @beautiful beautiful.border_width_maximized_urgent + * @param integer + * @see request::border + */ + +/** + * The client border width for the new maximized clients. + * + * @beautiful beautiful.border_width_maximized_new + * @param integer + * @see request::border + */ + +/** + * The client border width for the normal fullscreen clients. + * + * @beautiful beautiful.border_width_fullscreen_normal + * @param integer + * @see request::border + */ + +/** + * The client border width for the active fullscreen client. + * + * @beautiful beautiful.border_width_fullscreen_active + * @param integer + * @see request::border + */ + +/** + * The client border width for the urgent fullscreen clients. + * + * @beautiful beautiful.border_width_fullscreen_urgent + * @param integer + * @see request::border + */ + +/** + * The client border width for the new fullscreen clients. + * + * @beautiful beautiful.border_width_fullscreen_new + * @param integer + * @see request::border + */ + +/** + * The client opacity for the normal clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_normal + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the active client. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_active + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the urgent clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_urgent + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the new clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_new + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the normal floating clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_floating_normal + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the active floating client. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_floating_active + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the urgent floating clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_floating_urgent + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the new floating clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_floating_new + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the normal maximized clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_maximized_normal + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the active maximized client. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_maximized_active + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the urgent maximized clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_maximized_urgent + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the new maximized clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_maximized_new + * @param[opt=1] number + * @see request::border + */ +/** + * The client opacity for the normal fullscreen clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_fullscreen_normal + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the active fullscreen client. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_fullscreen_active + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the urgent fullscreen clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_fullscreen_urgent + * @param[opt=1] number + * @see request::border + */ + +/** + * The client opacity for the new fullscreen clients. + * + * A number between 0 and 1. + * + * @beautiful beautiful.opacity_fullscreen_new + * @param[opt=1] number + * @see request::border + */ + +/** + * The marked clients border color. + * Note that only solid colors are supported. + * @beautiful beautiful.border_marked + * @param color + */ + +/* diff --git a/lib/awful/client.lua b/lib/awful/client.lua index d713d2ee1..530415400 100644 --- a/lib/awful/client.lua +++ b/lib/awful/client.lua @@ -688,6 +688,12 @@ function client.object.set_floating(c, s) c:geometry(client.property.get(c, "floating_geometry")) end c.screen = scr + + if s then + c:emit_signal("request::border", "floating", {}) + else + c:emit_signal("request::border", (c.active and "" or "in").."active", {}) + end end end @@ -834,6 +840,17 @@ local function update_implicitly_floating(c) if cur ~= new then client.property.set(c, "_implicitly_floating", new) c:emit_signal("property::floating") + + -- Don't send the border signals as they would be sent twice (with this + -- one having the wrong context). There is some `property::` signal + -- sent before `request::manage`. + if client.property.get(c, "_border_init") then + if cur then + c:emit_signal("request::border", "floating", {}) + else + c:emit_signal("request::border", (c.active and "" or "in").."active", {}) + end + end end end @@ -1389,6 +1406,19 @@ function client.object.set_shape(self, shape) set_shape(self) end +-- Proxy those properties to decorate their accessors with an extra flag to +-- define when they are set by the user. This allows to "manage" the value of +-- those properties internally until they are manually overridden. +for _, prop in ipairs { "border_width", "border_color", "opacity" } do + client.object["get_"..prop] = function(self) + return self["_"..prop] + end + client.object["set_"..prop] = function(self, value) + self._private["_user_"..prop] = true + self["_"..prop] = value + end +end + --- Activate (focus) a client. -- -- This method is the correct way to focus a client. While @@ -1531,7 +1561,9 @@ function client.object.set_active(c, value) end end --- Register standards signals +capi.client.connect_signal("property::active", function(c) + c:emit_signal("request::border", (c.active and "" or "in").."active", {}) +end) --- The last geometry when client was floating. -- @signal property::floating_geometry @@ -1547,6 +1579,21 @@ end --- The client unmarked signal. -- @deprecatedsignal unmarked +--- Emited when the border client might need to be update. +-- +-- The context are: +-- +-- * **added**: When a new client is created. +-- * **active**: When client gains the focus (or stop being urgent/floating +-- but is active). +-- * **inactive**: When client loses the focus (or stop being urgent/floating +-- and is not active. +-- * **urgent**: When a client becomes urgent. +-- * **floating**: When the floating or maximization state changes. +-- +-- @signal request::border +-- @see awful.ewmh.update_border + -- Add clients during startup to focus history. -- This used to happen through ewmh.activate, but that only handles visible -- clients now. @@ -1561,6 +1608,9 @@ capi.client.connect_signal("request::manage", function (c) if awesome.startup then client.focus.history.add(c) end + + client.property.set(c, "_border_init", true) + c:emit_signal("request::border", "added", {}) end) capi.client.connect_signal("request::unmanage", client.focus.history.delete) diff --git a/lib/awful/client/urgent.lua b/lib/awful/client/urgent.lua index 265a25fb3..f8f188284 100644 --- a/lib/awful/client/urgent.lua +++ b/lib/awful/client/urgent.lua @@ -63,9 +63,24 @@ end -- @client c The client object. -- @param prop The property which is updated. function urgent.add(c, prop) - if type(c) == "client" and prop == "urgent" and c.urgent then + assert( + c.urgent ~= nil, + "`awful.client.urgent.add()` takes a client as first parameter" + ) + + if prop == "urgent" and c.urgent then table.insert(data, c) end + + if c.urgent then + c:emit_signal("request::border", "urgent", {}) + else + c:emit_signal( + "request::border", + (c.active and "" or "in").."active", + {} + ) + end end --- Remove client from urgent stack. diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index 842a05508..b8a2d3b78 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -17,6 +17,7 @@ local asuit = require("awful.layout.suit") local beautiful = require("beautiful") local alayout = require("awful.layout") local atag = require("awful.tag") +local gdebug = require("gears.debug") local ewmh = { generic_activate_filters = {}, @@ -453,6 +454,158 @@ ewmh.add_activate_filter(function(c) end end, "mouse_enter") +--- The default client `request::border` handler. +-- +-- To replace this handler with your own, use: +-- +-- client.disconnect_signal("request::border", awful.ewmh.update_border) +-- +-- The default implementation chooses from dozens beautiful theme variables +-- depending if the client is tiled, floating, maximized and then from its state +-- (urgent, new, active, normal) +-- +-- @signalhandler awful.ewmh.update_border +-- @usebeautiful beautiful.border_color_active +-- @usebeautiful beautiful.border_color_normal +-- @usebeautiful beautiful.border_color_new +-- @usebeautiful beautiful.border_color_urgent +-- @usebeautiful beautiful.border_color_floating +-- @usebeautiful beautiful.border_color_floating_active +-- @usebeautiful beautiful.border_color_floating_normal +-- @usebeautiful beautiful.border_color_floating_new +-- @usebeautiful beautiful.border_color_floating_urgent +-- @usebeautiful beautiful.border_color_maximized +-- @usebeautiful beautiful.border_color_maximized_active +-- @usebeautiful beautiful.border_color_maximized_normal +-- @usebeautiful beautiful.border_color_maximized_new +-- @usebeautiful beautiful.border_color_maximized_urgent +-- @usebeautiful beautiful.border_color_fullscreen +-- @usebeautiful beautiful.border_color_fullscreen_active +-- @usebeautiful beautiful.border_color_fullscreen_normal +-- @usebeautiful beautiful.border_color_fullscreen_new +-- @usebeautiful beautiful.border_color_fullscreen_urgent +-- @usebeautiful beautiful.border_width_active +-- @usebeautiful beautiful.border_width_normal +-- @usebeautiful beautiful.border_width_new +-- @usebeautiful beautiful.border_width_urgent +-- @usebeautiful beautiful.border_width_floating +-- @usebeautiful beautiful.border_width_floating_active +-- @usebeautiful beautiful.border_width_floating_normal +-- @usebeautiful beautiful.border_width_floating_new +-- @usebeautiful beautiful.border_width_floating_urgent +-- @usebeautiful beautiful.border_width_maximized +-- @usebeautiful beautiful.border_width_maximized_active +-- @usebeautiful beautiful.border_width_maximized_normal +-- @usebeautiful beautiful.border_width_maximized_new +-- @usebeautiful beautiful.border_width_maximized_urgent +-- @usebeautiful beautiful.border_width_fullscreen +-- @usebeautiful beautiful.border_width_fullscreen_active +-- @usebeautiful beautiful.border_width_fullscreen_normal +-- @usebeautiful beautiful.border_width_fullscreen_new +-- @usebeautiful beautiful.border_width_fullscreen_urgent +-- @usebeautiful beautiful.opacity_floating +-- @usebeautiful beautiful.opacity_floating_active +-- @usebeautiful beautiful.opacity_floating_normal +-- @usebeautiful beautiful.opacity_floating_new +-- @usebeautiful beautiful.opacity_floating_urgent +-- @usebeautiful beautiful.opacity_maximized +-- @usebeautiful beautiful.opacity_maximized_active +-- @usebeautiful beautiful.opacity_maximized_normal +-- @usebeautiful beautiful.opacity_maximized_new +-- @usebeautiful beautiful.opacity_maximized_urgent +-- @usebeautiful beautiful.opacity_fullscreen +-- @usebeautiful beautiful.opacity_fullscreen_active +-- @usebeautiful beautiful.opacity_fullscreen_normal +-- @usebeautiful beautiful.opacity_fullscreen_new +-- @usebeautiful beautiful.opacity_fullscreen_urgent +-- @usebeautiful beautiful.opacity_active +-- @usebeautiful beautiful.opacity_normal +-- @usebeautiful beautiful.opacity_new +-- @usebeautiful beautiful.opacity_urgent + +function ewmh.update_border(c, context) + local suffix, fallback = "", "" + + -- Add the sub-namespace. + if c.fullscreen then + suffix, fallback = "_fullscreen", "_fullscreen" + elseif c.maximized then + suffix, fallback = "_maximized", "_maximized" + elseif c.floating then + suffix, fallback = "_floating", "_floating" + end + + -- Add the state suffix. + if c.urgent then + suffix = suffix .. "_urgent" + elseif c.active then + suffix = suffix .. "_active" + elseif context == "added" then + suffix = suffix .. "_new" + else + suffix = suffix .. "_normal" + end + + if not c._private._user_border_width then + c._border_width = beautiful["border_width"..suffix] + or beautiful["border_width"..fallback] + or beautiful.border_width + end + + if not c._private._user_border_color then + -- First, check marked clients. This is a concept that should probably + -- never have been added to the core. The documentation claims it works, + -- even if it has been broken for 90% of AwesomeWM releases ever since + -- it was added. + if c.marked and beautiful.border_marked then + c._border_color = beautiful.border_marked + return + end + + local tv = beautiful["border_color"..suffix] + + if fallback ~= "" and not tv then + tv = beautiful["border_color"..fallback] + end + + -- The old theme variable did not have "color" in its name. + if (not tv) and beautiful.border_normal and (not c.active) then + gdebug.deprecate( + "Use `beautiful.border_color_normal` instead of `beautiful.border_normal`", + {deprecated_in=5} + ) + tv = beautiful.border_normal + elseif (not tv) and beautiful.border_focus then + gdebug.deprecate( + "Use `beautiful.border_color_active` instead of `beautiful.border_focus`", + {deprecated_in=5} + ) + tv = beautiful.border_focus + end + + if not tv then + tv = beautiful.border_color + end + + if tv then + c._border_color = tv + end + end + + if not c._private._user_opacity then + local tv = beautiful["opacity"..suffix] + + if fallback ~= "" and not tv then + tv = beautiful["opacity"..fallback] + end + + if tv then + c._opacity = tv + end + end +end + +client.connect_signal("request::border", ewmh.update_border) client.connect_signal("request::activate", ewmh.activate) client.connect_signal("request::tag", ewmh.tag) client.connect_signal("request::urgent", ewmh.urgent) diff --git a/lib/awful/menu.lua b/lib/awful/menu.lua index b17964a4d..369e63bd7 100644 --- a/lib/awful/menu.lua +++ b/lib/awful/menu.lua @@ -119,8 +119,8 @@ local function load_theme(a, b) local fallback = beautiful.get() if a.reset then b = fallback end if a == "reset" then a = fallback end - ret.border = a.border_color or b.menu_border_color or b.border_normal or - fallback.menu_border_color or fallback.border_normal + ret.border = a.border_color or b.menu_border_color or b.border_color_normal or + fallback.menu_border_color or fallback.border_color_normal ret.border_width= a.border_width or b.menu_border_width or b.border_width or fallback.menu_border_width or fallback.border_width or dpi(0) ret.fg_focus = a.fg_focus or b.menu_fg_focus or b.fg_focus or diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index 18f204b7d..354c81a41 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -708,7 +708,7 @@ local function get_relative_regions(geo, mode, is_absolute) -- Detect various types of geometry table and (try) to get rid of the -- differences so the code below don't have to care anymore. if geo.drawin then - bw, dgeo = geo.drawin.border_width, geo.drawin:geometry() + bw, dgeo = geo.drawin._border_width, geo.drawin:geometry() elseif geo.drawable and geo.drawable.get_wibox then bw = geo.drawable.get_wibox().border_width dgeo = geo.drawable.get_wibox():geometry() diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index 9a659c140..ba38cac82 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -538,6 +538,12 @@ crules._execute = function(_, c, props, callbacks) props.keys = props.keys or keys props.buttons = props.buttons or btns + -- Border width will also cause geometry related properties to fail + if props.border_width then + c.border_width = type(props.border_width) == "function" and + props.border_width(c, props) or props.border_width + end + -- This has to be done first, as it will impact geometry related props. if props.titlebars_enabled and (type(props.titlebars_enabled) ~= "function" or props.titlebars_enabled(c,props)) then @@ -545,12 +551,6 @@ crules._execute = function(_, c, props, callbacks) c._request_titlebars_called = true end - -- Border width will also cause geometry related properties to fail - if props.border_width then - c.border_width = type(props.border_width) == "function" and - props.border_width(c, props) or props.border_width - end - -- Size hints will be re-applied when setting width/height unless it is -- disabled first if props.size_hints_honor ~= nil then diff --git a/lib/awful/tooltip.lua b/lib/awful/tooltip.lua index 81674a3bc..b75a758be 100644 --- a/lib/awful/tooltip.lua +++ b/lib/awful/tooltip.lua @@ -694,7 +694,7 @@ function tooltip.new(args) or beautiful.bg_focus or "#ffcb60" local border_width = args.border_width or beautiful.tooltip_border_width or 0 local border_color = args.border_color or beautiful.tooltip_border_color - or beautiful.border_normal or "#ffcb60" + or beautiful.border_color_normal or "#ffcb60" -- Set wibox default properties self.wibox_properties = { diff --git a/lib/awful/widget/calendar_popup.lua b/lib/awful/widget/calendar_popup.lua index 3e3479d8d..3c9fa3fb0 100644 --- a/lib/awful/widget/calendar_popup.lua +++ b/lib/awful/widget/calendar_popup.lua @@ -131,7 +131,7 @@ local function parse_cell_options(cell, args) elseif prop == 'border_width' then default = beautiful.border_width or 0 elseif prop == 'border_color' then - default = beautiful.border_normal or beautiful.fg_normal + default = beautiful.border_color_normal or beautiful.fg_normal end -- Get default diff --git a/lib/beautiful/init.lua b/lib/beautiful/init.lua index 7731eddc5..9db96f254 100644 --- a/lib/beautiful/init.lua +++ b/lib/beautiful/init.lua @@ -132,23 +132,12 @@ local active_font -- @beautiful beautiful.useless_gap -- @param[opt=0] number ---- The client border width. +--- The fallback border width. -- @beautiful beautiful.border_width -- @param number ---- The default clients border color. --- Note that only solid colors are supported. --- @beautiful beautiful.border_normal --- @param color - ---- The focused client border color. --- Note that only solid colors are supported. --- @beautiful beautiful.border_focus --- @param color - ---- The marked clients border color. --- Note that only solid colors are supported. --- @beautiful beautiful.border_marked +--- The fallback border color. +-- @beautiful beautiful.border_color -- @param color --- The wallpaper path. diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index e65704b47..92342f9e3 100644 --- a/lib/naughty/core.lua +++ b/lib/naughty/core.lua @@ -630,7 +630,7 @@ end -- @string[opt=`beautiful.notification_fg` or `beautiful.fg_focus` or `'#ffffff'`] args.fg Foreground color. -- @string[opt=`beautiful.notification_fg` or `beautiful.bg_focus` or `'#535d6c'`] args.bg Background color. -- @int[opt=`beautiful.notification_border_width` or 1] args.border_width Border width. --- @string[opt=`beautiful.notification_border_color` or `beautiful.border_focus` or `'#535d6c'`] args.border_color Border color. +-- @string[opt=`beautiful.notification_border_color` or `beautiful.border_color_active` or `'#535d6c'`] args.border_color Border color. -- @tparam[opt=`beautiful.notification_shape`] gears.shape args.shape Widget shape. -- @tparam[opt=`beautiful.notification_opacity`] gears.opacity args.opacity Widget opacity. -- @tparam[opt=`beautiful.notification_margin`] gears.margin args.margin Widget margin. diff --git a/lib/naughty/notification.lua b/lib/naughty/notification.lua index f06d21c8d..5edb45e70 100644 --- a/lib/naughty/notification.lua +++ b/lib/naughty/notification.lua @@ -777,7 +777,7 @@ end -- @string[opt=`beautiful.notification_fg` or `beautiful.bg_focus` or `'#535d6c'`] args.bg Background color. -- @int[opt=`beautiful.notification_border_width` or 1] args.border_width Border width. -- @string[opt=`beautiful.notification_border_color` or --- `beautiful.border_focus` or `'#535d6c'`] args.border_color Border color. +-- `beautiful.border_color_active` or `'#535d6c'`] args.border_color Border color. -- @tparam[opt=`beautiful.notification_shape`] gears.shape args.shape Widget shape. -- @tparam[opt=`beautiful.notification_opacity`] gears.opacity args.opacity Widget opacity. -- @tparam[opt=`beautiful.notification_margin`] gears.margin args.margin Widget margin. diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index 6bf2b85fd..46f72d49c 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -221,7 +221,20 @@ function wibox:get_children_by_id(name) return {} end -for _, k in pairs{ "struts", "geometry", "get_xproperty", "set_xproperty" } do +-- Proxy those properties to decorate their accessors with an extra flag to +-- define when they are set by the user. This allows to "manage" the value of +-- those properties internally until they are manually overridden. +for _, prop in ipairs { "border_width", "border_color", "opacity" } do + wibox["get_"..prop] = function(self) + return self["_"..prop] + end + wibox["set_"..prop] = function(self, value) + self._private["_user_"..prop] = true + self["_"..prop] = value + end +end + +for _, k in ipairs{ "struts", "geometry", "get_xproperty", "set_xproperty" } do wibox[k] = function(self, ...) return self.drawin[k](self.drawin, ...) end @@ -362,6 +375,14 @@ local function new(args) ret.shape = args.shape end + if args.border_width then + ret.border_width = args.border_width + end + + if args.border_color then + ret.border_color = args.border_color + end + if args.input_passthrough then ret.input_passthrough = args.input_passthrough end diff --git a/objects/client.c b/objects/client.c index 893abf212..1b10f8a85 100644 --- a/objects/client.c +++ b/objects/client.c @@ -568,20 +568,19 @@ * The client border width. * @property border_width * @param integer + * @propemits false false + * @see request::border */ /** * The client border color. * - * **Signal:** - * - * * *property::border\_color* - * - * @see gears.color - * * @property border_color - * @param pattern Any string, gradients and patterns will be converted to a + * @param color Any string, gradients and patterns will be converted to a * cairo pattern. + * @propemits false false + * @see request::border + * @see gears.color */ /** @@ -593,6 +592,8 @@ * * @property urgent * @param boolean + * @propemits false false + * @see request::border */ /** @@ -619,6 +620,8 @@ * * @property opacity * @param number Between 0 (transparent) to 1 (opaque) + * @propemits false false + * @see request::border */ /** @@ -673,6 +676,8 @@ * * @property maximized * @param boolean + * @propemits false false + * @see request::border */ /** @@ -976,27 +981,6 @@ * @see client.geometry */ -/** - * The border color when the client is focused. - * - * @beautiful beautiful.border_focus - * @param string - */ - -/** - * The border color when the client is not focused. - * - * @beautiful beautiful.border_normal - * @param string - */ - -/** - * The client border width. - * - * @beautiful beautiful.border_width - * @param integer - */ - /** Return client struts (reserved space at the edge of the screen). * * @param struts A table with new strut values, or none. @@ -4095,4 +4079,6 @@ client_class_setup(lua_State *L) /* @DOC_cobject_COMMON@ */ +/* @DOC_client_theme_COMMON@ */ + // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/objects/window.c b/objects/window.c index 623cdbb6e..440970f3d 100644 --- a/objects/window.c +++ b/objects/window.c @@ -530,15 +530,15 @@ window_class_setup(lua_State *L) NULL, (lua_class_propfunc_t) luaA_window_get_window, NULL); - luaA_class_add_property(&window_class, "opacity", + luaA_class_add_property(&window_class, "_opacity", (lua_class_propfunc_t) luaA_window_set_opacity, (lua_class_propfunc_t) luaA_window_get_opacity, (lua_class_propfunc_t) luaA_window_set_opacity); - luaA_class_add_property(&window_class, "border_color", + luaA_class_add_property(&window_class, "_border_color", (lua_class_propfunc_t) luaA_window_set_border_color, (lua_class_propfunc_t) luaA_window_get_border_color, (lua_class_propfunc_t) luaA_window_set_border_color); - luaA_class_add_property(&window_class, "border_width", + luaA_class_add_property(&window_class, "_border_width", (lua_class_propfunc_t) luaA_window_set_border_width, (lua_class_propfunc_t) luaA_window_get_border_width, (lua_class_propfunc_t) luaA_window_set_border_width); diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index c425c5379..f554b76bd 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -70,7 +70,7 @@ function client.gen_fake(args) ret.type = "normal" ret.valid = true ret.size_hints = {} - ret.border_width = 1 + ret._border_width = 1 ret.icon_sizes = {{16,16}} ret.name = "Example Client" ret._private._struts = { top = 0, right = 0, left = 0, bottom = 0 } diff --git a/tests/examples/shims/drawin.lua b/tests/examples/shims/drawin.lua index 61ca495c8..8eb5d1bfe 100644 --- a/tests/examples/shims/drawin.lua +++ b/tests/examples/shims/drawin.lua @@ -15,7 +15,7 @@ local function new_drawin(_, args) ret.y=0 ret.width=1 ret.height=1 - ret.border_width=0 + ret._border_width=0 ret.ontop = false ret.below = false ret.above = false diff --git a/tests/test-awful-placement.lua b/tests/test-awful-placement.lua index 7761b3798..6aedf95c3 100644 --- a/tests/test-awful-placement.lua +++ b/tests/test-awful-placement.lua @@ -1,6 +1,4 @@ local awful = require("awful") -local gears = require("gears") -local beautiful = require("beautiful") local test_client = require("_client") local runner = require("_runner") @@ -14,8 +12,9 @@ end local tests = {} -local tb_height = gears.math.round(beautiful.get_font_height() * 1.5) -local border_width = beautiful.border_width +-- Set it to something different than the default to make sure it doesn't change +-- due to some request::border. +local border_width = 3 local class = "test-awful-placement" local rule = { @@ -24,6 +23,7 @@ local rule = { }, properties = { floating = true, + border_width = border_width, placement = awful.placement.no_overlap + awful.placement.no_offscreen } } @@ -40,7 +40,7 @@ end local function default_test(c, geometry) check_geometry(c, geometry.expected_x, geometry.expected_y, geometry.expected_width or geometry.width, - geometry.expected_height or (geometry.height + tb_height)) + geometry.expected_height or (geometry.height)) return true end @@ -242,7 +242,7 @@ for _, tag_num in ipairs{1, 2, 3} do width = wa.width - 50, height = 100, expected_x = wa.x, - expected_y = wa.y + tb_height + 2*border_width + 100 + expected_y = wa.y + 2*border_width + 100 } end } @@ -258,7 +258,7 @@ for _, tag_num in ipairs{1, 2, 3} do width = wa.width - 10, height = wa.height - 50, expected_x = wa.x, - expected_y = wa.y + 50 - 2*border_width - tb_height + expected_y = (wa.y + wa.height) - (wa.height - 50 + 2*border_width) } end } @@ -270,7 +270,7 @@ for _, tag_num in ipairs{1, 2, 3} do return { width = wa.width - 10, height = wa.height - 50, - expected_x = wa.x + 10 - 2*border_width, + expected_x = (wa.x + wa.width) - (wa.width - 10 + 2*border_width), expected_y = wa.y } end @@ -283,8 +283,8 @@ for _, tag_num in ipairs{1, 2, 3} do return { width = wa.width - 10, height = wa.height - 50, - expected_x = wa.x + 10 - 2*border_width, - expected_y = wa.y + 50 - 2*border_width - tb_height + expected_x = (wa.x + wa.width ) - (wa.width - 10 + 2*border_width), + expected_y = (wa.y + wa.height) - (wa.height - 50 + 2*border_width) } end } diff --git a/tests/test-awful-rules.lua b/tests/test-awful-rules.lua index 24c61c7e4..2482363da 100644 --- a/tests/test-awful-rules.lua +++ b/tests/test-awful-rules.lua @@ -1,6 +1,5 @@ local awful = require("awful") local gears = require("gears") -local beautiful = require("beautiful") local test_client = require("_client") local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) @@ -10,7 +9,6 @@ local message_printed = false -- Magic table to store tests local tests = {} -local tb_height = gears.math.round(beautiful.get_font_height() * 1.5) -- local border_width = beautiful.border_width -- Detect "request::manage" race conditions @@ -74,7 +72,7 @@ test_rule { -- The size should not have changed local geo = get_client_by_class(class):geometry() - assert(geo.width == 100 and geo.height == 100+tb_height) + assert(geo.width == 100 and geo.height == 100) return true end diff --git a/tests/test-focus.lua b/tests/test-focus.lua index e7fa09123..5a2fe90d8 100644 --- a/tests/test-focus.lua +++ b/tests/test-focus.lua @@ -5,8 +5,8 @@ local runner = require("_runner") local awful = require("awful") local beautiful = require("beautiful") -beautiful.border_normal = "#0000ff" -beautiful.border_focus = "#00ff00" +beautiful.border_color_normal = "#0000ff" +beautiful.border_color_active = "#00ff00" client.connect_signal("focus", function(c) c.border_color = "#ff0000" diff --git a/tests/test-geometry.lua b/tests/test-geometry.lua index c90d1b9d5..a97491a88 100644 --- a/tests/test-geometry.lua +++ b/tests/test-geometry.lua @@ -17,7 +17,7 @@ awful.rules.rules = { y = 0, width = 100, height = 100, - border_color = beautiful.border_normal + border_color = beautiful.border_color_normal } } } @@ -103,7 +103,7 @@ local steps = { function() local c = client.get()[1] - assert(not pcall(function() c.border_width = -2000 end)) + assert(not pcall(function() c._border_width = -2000 end)) assert(c.border_width==0) c.border_width = 125 diff --git a/themes/default/theme.lua b/themes/default/theme.lua index b0be48012..fd9f9c43c 100644 --- a/themes/default/theme.lua +++ b/themes/default/theme.lua @@ -24,11 +24,11 @@ theme.fg_focus = "#ffffff" theme.fg_urgent = "#ffffff" theme.fg_minimize = "#ffffff" -theme.useless_gap = dpi(0) -theme.border_width = dpi(1) -theme.border_normal = "#000000" -theme.border_focus = "#535d6c" -theme.border_marked = "#91231c" +theme.useless_gap = dpi(0) +theme.border_width = dpi(1) +theme.border_color_normal = "#000000" +theme.border_color_active = "#535d6c" +theme.border_marked = "#91231c" -- There are other variable sets -- overriding the default one when diff --git a/themes/gtk/theme.lua b/themes/gtk/theme.lua index ca31be8f0..392791ff3 100644 --- a/themes/gtk/theme.lua +++ b/themes/gtk/theme.lua @@ -120,9 +120,9 @@ theme.fg_minimize = mix(theme.wibar_fg, theme.wibar_bg, 0.9) theme.bg_systray = theme.wibar_bg -theme.border_normal = theme.gtk.wm_border_unfocused_color -theme.border_focus = theme.gtk.wm_border_focused_color -theme.border_marked = theme.gtk.success_color +theme.border_color_normal = theme.gtk.wm_border_unfocused_color +theme.border_color_active = theme.gtk.wm_border_focused_color +theme.border_color_marked = theme.gtk.success_color theme.border_width = dpi(theme.gtk.button_border_width or 1) theme.border_radius = theme.gtk.button_border_radius diff --git a/themes/sky/theme.lua b/themes/sky/theme.lua index 0aa7d1bd6..b724bad89 100644 --- a/themes/sky/theme.lua +++ b/themes/sky/theme.lua @@ -27,9 +27,9 @@ theme.fg_minimize = "#2e3436" theme.useless_gap = dpi(0) theme.border_width = dpi(2) -theme.border_normal = "#dae3e0" -theme.border_focus = "#729fcf" -theme.border_marked = "#eeeeec" +theme.border_color_normal = "#dae3e0" +theme.border_color_active = "#729fcf" +theme.border_color_marked = "#eeeeec" -- IMAGES theme.layout_fairh = themes_path .. "sky/layouts/fairh.png" diff --git a/themes/xresources/theme.lua b/themes/xresources/theme.lua index e11a83c9e..4168bcc07 100644 --- a/themes/xresources/theme.lua +++ b/themes/xresources/theme.lua @@ -29,9 +29,9 @@ theme.fg_minimize = theme.bg_normal theme.useless_gap = dpi(3) theme.border_width = dpi(2) -theme.border_normal = xrdb.color0 -theme.border_focus = theme.bg_focus -theme.border_marked = xrdb.color10 +theme.border_color_normal = xrdb.color0 +theme.border_color_active = theme.bg_focus +theme.border_color_marked = xrdb.color10 -- There are other variable sets -- overriding the default one when diff --git a/themes/zenburn/theme.lua b/themes/zenburn/theme.lua index 2b6fa08a8..ead4081b2 100644 --- a/themes/zenburn/theme.lua +++ b/themes/zenburn/theme.lua @@ -27,9 +27,9 @@ theme.bg_systray = theme.bg_normal -- {{{ Borders theme.useless_gap = dpi(0) theme.border_width = dpi(2) -theme.border_normal = "#3F3F3F" -theme.border_focus = "#6F6F6F" -theme.border_marked = "#CC9393" +theme.border_color_normal = "#3F3F3F" +theme.border_color_active = "#6F6F6F" +theme.border_color_marked = "#CC9393" -- }}} -- {{{ Titlebars