diff --git a/lib/awful/tooltip.lua b/lib/awful/tooltip.lua index 653a1823..ca51e801 100644 --- a/lib/awful/tooltip.lua +++ b/lib/awful/tooltip.lua @@ -71,9 +71,8 @@ end -- @tparam tooltip self A tooltip object. local function set_geometry(self) local my_geo = self.wibox:geometry() - local textbox_context = {dpi=beautiful.xresources.get_dpi(mouse.screen)} -- calculate width / height - local n_w, n_h = self.textbox:fit(textbox_context, -1, -1) -- Hack! :( + local n_w, n_h = self.textbox:get_preferred_size(mouse.screen) n_w = n_w + self.marginbox.left + self.marginbox.right n_h = n_h + self.marginbox.top + self.marginbox.bottom if my_geo.width ~= n_w or my_geo.height ~= n_h then diff --git a/lib/naughty/core.lua b/lib/naughty/core.lua index 546d9fc9..ee41e72b 100644 --- a/lib/naughty/core.lua +++ b/lib/naughty/core.lua @@ -458,8 +458,6 @@ function naughty.notify(args) local border_color = args.border_color or preset.border_color or beautiful.bg_focus or '#535d6c' local notification = { screen = screen, destroy_cb = destroy_cb, timeout = timeout } - local textbox_context = {dpi=bt.xresources.get_dpi(s)} - -- replace notification if needed if args.replaces_id then local obj = naughty.getById(args.replaces_id) @@ -532,7 +530,7 @@ function naughty.notify(args) actiontextbox:set_font(font) actiontextbox:set_markup(string.format('%s', action)) -- calculate the height and width - local w, h = actiontextbox:fit(textbox_context, -1, -1) -- Hack! :( + local w, h = actiontextbox:get_preferred_size(s) local height = h + 2 * margin local width = w + 2 * margin @@ -600,9 +598,20 @@ function naughty.notify(args) if hover_timeout then notification.box:connect_signal("mouse::enter", hover_destroy) end + -- calculate the width + if not width then + local w, h = textbox:get_preferred_size(s) + width = w + (iconbox and icon_w + 2 * margin or 0) + 2 * margin + end + + if width < actions_max_width then + width = actions_max_width + end + -- calculate the height if not height then - local w, h = textbox:fit(textbox_context, -1, -1) -- Hack! :-( + local w = width - (iconbox and icon_w + 2 * margin or 0) - 2 * margin + local h = textbox:get_height_for_width(w, s) if iconbox and icon_h + 2 * margin > h + 2 * margin then height = icon_h + 2 * margin else @@ -612,16 +621,6 @@ function naughty.notify(args) height = height + actions_total_height - -- calculate the width - if not width then - local w, h = textbox:fit(textbox_context, -1, -1) -- Hack! :-( - width = w + (iconbox and icon_w + 2 * margin or 0) + 2 * margin - end - - if width < actions_max_width then - width = actions_max_width - end - -- crop to workarea size if too big local workarea = capi.screen[screen].workarea if width > workarea.width - 2 * (border_width or 0) - 2 * (naughty.config.padding or 0) then diff --git a/lib/wibox/widget/textbox.lua b/lib/wibox/widget/textbox.lua index 90a37fe6..039cda3b 100644 --- a/lib/wibox/widget/textbox.lua +++ b/lib/wibox/widget/textbox.lua @@ -19,11 +19,8 @@ local error = error local textbox = { mt = {} } ---- Setup a pango layout for the given textbox and cairo context -local function setup_layout(box, width, height, dpi) - local layout = box._layout - layout.width = Pango.units_from_double(width) - layout.height = Pango.units_from_double(height) +--- Set the DPI of a Pango layout +local function setup_dpi(box, dpi) if box.dpi ~= dpi then box.dpi = dpi box._ctx:set_resolution(dpi) @@ -31,6 +28,13 @@ local function setup_layout(box, width, height, dpi) end end +--- Setup a pango layout for the given textbox and dpi +local function setup_layout(box, width, height, dpi) + box._layout.width = Pango.units_from_double(width) + box._layout.height = Pango.units_from_double(height) + setup_dpi(box, dpi) +end + --- Draw the given textbox on the given cairo context in the given geometry function textbox:draw(context, cr, width, height) setup_layout(self, width, height, context.dpi) @@ -46,18 +50,69 @@ function textbox:draw(context, cr, width, height) cr:show_layout(self._layout) end ---- Fit the given textbox -function textbox:fit(context, width, height) - setup_layout(self, width, height, context.dpi) +local function do_fit_return(self) local ink, logical = self._layout:get_pixel_extents() - if logical.width == 0 or logical.height == 0 then return 0, 0 end - return logical.width, logical.height end +--- Fit the given textbox +function textbox:fit(context, width, height) + setup_layout(self, width, height, context.dpi) + return do_fit_return(self) +end + +--- Get the preferred size of a textbox. +-- This returns the size that the textbox would use if infinite space were +-- available. +-- @tparam integer s The screen number on which the textbox will be displayed. +-- @treturn number The preferred width. +-- @treturn number The preferred height. +function textbox:get_preferred_size(s) + return self:get_preferred_size_at_dpi(beautiful.xresources.get_dpi(s)) +end + +--- Get the preferred height of a textbox at a given width. +-- This returns the height that the textbox would use when it is limited to the +-- given width. +-- @tparam number width The available width. +-- @tparam integer s The screen number on which the textbox will be displayed. +-- @treturn number The needed height. +function textbox:get_height_for_width(width, s) + return self:get_height_for_width_at_dpi(width, beautiful.xresources.get_dpi(s)) +end + +--- Get the preferred size of a textbox. +-- This returns the size that the textbox would use if infinite space were +-- available. +-- @tparam number dpi The DPI value to render at. +-- @treturn number The preferred width. +-- @treturn number The preferred height. +function textbox:get_preferred_size_at_dpi(dpi) + local max_lines = 2^20 + setup_dpi(self, dpi) + self._layout.width = -1 -- no width set + self._layout.height = -max_lines -- show this many lines per paragraph + return do_fit_return(self) +end + +--- Get the preferred height of a textbox at a given width. +-- This returns the height that the textbox would use when it is limited to the +-- given width. +-- @tparam number width The available width. +-- @tparam number dpi The DPI value to render at. +-- @treturn number The needed height. +function textbox:get_height_for_width_at_dpi(width, dpi) + local max_lines = 2^20 + setup_dpi(self, dpi) + self._layout.width = Pango.units_from_double(width) + self._layout.height = -max_lines -- show this many lines per paragraph + local w, h = do_fit_return(self) + return h +end + --- Set the text of the textbox (with -- [Pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html)). -- @tparam string text The text to set. This can contain pango markup (e.g.