diff --git a/lib/awful/init.lua.in b/lib/awful/init.lua.in index d5644ef67..9954a0f2b 100644 --- a/lib/awful/init.lua.in +++ b/lib/awful/init.lua.in @@ -22,6 +22,7 @@ require("awful.key") require("awful.button") require("awful.wibox") require("awful.startup_notification") +require("awful.tooltip") --- AWesome Functions very UsefuL module("awful") diff --git a/lib/awful/tooltip.lua.in b/lib/awful/tooltip.lua.in new file mode 100644 index 000000000..a1b03e20e --- /dev/null +++ b/lib/awful/tooltip.lua.in @@ -0,0 +1,230 @@ +------------------------------------------------------------------------- +-- @author Sébastien Gross <seb•ɱɩɲʋʃ•awesome•ɑƬ•chezwam•ɖɵʈ•org> +-- @copyright 2009 Sébastien Gross +-- @release @AWESOME_VERSION@ +------------------------------------------------------------------------- + +local mouse = mouse +local widget = widget +local wibox = wibox +local screen = screen +local timer = timer +local a_placement = require("awful.placement") +local beautiful = require("beautiful") +local setmetatable = setmetatable +local ipairs = ipairs + +--- Tooltip module for awesome objects. +-- A tooltip is a small hint displayed when the mouse cursor +-- hovers a specific item. +-- In awesome, a tooltip can be linked with almost any +-- object having a add_signal() method and receiving +-- mouse::enter and mouse::leave signals. +--

How to create a tooltip?
+-- +-- myclock = awful.widget.textclock({}, "%T", 1)
+-- myclock_t = awful.tooltip({
+-- objects = { K },
+-- timer_function = function()
+-- return os.date("Today is %A %B %d %Y\nThe time is %T")
+-- end,
+-- })
+--
+--

+--

How to add the same tooltip to several objects?
+-- +-- myclock_t:add_to_object(obj1)
+-- myclock_t:add_to_object(obj2)
+--
+-- Now the same tooltip is attached to K, obj1, +-- obj2.
+--

+--

How to remove tooltip from many objects?
+-- +-- myclock_t:remove_from_object(obj1)
+-- myclock_t:remove_from_object(obj2)
+--
+-- Now the same tooltip is only attached to K.
+--

+module("awful.tooltip") + +local data = setmetatable({}, { __mode = 'k' }) + +--- Tooltip object definition. +-- @name tooltip +-- @field wibox The wibox displaying the tooltip. +-- @field visible True if tooltip is visible. +-- @class table + +-- Tooltip private data. +-- @name awful.tooltip.data +-- @field fg tooltip foreground color. +-- @field font Tooltip font. +-- @field hide The hide() function. +-- @field show The show() function. +-- @field timer The text update timer. +-- @field timer_function The text update timer function. + +-- Place to tooltip on th screen. +-- @param self A tooltip object. +local function place(self) + a_placement.under_mouse(self.wibox) + a_placement.no_offscreen(self.wibox) +end + +-- Place the tooltip under the mouse. +-- @param self A tooltip object. +local function set_geometry(self) + local my_geo = self.wibox:geometry() + -- calculate width / height + n_s = self.wibox.widgets[1]:extents() + if my_geo.width ~= n_s.width or my_geo.height ~= n_s.height then + self.wibox:geometry(n_s) + place(self) + end +end + +-- Show a tooltip. +-- @param self The tooltip to show. +local function show(self) + -- do nothing if the tooltip is already shown + if self.visible then return end + if data[self].timer then + if not data[self].timer.started then + -- make sure the tooltip is on the same screen as the mouse + self.wibox.screen = mouse.screen + data[self].timer_function() + data[self].timer:start() + end + end + place(self) + self.wibox.visible = true + self.visible = true +end + +-- Hide a tooltip. +-- @param self The tooltip to hide. +local function hide(self) + -- do nothing if the tooltip is already hidden + if not self.visible then return end + if data[self].timer then + if data[self].timer.started then + data[self].timer:stop() + end + end + self.visible = false + self.wibox.visible = false +end + +--- Change displayed text. +-- @param self The tooltip object. +-- @param text New tooltip text. +local function set_text(self, text) + self.wibox.widgets[1].text = '' .. text .. "" +end + +--- Change the tooltip's update interval. +-- @param self A tooltip object. +-- @param timeout The timeout value. +local function set_timeout(self, timeout) + if data[self].timer then + data[self].timer.timeout = timeout + end +end + +-- Load Default values. +-- @param self A tooltip object. +local function set_defaults(self) + self.wibox.border_width = beautiful.tooltip_border_width or beautiful.border_width or 1 + self.wibox.border_color = beautiful.tooltip_border_color or beautiful.border_normal or "#ffcb60" + self.wibox.opacity = beautiful.tooltip_opacity or 1 + self.wibox.bg = beautiful.tooltip_bg_color or beautiful.bg_focus or "#ffcb60" + data[self].fg = beautiful.tooltip_fg_color or beautiful.fg_focus or "#000000" + data[self].font = beautiful.tooltip_font or beautiful.font or "terminus 6" +end + +--- Add tooltip to an object. +-- @param self The tooltip. +-- @param object An object. +local function add_to_object(self, object) + object:add_signal("mouse::enter", data[self].show) + object:add_signal("mouse::leave", data[self].hide) +end + +--- Remove tooltip from an object. +-- @param self The tooltip. +-- @param object An object. +local function remove_from_object(self, object) + object:remove_signal("mouse::enter", data[self].show) + object:remove_signal("mouse::leave", data[self].hide) +end + + +--- Create a new tooltip and link it to a widget. +-- @param args Arguments for tooltip creation may containt:
+-- timeout: The timeout value for update_func.
+-- timer_function: A function to dynamicaly change the tooltip +-- text.
+-- objects: A list of objects linked to the tooltip.
+-- @return The created tooltip. +-- @see add_to_object +-- @see set_timeout +-- @see set_text +local function new(args) + local self = { + wibox = wibox({ }), + visible = false, + } + + local my_textbox = widget({ + type = "textbox", + name = "tooltip_textbox", + align="right"}) + + -- private data + data[self] = { + show = function() show(self) end, + hide = function() hide(self) end + } + + -- export functions + self.set_text = set_text + self.set_timeout = set_timeout + self.add_to_object = add_to_object + self.remove_from_object = remove_from_object + + set_defaults(self) + + -- setup the timer action only if needed + if args.timer_function then + data[self].timer = timer { timeout = args.timeout and args.timeout or 1 } + data[self].timer_function = function() + self:set_text(args.timer_function()) + set_geometry(self) + end + data[self].timer:add_signal("timeout", data[self].timer_function) + end + + -- set tooltip properties + self.wibox.visible = false + -- Who want a non ontop tooltip ? + self.wibox.ontop = true + self.wibox.widgets = { my_textbox } + + -- add some signals on both the tooltip and widget + self.wibox:add_signal("mouse::enter", data[self].hide) + + -- Add tooltip to objects + if args.objects then + for _, object in ipairs(args.objects) do + self:add_to_object(object) + end + end + + return self +end + +setmetatable(_M, { __call = function(_, ...) return new(...) end }) + +-- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78 diff --git a/lib/awful/wibox.lua.in.rej b/lib/awful/wibox.lua.in.rej new file mode 100644 index 000000000..d685d287d --- /dev/null +++ b/lib/awful/wibox.lua.in.rej @@ -0,0 +1,9 @@ +diff a/lib/awful/wibox.lua.in b/lib/awful/wibox.lua.in (rejected hunks) +@@ -17,6 +17,7 @@ local ipairs = ipairs + local table = table + local type = type + local image = image ++local error = error + + --- Wibox module for awful. + -- This module allows you to easily create wibox and attach them to the edge of