From 4e54aea6a9755abd3d9163aea7cd84659612e564 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 23 Nov 2017 22:54:13 -0500 Subject: [PATCH 1/3] wibox: Add an input_passthrough property. Allows, for example, to have semi translucent wibars on top of the fullscreens clients without having issues with inputs. --- docs/common/wibox.ldoc | 16 ++++++++++++++++ lib/wibox/init.lua | 31 +++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/docs/common/wibox.ldoc b/docs/common/wibox.ldoc index 4898fb33..050bb2b8 100644 --- a/docs/common/wibox.ldoc +++ b/docs/common/wibox.ldoc @@ -180,6 +180,22 @@ -- @property shape -- @tparam gears.shape shape +--- Forward the inputs to the client below the wibox. +-- +-- This replace the `shape_input` mask with an empty area. All mouse and +-- keyboard events are sent to the object (such as a client) positioned below +-- this wibox. When used alongside compositing, it allows, for example, to have +-- a subtle transparent wibox on top a fullscreen client to display important +-- data such as a low battery warning. +-- +-- **Signal:** +-- +-- * *property::input_passthrough* +-- +-- @property input_passthrough +-- @param[opt=false] boolean +-- @see shape_input + --- Get or set mouse buttons bindings to a wibox. -- -- @param buttons_table A table of buttons objects, or nothing. diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index aa027bcb..e556580c 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -137,11 +137,6 @@ function wibox:_apply_shape() img:finish() end ---- Set the wibox shape. --- @property shape --- @tparam gears.shape A gears.shape compatible function. --- @see gears.shape - function wibox:set_shape(shape) self._shape = shape self:_apply_shape() @@ -151,6 +146,24 @@ function wibox:get_shape() return self._shape end +function wibox:set_input_passthrough(value) + rawset(self, "_input_passthrough", value) + + if not value then + self.shape_input = nil + else + local img = cairo.ImageSurface(cairo.Format.A1, 0, 0) + self.shape_input = img._native + img:finish() + end + + self:emit_signal("property::input_passthrough", value) +end + +function wibox:get_input_passthrough() + return self._input_passthrough +end + function wibox:get_screen() if self.screen_assigned and self.screen_assigned.valid then return self.screen_assigned @@ -324,7 +337,13 @@ local function new(args) ret:set_screen ( args.screen ) end - ret.shape = args.shape + if args.shape then + ret.shape = args.shape + end + + if args.screen then + ret.input_passthrough = args.input_passthrough + end return ret end From 9e81045d42aee40661ebad1492c4d1eb69d9c40a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 23 Nov 2017 22:56:20 -0500 Subject: [PATCH 2/3] tests: Test the input_passthrough property --- tests/test-wibox-shape.lua | 96 +++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/tests/test-wibox-shape.lua b/tests/test-wibox-shape.lua index 62166f10..1d56e1e1 100644 --- a/tests/test-wibox-shape.lua +++ b/tests/test-wibox-shape.lua @@ -18,14 +18,106 @@ local wb = wibox { wb:geometry(screen[1].geometry) wb.visible = true -runner.run_steps({ +local count = 0 + +local steps = { function() assert(wb.shape == shape.powerline) assert(wb.shape_bounding) -- This is a memory leak! Don't copy! if was_drawn then return true end + end, + -- Remove the shape and test the input + function() + wb.shape = nil + wb.input_passthrough = false + wb:connect_signal("button::press", function() + count = count + 1 + end) + + wb:geometry { + x = 0, + y = 100, + width = 101, + height = 101, + } + wb.border_width = 0 + + return true end -}) +} + +-- Emulate a click. +-- Each pair of the `...` corresponds to a point. +local function click(...) + local args = {...} + table.insert(steps, function() + for i = 0, math.floor(#args/2)-1 do + local x, y = args[i*2+1], args[i*2+2] + mouse.coords{x=x, y=y} + assert(mouse.coords().x == x and mouse.coords().y == y) + root.fake_input("button_release", 1) + root.fake_input("button_press", 1) + end + + awesome.sync() + + return true + end) +end + +local function check_count(cnt) + table.insert(steps, function() + return cnt == count + end) +end + +-- Check each corner +click(0 , 100, + 99, 100, + 99, 199, + 0 , 199 +) + +check_count(4) + +table.insert(steps, function() + wb.input_passthrough = true + count = 0 + return true +end) + +-- Do it again +click(0 , 100, + 99, 100, + 99, 199, + 0 , 199 +) + +-- It's passthrough, so there should be no recorded clicks. +check_count(0) + +table.insert(steps, function() + wb.input_passthrough = false + count = 0 + return true +end) + +table.insert(steps, function() + awesome.sync() + count = 0 + return true +end) + +-- One last time +click(0 , 100, + 99, 100, + 99, 199, + 0 , 199 +) +check_count(4) + +runner.run_steps(steps) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 From d99504775ba18eca2d5e3ccbe25db2c62823d91b Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 23 Nov 2017 23:19:41 -0500 Subject: [PATCH 3/3] doc: Mutualize the wibar and wibox constructor documentation. Do it now since the future awful.popup and notification widget also uses it. The `load_ldoc.cmake` changes allow to include `.ldoc` blocks in existing ldoc comments. Previously, it added some extra newlines and an autogenerated comments saying the content below was imported. The problem is that this prevented the system to be used for shared function arguments. This commit also renames the `wibar` argument table from `arg` to `args` as the name has to be the same in the `wibox` and `wibar` constructor for this to work. --- docs/common/wibox_constructor.ldoc | 22 +++++++++ docs/load_ldoc.cmake | 5 ++- lib/awful/wibar.lua | 72 +++++++++++------------------- lib/wibox/init.lua | 20 +-------- 4 files changed, 54 insertions(+), 65 deletions(-) create mode 100644 docs/common/wibox_constructor.ldoc diff --git a/docs/common/wibox_constructor.ldoc b/docs/common/wibox_constructor.ldoc new file mode 100644 index 00000000..e93cc226 --- /dev/null +++ b/docs/common/wibox_constructor.ldoc @@ -0,0 +1,22 @@ + @tparam integer args.border_width Border width. +-- @tparam string args.border_color Border color. +-- @tparam[opt=false] boolean args.ontop On top of other windows. +-- @tparam string args.cursor The mouse cursor. +-- @tparam boolean args.visible Visibility. +-- @tparam[opt=1] number args.opacity The opacity, between 0 and 1. +-- @tparam string args.type The window type (desktop, normal, dock, …). +-- @tparam integer args.x The x coordinates. +-- @tparam integer args.y The y coordinates. +-- @tparam integer args.width The width. +-- @tparam integer args.height The height. +-- @tparam screen args.screen The wibox screen. +-- @tparam wibox.widget args.widget The widget that the wibox displays. +-- @param args.shape_bounding The wibox’s bounding shape as a (native) cairo surface. +-- @param args.shape_clip The wibox’s clip shape as a (native) cairo surface. +-- @param args.shape_input The wibox’s input shape as a (native) cairo surface. +-- @tparam color args.bg The background. +-- @tparam surface args.bgimage The background image of the drawable. +-- @tparam color args.fg The foreground (text) color. +-- @tparam gears.shape args.shape The shape. +-- @tparam[opt=false] boolean args.input_passthrough If the inputs are +-- forward to the element below. diff --git a/docs/load_ldoc.cmake b/docs/load_ldoc.cmake index d8f6fe21..a783e7db 100644 --- a/docs/load_ldoc.cmake +++ b/docs/load_ldoc.cmake @@ -13,8 +13,11 @@ foreach(doc_file_name ${doc_files}) # Remove the file extension string(REGEX REPLACE "\\.ldoc" "" DOC_FILE_NAME ${doc_file_name}) + # There is a trailing \n, remove it or it cannot be included in existing blocks + string(REGEX REPLACE "\n$" "" doc_file_content "${doc_file_content}") + # Create a new variable usable from lua files - set(DOC_${DOC_FILE_NAME}_COMMON "Imported documentation\n\n${doc_file_content}") + set(DOC_${DOC_FILE_NAME}_COMMON "${doc_file_content}") endforeach() # vim: filetype=cmake:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80:foldmethod=marker diff --git a/lib/awful/wibar.lua b/lib/awful/wibar.lua index 5e96a2b8..bdb3da88 100644 --- a/lib/awful/wibar.lua +++ b/lib/awful/wibar.lua @@ -339,37 +339,19 @@ end -- You can also set the screen key with a screen number to attach the wibox. -- If not specified, the primary screen is assumed. -- @see wibox --- @tparam[opt=nil] table arg --- @tparam string arg.position The position. --- @tparam string arg.stretch If the wibar need to be stretched to fill the screen. --- @tparam integer arg.border_width Border width. --- @tparam string arg.border_color Border color. --- @tparam boolean arg.ontop On top of other windows. --- @tparam string arg.cursor The mouse cursor. --- @tparam boolean arg.visible Visibility. --- @tparam number arg.opacity The wibar's opacity, between 0 and 1. --- @tparam string arg.type The window type (desktop, normal, dock, …). --- @tparam integer arg.x The x coordinates. --- @tparam integer arg.y The y coordinates. --- @tparam integer arg.width The wibar's width. --- @tparam integer arg.height The wibar's height. --- @tparam screen arg.screen The wibox screen. --- @tparam wibox.widget arg.widget The widget that the wibox displays. --- @param arg.shape_bounding The wibox’s bounding shape as a (native) cairo surface. --- @param arg.shape_clip The wibox’s clip shape as a (native) cairo surface. --- @param arg.shape_input The wibox’s input shape as a (native) cairo surface. --- @tparam color arg.bg The wibar's background. --- @tparam surface arg.bgimage The background image of the drawable. --- @tparam color arg.fg The wibar's foreground (text) color. +-- @tparam[opt=nil] table args +-- @tparam string args.position The position. +-- @tparam string args.stretch If the wibar need to be stretched to fill the screen. +--@DOC_wibox_constructor_COMMON@ -- @return The new wibar -- @function awful.wibar -function awfulwibar.new(arg) - arg = arg or {} - local position = arg.position or "top" +function awfulwibar.new(args) + args = args or {} + local position = args.position or "top" local has_to_stretch = true - local screen = get_screen(arg.screen or 1) + local screen = get_screen(args.screen or 1) - arg.type = arg.type or "dock" + args.type = args.type or "dock" if position ~= "top" and position ~="bottom" and position ~= "left" and position ~= "right" then @@ -379,48 +361,48 @@ function awfulwibar.new(arg) -- Set default size if position == "left" or position == "right" then - arg.width = arg.width or beautiful["wibar_width"] - or math.ceil(beautiful.get_font_height(arg.font) * 1.5) - if arg.height then + args.width = args.width or beautiful["wibar_width"] + or math.ceil(beautiful.get_font_height(args.font) * 1.5) + if args.height then has_to_stretch = false - if arg.screen then - local hp = tostring(arg.height):match("(%d+)%%") + if args.screen then + local hp = tostring(args.height):match("(%d+)%%") if hp then - arg.height = math.ceil(screen.geometry.height * hp / 100) + args.height = math.ceil(screen.geometry.height * hp / 100) end end end else - arg.height = arg.height or beautiful["wibar_height"] - or math.ceil(beautiful.get_font_height(arg.font) * 1.5) - if arg.width then + args.height = args.height or beautiful["wibar_height"] + or math.ceil(beautiful.get_font_height(args.font) * 1.5) + if args.width then has_to_stretch = false - if arg.screen then - local wp = tostring(arg.width):match("(%d+)%%") + if args.screen then + local wp = tostring(args.width):match("(%d+)%%") if wp then - arg.width = math.ceil(screen.geometry.width * wp / 100) + args.width = math.ceil(screen.geometry.width * wp / 100) end end end end - arg.screen = nil + args.screen = nil -- The C code scans the table directly, so metatable magic cannot be used. for _, prop in ipairs { "border_width", "border_color", "font", "opacity", "ontop", "cursor", "bgimage", "bg", "fg", "type", "stretch", "shape" } do - if (arg[prop] == nil) and beautiful["wibar_"..prop] ~= nil then - arg[prop] = beautiful["wibar_"..prop] + if (args[prop] == nil) and beautiful["wibar_"..prop] ~= nil then + args[prop] = beautiful["wibar_"..prop] end end - local w = wibox(arg) + local w = wibox(args) w.screen = screen w._screen = screen --HACK When a screen is removed, then getbycoords wont work - w._stretch = arg.stretch == nil and has_to_stretch or arg.stretch + w._stretch = args.stretch == nil and has_to_stretch or args.stretch w.get_position = get_position w.set_position = set_position @@ -429,7 +411,7 @@ function awfulwibar.new(arg) w.set_stretch = set_stretch w.remove = remove - if arg.visible == nil then w.visible = true end + if args.visible == nil then w.visible = true end -- `w` needs to be inserted in `wiboxes` before reattach or its own offset -- will not be taken into account by the "older" wibars when `reattach` is diff --git a/lib/wibox/init.lua b/lib/wibox/init.lua index e556580c..a8037954 100644 --- a/lib/wibox/init.lua +++ b/lib/wibox/init.lua @@ -236,25 +236,7 @@ end --- Create a wibox. -- @tparam[opt=nil] table args --- @tparam integer args.border_width Border width. --- @tparam string args.border_color Border color. --- @tparam boolean args.ontop On top of other windows. --- @tparam string args.cursor The mouse cursor. --- @tparam boolean args.visible Visibility. --- @tparam number args.opacity The opacity of the wibox, between 0 and 1. --- @tparam string args.type The window type (desktop, normal, dock, …). --- @tparam integer args.x The x coordinates. --- @tparam integer args.y The y coordinates. --- @tparam integer args.width The width of the wibox. --- @tparam integer args.height The height of the wibox. --- @tparam screen args.screen The wibox screen. --- @tparam wibox.widget args.widget The widget that the wibox displays. --- @param args.shape_bounding The wibox’s bounding shape as a (native) cairo surface. --- @param args.shape_clip The wibox’s clip shape as a (native) cairo surface. --- @param args.shape_input The wibox’s input shape as a (native) cairo surface. --- @tparam color args.bg The background of the wibox. --- @tparam surface args.bgimage The background image of the drawable. --- @tparam color args.fg The foreground (text) of the wibox. +--@DOC_wibox_constructor_COMMON@ -- @treturn wibox The new wibox -- @function .wibox