diff --git a/docs/common/widget.ldoc b/docs/common/widget.ldoc index ec215f5b9..cae2e47f1 100644 --- a/docs/common/widget.ldoc +++ b/docs/common/widget.ldoc @@ -48,77 +48,119 @@ -- @function emit_signal_recursive --- When the layout (size) change. --- This signal is emited when the previous results of `:layout()` and `:fit()` --- are no longer valid. +-- This signal is emitted when the previous results of `:layout()` and `:fit()` +-- are no longer valid. Unless this signal is emitted, `:layout()` and `:fit()` +-- must return the same result when called with the same arguments. -- @signal widget::layout_changed -- @see widget::redraw_needed --- When the widget content changed. --- Unless this signal is emitted, `:layout()` and `:fit()` must return the same --- result when called with the same arguments. In case this isn't the case, --- use `widget::layout_changed`. +-- This signal is emitted when the content of the widget changes. The widget will +-- be redrawn, it is not re-layouted. Put differently, it is assumed that +-- `:layout()` and `:fit()` would still return the same results as before. -- @signal widget::redraw_needed +-- @see widget::layout_changed --- When a mouse button is pressed over the widget. --- The position of the mouse press relative to the widget while geometry --- contains the geometry of the widget relative to the wibox. -- @signal button::press --- @tparam table widget The widget --- @tparam number lx The relative horizontal position. --- @tparam number ly The relative vertical position. +-- @tparam number lx The horizontal position relative to the (0,0) position in +-- the widget. +-- @tparam number ly The vertical position relative to the (0,0) position in the +-- widget. -- @tparam number button The button number. -- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift) --- @tparam table geometry --- @tparam number geometry.x The vertical position --- @tparam number geometry.y The horizontal position --- @tparam number geometry.width The widget --- @tparam number geometry.height The height --- @tparam drawable geometry.drawable The `drawable` --- @tparam table geometry.matrix_to_parent The relative `gears.matrix` --- @tparam table geometry.matrix_to_device The absolute `gears.matrix` +-- @tparam table find_widgets_result The entry from the result of +-- @{wibox.drawable:find_widgets} for the position that the mouse hit. +-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing +-- the widget. +-- @tparam widget find_widgets_result.widget The widget being displayed. +-- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy +-- managing the widget's geometry. +-- @tparam number find_widgets_result.x An approximation of the X position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.y An approximation of the Y position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.width An approximation of the width that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.height An approximation of the height that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.widget_width The exact width of the widget +-- in its local coordinate system. +-- @tparam number find_widgets_result.widget_height The exact height of the widget +-- in its local coordinate system. -- @see mouse --- When a mouse button is released over the widget. --- The position of the mouse press relative to the widget while geometry --- contains the geometry of the widget relative to the wibox. -- @signal button::release --- @tparam table widget The widget --- @tparam number lx The relative horizontal position. --- @tparam number ly The relative vertical position. +-- @tparam number lx The horizontal position relative to the (0,0) position in +-- the widget. +-- @tparam number ly The vertical position relative to the (0,0) position in the +-- widget. -- @tparam number button The button number. -- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift) --- @tparam table geometry --- @tparam number geometry.x The vertical position --- @tparam number geometry.y The horizontal position --- @tparam number geometry.width The widget --- @tparam number geometry.height The height --- @tparam drawable geometry.drawable The `drawable` --- @tparam table geometry.matrix_to_parent The relative `gears.matrix` --- @tparam table geometry.matrix_to_device The absolute `gears.matrix` +-- @tparam table find_widgets_result The entry from the result of +-- @{wibox.drawable:find_widgets} for the position that the mouse hit. +-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing +-- the widget. +-- @tparam widget find_widgets_result.widget The widget being displayed. +-- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy +-- managing the widget's geometry. +-- @tparam number find_widgets_result.x An approximation of the X position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.y An approximation of the Y position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.width An approximation of the width that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.height An approximation of the height that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.widget_width The exact width of the widget +-- in its local coordinate system. +-- @tparam number find_widgets_result.widget_height The exact height of the widget +-- in its local coordinate system. -- @see mouse --- When the mouse enter a widget. -- @signal mouse::enter --- @tparam table widget The widget --- @tparam table geometry --- @tparam number geometry.x The vertical position --- @tparam number geometry.y The horizontal position --- @tparam number geometry.width The widget --- @tparam number geometry.height The height --- @tparam drawable geometry.drawable The `drawable` --- @tparam table geometry.matrix_to_parent The relative `gears.matrix` --- @tparam table geometry.matrix_to_device The absolute `gears.matrix` +-- @tparam table find_widgets_result The entry from the result of +-- @{wibox.drawable:find_widgets} for the position that the mouse hit. +-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing +-- the widget. +-- @tparam widget find_widgets_result.widget The widget being displayed. +-- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy +-- managing the widget's geometry. +-- @tparam number find_widgets_result.x An approximation of the X position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.y An approximation of the Y position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.width An approximation of the width that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.height An approximation of the height that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.widget_width The exact width of the widget +-- in its local coordinate system. +-- @tparam number find_widgets_result.widget_height The exact height of the widget +-- in its local coordinate system. -- @see mouse --- When the mouse leave a widget. -- @signal mouse::leave --- @tparam table widget The widget --- @tparam table geometry --- @tparam number geometry.x The vertical position --- @tparam number geometry.y The horizontal position --- @tparam number geometry.width The widget --- @tparam number geometry.height The height --- @tparam drawable geometry.drawable The `drawable` --- @tparam table geometry.matrix_to_parent The relative `gears.matrix` --- @tparam table geometry.matrix_to_device The absolute `gears.matrix` +-- @tparam table find_widgets_result The entry from the result of +-- @{wibox.drawable:find_widgets} for the position that the mouse hit. +-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing +-- the widget. +-- @tparam widget find_widgets_result.widget The widget being displayed. +-- @tparam wibox.hierarchy find_widgets_result.hierarchy The hierarchy +-- managing the widget's geometry. +-- @tparam number find_widgets_result.x An approximation of the X position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.y An approximation of the Y position that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.width An approximation of the width that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.height An approximation of the height that +-- the widget is visible at on the surface. +-- @tparam number find_widgets_result.widget_width The exact width of the widget +-- in its local coordinate system. +-- @tparam number find_widgets_result.widget_height The exact height of the widget +-- in its local coordinate system. -- @see mouse diff --git a/lib/wibox/drawable.lua b/lib/wibox/drawable.lua index e7df58217..771adbc7b 100644 --- a/lib/wibox/drawable.lua +++ b/lib/wibox/drawable.lua @@ -173,9 +173,11 @@ local function find_widgets(_drawable, result, _hierarchy, x, y) 0, 0, width, height) table.insert(result, { x = x3, y = y3, width = w3, height = h3, - drawable = _drawable, widget = _hierarchy:get_widget(), - matrix_to_device = _hierarchy:get_matrix_to_device(), - matrix_to_parent = _hierarchy:get_matrix_to_parent(), + widget_width = width, + widget_height = height, + drawable = _drawable, + widget = _hierarchy:get_widget(), + hierarchy = _hierarchy }) end for _, child in ipairs(_hierarchy:get_children()) do @@ -187,8 +189,14 @@ end -- The drawable must have drawn itself at least once for this to work. -- @param x X coordinate of the point -- @param y Y coordinate of the point --- @return A sorted table with all widgets that contain the given point. The --- widgets are sorted by relevance. +-- @treturn table A table containing a description of all the widgets that +-- contain the given point. Each entry is a table containing this drawable as +-- its `.drawable` entry, the widget under `.widget` and the instance of +-- `wibox.hierarchy` describing the size and position of the widget under +-- `.hierarchy`. For convenience, `.x`, `.y`, `.width` and `.height` contain an +-- approximation of the widget's extents on the surface. `widget_width` and +-- `widget_height` contain the exact size of the widget in its own, local +-- coordinate system (which may e.g. be rotated and scaled). function drawable:find_widgets(x, y) local result = {} if self._widget_hierarchy then @@ -386,8 +394,7 @@ function drawable.new(d, widget_context_skeleton, drawable_name) local widgets = ret:find_widgets(x, y) for _, v in pairs(widgets) do -- Calculate x/y inside of the widget - local lx = x - v.x - local ly = y - v.y + local lx, ly = v.hierarchy:get_matrix_from_device():transform_point(x, y) v.widget:emit_signal(name, lx, ly, button, modifiers,v) end end) diff --git a/lib/wibox/hierarchy.lua b/lib/wibox/hierarchy.lua index ffdc9924a..69f037773 100644 --- a/lib/wibox/hierarchy.lua +++ b/lib/wibox/hierarchy.lua @@ -126,7 +126,7 @@ function hierarchy_update(self, context, widget, width, height, region, matrix_t r = hierarchy_new(self._redraw_callback, self._layout_callback, self._callback_arg) r._parent = self end - hierarchy_update(r, context, w._widget, w._width, w._height, region, w._matrix, matrix_to_device * w._matrix) + hierarchy_update(r, context, w._widget, w._width, w._height, region, w._matrix, w._matrix * matrix_to_device) table.insert(self._children, r) end diff --git a/spec/wibox/hierarchy_spec.lua b/spec/wibox/hierarchy_spec.lua index 92541bc01..cb04451ce 100644 --- a/spec/wibox/hierarchy_spec.lua +++ b/spec/wibox/hierarchy_spec.lua @@ -124,7 +124,7 @@ describe("wibox.hierarchy", function() before_each(function() child = make_widget(nil) intermediate = make_widget({ - make_child(child, 10, 20, matrix.create_translate(0, 5)) + make_child(child, 10, 20, matrix.create_translate(0, 5):scale(2, 2)) }) parent = make_widget({ make_child(intermediate, 5, 2, matrix.create_translate(4, 0)) @@ -151,33 +151,33 @@ describe("wibox.hierarchy", function() end) it("get_matrix_to_parent", function() - assert.is.equal(hierarchy_child:get_matrix_to_parent(), matrix.create_translate(0, 5)) + assert.is.equal(hierarchy_child:get_matrix_to_parent(), matrix.create(2, 0, 0, 2, 0, 5)) assert.is.equal(hierarchy_intermediate:get_matrix_to_parent(), matrix.create_translate(4, 0)) assert.is.equal(hierarchy_parent:get_matrix_to_parent(), matrix.identity) end) it("get_matrix_to_device", function() - assert.is.equal(hierarchy_child:get_matrix_to_device(), matrix.create_translate(4, 5)) + assert.is.equal(hierarchy_child:get_matrix_to_device(), matrix.create(2, 0, 0, 2, 4, 5)) assert.is.equal(hierarchy_intermediate:get_matrix_to_device(), matrix.create_translate(4, 0)) assert.is.equal(hierarchy_parent:get_matrix_to_device(), matrix.identity) end) it("get_matrix_from_parent", function() - assert.is.equal(hierarchy_child:get_matrix_from_parent(), matrix.create_translate(0, -5)) + assert.is.equal(hierarchy_child:get_matrix_from_parent(), matrix.create(0.5, 0, 0, 0.5, 0, -2.5)) assert.is.equal(hierarchy_intermediate:get_matrix_from_parent(), matrix.create_translate(-4, 0)) assert.is.equal(hierarchy_parent:get_matrix_from_parent(), matrix.identity) end) it("get_matrix_from_device", function() - assert.is.equal(hierarchy_child:get_matrix_from_device(), matrix.create_translate(-4, -5)) + assert.is.equal(hierarchy_child:get_matrix_from_device(), matrix.create(0.5, 0, 0, 0.5, -2, -2.5)) assert.is.equal(hierarchy_intermediate:get_matrix_from_device(), matrix.create_translate(-4, 0)) assert.is.equal(hierarchy_parent:get_matrix_from_device(), matrix.identity) end) it("get_draw_extents", function() assert.is.same({ hierarchy_child:get_draw_extents() }, { 0, 0, 10, 20 }) - assert.is.same({ hierarchy_intermediate:get_draw_extents() }, { 0, 0, 10, 25 }) - assert.is.same({ hierarchy_parent:get_draw_extents() }, { 0, 0, 15, 25 }) + assert.is.same({ hierarchy_intermediate:get_draw_extents() }, { 0, 0, 20, 45 }) + assert.is.same({ hierarchy_parent:get_draw_extents() }, { 0, 0, 24, 45 }) end) it("get_size", function()