Merge pull request #2510 from Elv13/xmas_2k18_4
Add the popup widget take 2 (only relevant commits)
This commit is contained in:
commit
c87e7aad56
|
@ -1,7 +1,6 @@
|
||||||
# The declarative layout system
|
# The AwesomeWM widget system
|
||||||
|
|
||||||
The declarative layout system provides an alternative to the imperative system.
|
This document explains how to define, place and manage widgets.
|
||||||
It is inspired by the one used by Awesome 3.2-3.4 and the Qt QML style.
|
|
||||||
|
|
||||||
## The default widgets
|
## The default widgets
|
||||||
|
|
||||||
|
@ -29,7 +28,127 @@ configurable rules.
|
||||||
|
|
||||||
@DOC_layout_WIDGET_LIST@
|
@DOC_layout_WIDGET_LIST@
|
||||||
|
|
||||||
## Placing widgets
|
### The different type of widget boxes (Wibox)
|
||||||
|
|
||||||
|
The Awesome API uses the word "wibox" (widget box) to describe an area of the
|
||||||
|
screen filled with widgets. There are many subvariants of wiboxes with
|
||||||
|
specialized roles such as widget bars or tooltips. All variants mostly share the
|
||||||
|
same characteristics, but add some extra features to make those specialized
|
||||||
|
widget boxes easier to work with.
|
||||||
|
|
||||||
|
@DOC_awful_popup_wiboxtypes_EXAMPLE@
|
||||||
|
|
||||||
|
The normal `wibox` is the base class for each of these types. It is extremely
|
||||||
|
flexible and allows to place just about anything on the screen. However it
|
||||||
|
requires a lot of repetitive boilerplate code to use directly. For example,
|
||||||
|
the user needs to compute the optimal size by hand or use `awful.placement`.
|
||||||
|
|
||||||
|
The `awful.wibar` specialization allows to attach a `wibox` to a screen edge
|
||||||
|
and prevents clients from using this area when tiled.
|
||||||
|
|
||||||
|
The `awful.popup` allows to easily place widgets on the screen. It automatically
|
||||||
|
resizes itself to fit the optimal widget size. It also has helper properties
|
||||||
|
and methods to make it easy to place it on the screen. It supports absolute
|
||||||
|
positioning, relative positioning, and manual positioning.
|
||||||
|
|
||||||
|
The `awful.tooltip` is a very simple `wibox` that allows to display text next
|
||||||
|
to an object such as the mouse.
|
||||||
|
|
||||||
|
Finally, the `awful.titlebar`, while not technically a real `wibox`, acts
|
||||||
|
exactly the same way and allows to attach widgets on each side of clients.
|
||||||
|
|
||||||
|
## The different syntaxes to initiate widgets
|
||||||
|
|
||||||
|
Awesome provides 2 totally different API access styles to manage widgets. Both
|
||||||
|
suit different use cases. Under the hood, both produce the
|
||||||
|
exact same code. Consider the declarative API to be compiled into the
|
||||||
|
imperative syntax when loaded. Also note that in contrast to technologies such
|
||||||
|
as QML, it is interpreted only once and isn't automatically updated when
|
||||||
|
values change.
|
||||||
|
|
||||||
|
The **imperative** widget initialization is similar to QtWidgets, GTK and Win32.
|
||||||
|
You create the object, then set the property and add the widget as a child to
|
||||||
|
another already declared widget. It is quite simple to use but very verbose
|
||||||
|
and full of boilerplate code. The imperative API also offers properties both
|
||||||
|
with accessors or directly. It is useful when creating highly dynamic layouts
|
||||||
|
where widgets are added and removed over the course of their lifecycle.
|
||||||
|
|
||||||
|
The **declarative** syntax resembles HTML style code
|
||||||
|
written in JSON or YAML. The widget instances are created automatically and
|
||||||
|
the hierarchy is related to the table nesting (indentation). It is preferred
|
||||||
|
when creating static layouts that won't change over the course of their
|
||||||
|
lifecycle.
|
||||||
|
|
||||||
|
Here is the same code written in both the imperative and declarative style
|
||||||
|
|
||||||
|
**Imperative with accessors**
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
local bg = wibox.container.background()
|
||||||
|
bg:set_bg("#ff0000")
|
||||||
|
|
||||||
|
local tb1 = wibox.widget.textbox()
|
||||||
|
local tb2 = wibox.widget.textbox("bar")
|
||||||
|
|
||||||
|
tb1:set_text("foo")
|
||||||
|
tb2:set_text("bar")
|
||||||
|
|
||||||
|
local l = wibox.layout.fixed.vertical()
|
||||||
|
l:add(tb1)
|
||||||
|
l:add(tb2)
|
||||||
|
|
||||||
|
bg:set_widget(l)
|
||||||
|
|
||||||
|
**Imperative with properties**
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
local bg = wibox.container.background()
|
||||||
|
bg.bg = "#ff0000"
|
||||||
|
|
||||||
|
local tb1 = wibox.widget.textbox("foo")
|
||||||
|
local tb2 = wibox.widget.textbox("bar")
|
||||||
|
|
||||||
|
tb1.text = "foo"
|
||||||
|
tb2.text = "bar"
|
||||||
|
|
||||||
|
local l = wibox.layout.fixed.vertical()
|
||||||
|
l:add(tb1)
|
||||||
|
l:add(tb2)
|
||||||
|
|
||||||
|
bg.widget = l
|
||||||
|
|
||||||
|
**Declarative**
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
local bg = wibox.widget {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = "foo",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = "bar",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
layout = wibox.layout.fixed.vertical
|
||||||
|
},
|
||||||
|
bg = "#ff0000",
|
||||||
|
widget = wibox.container.background
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The Awesome documentation mostly uses the declarative style for consistency,
|
||||||
|
but both are **always** available. Note that each style can be mixed with other
|
||||||
|
styles, but this creates very confusing code and should be avoided.
|
||||||
|
|
||||||
|
## Creating and placing widgets using the declarative style
|
||||||
|
|
||||||
|
The examples below explain in detail how to use the declarative layout system.
|
||||||
|
The imperative system is quite self explanatory and the respective widget API
|
||||||
|
documentation should be enough for most.
|
||||||
|
|
||||||
### A simple layout
|
### A simple layout
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ return
|
||||||
ewmh = require("awful.ewmh");
|
ewmh = require("awful.ewmh");
|
||||||
titlebar = require("awful.titlebar");
|
titlebar = require("awful.titlebar");
|
||||||
rules = require("awful.rules");
|
rules = require("awful.rules");
|
||||||
|
popup = require("awful.popup");
|
||||||
spawn = spawn;
|
spawn = spawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,467 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
--- An auto-resized, free floating or modal wibox built around a widget.
|
||||||
|
--
|
||||||
|
-- This type of widget box (wibox) is auto closed when being clicked on and is
|
||||||
|
-- automatically resized to the size of its main widget.
|
||||||
|
--
|
||||||
|
-- Note that the widget itself should have a finite size. If something like a
|
||||||
|
-- `wibox.layout.flex` is used, then the size would be unlimited and an error
|
||||||
|
-- will be printed. The `wibox.layout.fixed`, `wibox.container.constraint`,
|
||||||
|
-- `forced_width` and `forced_height` are recommended.
|
||||||
|
--
|
||||||
|
--@DOC_awful_popup_simple_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- Here is an example of how to create an alt-tab like dialog by leveraging
|
||||||
|
-- the `awful.widget.tasklist`.
|
||||||
|
--
|
||||||
|
--@DOC_awful_popup_alttab_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @author Emmanuel Lepage Vallee
|
||||||
|
-- @copyright 2016 Emmanuel Lepage Vallee
|
||||||
|
-- @classmod awful.popup
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
local wibox = require( "wibox" )
|
||||||
|
local util = require( "awful.util" )
|
||||||
|
local placement = require( "awful.placement" )
|
||||||
|
local xresources= require("beautiful.xresources")
|
||||||
|
local timer = require( "gears.timer" )
|
||||||
|
local capi = {mouse = mouse}
|
||||||
|
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
local main_widget = {}
|
||||||
|
|
||||||
|
-- Get the optimal direction for the wibox
|
||||||
|
-- This (try to) avoid going offscreen
|
||||||
|
local function set_position(self)
|
||||||
|
-- First, if there is size to be applied, do it
|
||||||
|
if self._private.next_width then
|
||||||
|
self.width = self._private.next_width
|
||||||
|
self._private.next_width = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._private.next_height then
|
||||||
|
self.height = self._private.next_height
|
||||||
|
self._private.next_height = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local pf = self._private.placement
|
||||||
|
|
||||||
|
if pf == false then return end
|
||||||
|
|
||||||
|
if pf then
|
||||||
|
pf(self, {bounding_rect = self.screen.geometry})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local geo = self._private.widget_geo
|
||||||
|
|
||||||
|
if not geo then return end
|
||||||
|
|
||||||
|
local _, pos_name, anchor_name = placement.next_to(self, {
|
||||||
|
preferred_positions = self._private.preferred_directions,
|
||||||
|
geometry = geo,
|
||||||
|
preferred_anchors = self._private.preferred_anchors,
|
||||||
|
offset = self._private.offset or { x = 0, y = 0},
|
||||||
|
})
|
||||||
|
|
||||||
|
if pos_name ~= self._private.current_position then
|
||||||
|
local old = self._private.current_position
|
||||||
|
self._private.current_position = pos_name
|
||||||
|
self:emit_signal("property::current_position", pos_name, old)
|
||||||
|
end
|
||||||
|
|
||||||
|
if anchor_name ~= self._private.current_anchor then
|
||||||
|
local old = self._private.current_anchor
|
||||||
|
self._private.current_anchor = anchor_name
|
||||||
|
self:emit_signal("property::current_anchor", anchor_name, old)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the wibox size taking into consideration the limits
|
||||||
|
local function apply_size(self, width, height, set_pos)
|
||||||
|
local prev_geo = self:geometry()
|
||||||
|
|
||||||
|
width = math.max(self._private.minimum_width or 1, math.ceil(width or 1))
|
||||||
|
height = math.max(self._private.minimum_height or 1, math.ceil(height or 1))
|
||||||
|
|
||||||
|
if self._private.maximum_width then
|
||||||
|
width = math.min(self._private.maximum_width, width)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._private.maximum_height then
|
||||||
|
height = math.min(self._private.maximum_height, height)
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private.next_width, self._private.next_height = width, height
|
||||||
|
|
||||||
|
if set_pos or width ~= prev_geo.width or height ~= prev_geo.height then
|
||||||
|
set_position(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Layout this widget
|
||||||
|
function main_widget:layout(context, width, height)
|
||||||
|
if self._private.widget then
|
||||||
|
local w, h = wibox.widget.base.fit_widget(
|
||||||
|
self,
|
||||||
|
context,
|
||||||
|
self._private.widget,
|
||||||
|
self._wb._private.maximum_width or 9999,
|
||||||
|
self._wb._private.maximum_height or 9999
|
||||||
|
)
|
||||||
|
timer.delayed_call(function()
|
||||||
|
apply_size(self._wb, w, h, true)
|
||||||
|
end)
|
||||||
|
return { wibox.widget.base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the widget that is drawn on top of the background
|
||||||
|
function main_widget:set_widget(widget)
|
||||||
|
if widget then
|
||||||
|
wibox.widget.base.check_widget(widget)
|
||||||
|
end
|
||||||
|
self._private.widget = widget
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
|
function main_widget:get_widget()
|
||||||
|
return self._private.widget
|
||||||
|
end
|
||||||
|
|
||||||
|
function main_widget:get_children_by_id(name)
|
||||||
|
return self._wb:get_children_by_id(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local popup = {}
|
||||||
|
|
||||||
|
--- Set the preferred popup position relative to its parent.
|
||||||
|
--
|
||||||
|
-- This allows, for example, to have a submenu that goes on the right of the
|
||||||
|
-- parent menu. If there is no space on the right, it tries on the left and so
|
||||||
|
-- on.
|
||||||
|
--
|
||||||
|
-- Valid directions are:
|
||||||
|
--
|
||||||
|
-- * left
|
||||||
|
-- * right
|
||||||
|
-- * top
|
||||||
|
-- * bottom
|
||||||
|
--
|
||||||
|
-- The basic use case for this method is to give it a parent wibox:
|
||||||
|
--
|
||||||
|
-- @DOC_awful_popup_position1_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- As demonstrated by this second example, it is also possible to use a widget
|
||||||
|
-- as a parent object:
|
||||||
|
--
|
||||||
|
-- @DOC_awful_popup_position2_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property preferred_positions
|
||||||
|
-- @tparam table|string preferred_positions A position name or an ordered
|
||||||
|
-- table of positions
|
||||||
|
-- @see awful.placement.next_to
|
||||||
|
-- @see awful.popup.preferred_anchors
|
||||||
|
|
||||||
|
function popup:set_preferred_positions(pref_pos)
|
||||||
|
self._private.preferred_directions = pref_pos
|
||||||
|
set_position(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the preferred popup anchors relative to the parent.
|
||||||
|
--
|
||||||
|
-- The possible values are:
|
||||||
|
--
|
||||||
|
-- * front
|
||||||
|
-- * middle
|
||||||
|
-- * back
|
||||||
|
--
|
||||||
|
-- For details information, see the `awful.placement.next_to` documentation.
|
||||||
|
--
|
||||||
|
-- In this example, it is possible to see the effect of having a fallback
|
||||||
|
-- preferred anchors when the popup would otherwise not fit:
|
||||||
|
--
|
||||||
|
-- @DOC_awful_popup_anchors_EXAMPLE@
|
||||||
|
--
|
||||||
|
-- @property preferred_anchors
|
||||||
|
-- @tparam table|string preferred_anchors Either a single anchor name or a table
|
||||||
|
-- ordered by priority.
|
||||||
|
-- @see awful.placement.next_to
|
||||||
|
-- @see awful.popup.preferred_positions
|
||||||
|
|
||||||
|
function popup:set_preferred_anchors(pref_anchors)
|
||||||
|
self._private.preferred_anchors = pref_anchors
|
||||||
|
set_position(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- The current position relative to the parent object.
|
||||||
|
--
|
||||||
|
-- If there is a parent object (widget, wibox, wibar, client or the mouse), then
|
||||||
|
-- this property returns the current position. This is determined using
|
||||||
|
-- `preferred_positions`. It is usually the preferred position, but when there
|
||||||
|
-- isn't enough space, it can also be one of the fallback.
|
||||||
|
--
|
||||||
|
-- @property current_position
|
||||||
|
-- @tparam string current_position Either "left", "right", "top" or "bottom"
|
||||||
|
|
||||||
|
function popup:get_current_position()
|
||||||
|
return self._private.current_position
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the current anchor relative to the parent object.
|
||||||
|
--
|
||||||
|
-- If there is a parent object (widget, wibox, wibar, client or the mouse), then
|
||||||
|
-- this property returns the current anchor. The anchor is the "side" of the
|
||||||
|
-- parent object on which the popup is based on. It will "grow" in the
|
||||||
|
-- opposite direction from the anchor.
|
||||||
|
--
|
||||||
|
-- @property current_anchor
|
||||||
|
-- @tparam string current_anchor Either "front", "middle", "back"
|
||||||
|
|
||||||
|
function popup:get_current_anchor()
|
||||||
|
return self._private.current_anchor
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Move the wibox to a position relative to `geo`.
|
||||||
|
-- This will try to avoid overlapping the source wibox and auto-detect the right
|
||||||
|
-- direction to avoid going off-screen.
|
||||||
|
--
|
||||||
|
-- @param[opt=mouse] obj An object such as a wibox, client or a table entry
|
||||||
|
-- returned by `wibox:find_widgets()`.
|
||||||
|
-- @see awful.placement.next_to
|
||||||
|
-- @see awful.popup.preferred_positions
|
||||||
|
-- @see awful.popup.preferred_anchors
|
||||||
|
-- @treturn table The new geometry
|
||||||
|
function popup:move_next_to(obj)
|
||||||
|
if self._private.is_relative == false then return end
|
||||||
|
|
||||||
|
self._private.widget_geo = obj
|
||||||
|
|
||||||
|
obj = obj or capi.mouse
|
||||||
|
|
||||||
|
if obj._apply_size_now then
|
||||||
|
obj:_apply_size_now(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.visible = true
|
||||||
|
|
||||||
|
self:_apply_size_now(true)
|
||||||
|
|
||||||
|
self._private.widget_geo = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Bind the popup to a widget button press.
|
||||||
|
--
|
||||||
|
-- @tparam widget widget The widget
|
||||||
|
-- @tparam[opt=1] number button The button index
|
||||||
|
function popup:bind_to_widget(widget, button)
|
||||||
|
if not self._private.button_for_widget then
|
||||||
|
self._private.button_for_widget = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private.button_for_widget[widget] = button or 1
|
||||||
|
widget:connect_signal("button::press", self._private.show_fct)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Unbind the popup from a widget button.
|
||||||
|
-- @tparam widget widget The widget
|
||||||
|
function popup:unbind_to_widget(widget)
|
||||||
|
widget:disconnect_signal("button::press", self._private.show_fct)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Hide the popup when right clicked.
|
||||||
|
--
|
||||||
|
-- @property hide_on_right_click
|
||||||
|
-- @tparam[opt=false] boolean hide_on_right_click
|
||||||
|
|
||||||
|
function popup:set_hide_on_right_click(value)
|
||||||
|
self[value and "connect_signal" or "disconnect_signal"](
|
||||||
|
self, "button::press", self._private.hide_fct
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- The popup minimum width.
|
||||||
|
-- @property minimum_width
|
||||||
|
-- @tparam[opt=1] number The minimum width
|
||||||
|
|
||||||
|
--- The popup minimum height.
|
||||||
|
-- @property minimum_height
|
||||||
|
-- @tparam[opt=1] number The minimum height
|
||||||
|
|
||||||
|
--- The popup minimum width.
|
||||||
|
-- @property maxmimum_width
|
||||||
|
-- @tparam[opt=1] number The maxmimum width
|
||||||
|
|
||||||
|
--- The popup maximum height.
|
||||||
|
-- @property maximum_height
|
||||||
|
-- @tparam[opt=1] number The maximum height
|
||||||
|
|
||||||
|
for _, orientation in ipairs {"_width", "_height"} do
|
||||||
|
for _, limit in ipairs {"minimum", "maximum"} do
|
||||||
|
popup["set_"..limit..orientation] = function(self, value)
|
||||||
|
self._private[limit..orientation] = value
|
||||||
|
self._private.container:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- The distance between the popup and its parent (if any).
|
||||||
|
--
|
||||||
|
-- Here is an example of 5 popups stacked one below the other with an y axis
|
||||||
|
-- offset (spacing).
|
||||||
|
--
|
||||||
|
-- @DOC_awful_popup_position3_EXAMPLE@
|
||||||
|
-- @property offset
|
||||||
|
-- @tparam table|number offset An integer value or a `{x=, y=}` table.
|
||||||
|
-- @tparam[opt=offset] number offset.x The horizontal distance.
|
||||||
|
-- @tparam[opt=offset] number offset.y The vertical distance.
|
||||||
|
|
||||||
|
function popup:set_offset(offset)
|
||||||
|
|
||||||
|
if type(offset) == "number" then
|
||||||
|
offset = {
|
||||||
|
x = offset or 0,
|
||||||
|
y = offset or 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local oldoff = self._private.offset or {x=0, y=0}
|
||||||
|
|
||||||
|
if oldoff.x == offset.x and oldoff.y == offset.y then return end
|
||||||
|
|
||||||
|
offset.x, offset.y = offset.x or oldoff.x or 0, offset.y or oldoff.y or 0
|
||||||
|
|
||||||
|
self._private.offset = offset
|
||||||
|
|
||||||
|
self:_apply_size_now(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the placement function.
|
||||||
|
-- @tparam[opt=next_to] function|string|boolean The placement function or name
|
||||||
|
-- (or false to disable placement)
|
||||||
|
-- @property placement
|
||||||
|
-- @param function
|
||||||
|
|
||||||
|
function popup:set_placement(f)
|
||||||
|
if type(f) == "string" then
|
||||||
|
f = placement[f]
|
||||||
|
end
|
||||||
|
|
||||||
|
self._private.placement = f
|
||||||
|
self:_apply_size_now(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- For the tests and the race condition when 2 popups are placed next to each
|
||||||
|
-- other.
|
||||||
|
function popup:_apply_size_now(skip_set)
|
||||||
|
if not self.widget then return end
|
||||||
|
|
||||||
|
local w, h = wibox.widget.base.fit_widget(
|
||||||
|
self.widget,
|
||||||
|
{dpi= self.screen.dpi or xresources.get_dpi()},
|
||||||
|
self.widget,
|
||||||
|
self._private.maximum_width or 9999,
|
||||||
|
self._private.maximum_height or 9999
|
||||||
|
)
|
||||||
|
|
||||||
|
-- It is important to do it for the obscure reason that calling `w:geometry()`
|
||||||
|
-- is actually mutating the state due to quantum determinism thanks to XCB
|
||||||
|
-- async nature... It is only true the very first time `w:geometry()` is
|
||||||
|
-- called
|
||||||
|
self.width = math.max(1, math.ceil(w or 1))
|
||||||
|
self.height = math.max(1, math.ceil(h or 1))
|
||||||
|
|
||||||
|
apply_size(self, w, h, skip_set ~= false)
|
||||||
|
end
|
||||||
|
|
||||||
|
function popup:set_widget(wid)
|
||||||
|
self._private.widget = wid
|
||||||
|
self._private.container:set_widget(wid)
|
||||||
|
end
|
||||||
|
|
||||||
|
function popup:get_widget()
|
||||||
|
return self._private.widget
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a new popup build around a passed in widget.
|
||||||
|
-- @tparam[opt=nil] table args
|
||||||
|
--@DOC_wibox_constructor_COMMON@
|
||||||
|
-- @tparam function args.placement The `awful.placement` function
|
||||||
|
-- @tparam string|table args.preferred_positions
|
||||||
|
-- @tparam string|table args.preferred_anchors
|
||||||
|
-- @tparam table|number args.offset The X and Y offset compared to the parent object
|
||||||
|
-- @tparam boolean args.hide_on_right_click Whether or not to hide the popup on
|
||||||
|
-- right clicks.
|
||||||
|
-- @function awful.popup
|
||||||
|
local function create_popup(_, args)
|
||||||
|
assert(args)
|
||||||
|
|
||||||
|
-- Temporarily remove the widget
|
||||||
|
local original_widget = args.widget
|
||||||
|
args.widget = nil
|
||||||
|
|
||||||
|
assert(original_widget, "The `awful.popup` requires a `widget` constructor argument")
|
||||||
|
|
||||||
|
local child_widget = wibox.widget.base.make_widget_from_value(original_widget)
|
||||||
|
|
||||||
|
local ii = wibox.widget.base.make_widget(child_widget, "awful.popup", {
|
||||||
|
enable_properties = true
|
||||||
|
})
|
||||||
|
|
||||||
|
util.table.crush(ii, main_widget, true)
|
||||||
|
|
||||||
|
-- Create a wibox to host the widget
|
||||||
|
local w = wibox(args or {})
|
||||||
|
|
||||||
|
rawset(w, "_private", {
|
||||||
|
container = ii,
|
||||||
|
preferred_directions = { "right", "left", "top", "bottom" },
|
||||||
|
preferred_anchors = { "back", "front", "middle" },
|
||||||
|
widget = child_widget
|
||||||
|
})
|
||||||
|
|
||||||
|
util.table.crush(w, popup)
|
||||||
|
|
||||||
|
ii:set_widget(child_widget)
|
||||||
|
|
||||||
|
-- Create the signal handlers
|
||||||
|
function w._private.show_fct(wdg, _, _, button, _, geo)
|
||||||
|
if button == w._private.button_for_widget[wdg] then
|
||||||
|
w:move_next_to(geo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function w._private.hide_fct()
|
||||||
|
w.visible = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore
|
||||||
|
args.widget = original_widget
|
||||||
|
|
||||||
|
-- Cross-link the wibox and widget
|
||||||
|
ii._wb = w
|
||||||
|
wibox.set_widget(w, ii)
|
||||||
|
|
||||||
|
--WARNING The order is important
|
||||||
|
-- First, apply the limits to avoid a flicker with large width or height
|
||||||
|
-- when set_position is called before the limits
|
||||||
|
for _,v in ipairs{"minimum_width", "minimum_height", "maximum_height",
|
||||||
|
"maximum_width", "offset", "placement","preferred_positions",
|
||||||
|
"preferred_anchors", "hide_on_right_click"} do
|
||||||
|
if args[v] ~= nil then
|
||||||
|
w["set_"..v](w, args[v])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Default to visible
|
||||||
|
if args.visible ~= false then
|
||||||
|
w.visible = true
|
||||||
|
end
|
||||||
|
|
||||||
|
return w
|
||||||
|
end
|
||||||
|
|
||||||
|
--@DOC_wibox_COMMON@
|
||||||
|
|
||||||
|
return setmetatable(module, {__call = create_popup})
|
|
@ -0,0 +1,59 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
popup = require("awful.popup"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE
|
||||||
|
tasklist = require("awful.widget.tasklist")} --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local gears = { shape = require("gears.shape") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
for _=1, 6 do --DOC_HIDE
|
||||||
|
local c = client.gen_fake {x = 80, y = 55, width=75, height=50} --DOC_HIDE
|
||||||
|
c.icon = beautiful.awesome_icon --DOC_HIDE
|
||||||
|
c.minimized = true --DOC_HIDE
|
||||||
|
end --DOC_HIDE
|
||||||
|
|
||||||
|
local tasklist_buttons = nil --DOC_HIDE
|
||||||
|
|
||||||
|
awful.popup {
|
||||||
|
widget = awful.widget.tasklist {
|
||||||
|
screen = screen[1],
|
||||||
|
filter = awful.widget.tasklist.filter.allscreen,
|
||||||
|
buttons = tasklist_buttons,
|
||||||
|
style = {
|
||||||
|
shape = gears.shape.rounded_rect,
|
||||||
|
},
|
||||||
|
layout = {
|
||||||
|
spacing = 5,
|
||||||
|
forced_num_rows = 2,
|
||||||
|
layout = wibox.layout.grid.horizontal
|
||||||
|
},
|
||||||
|
|
||||||
|
widget_template = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
id = "clienticon",
|
||||||
|
widget = awful.widget.clienticon,
|
||||||
|
},
|
||||||
|
margins = 4,
|
||||||
|
widget = wibox.container.margin,
|
||||||
|
},
|
||||||
|
id = "background_role",
|
||||||
|
forced_width = 48,
|
||||||
|
forced_height = 48,
|
||||||
|
widget = wibox.container.background,
|
||||||
|
create_callback = function(self, c, index, objects) --luacheck: no unused
|
||||||
|
self:get_children_by_id("clienticon")[1].client = c
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
border_color = "#777777",
|
||||||
|
border_width = 2,
|
||||||
|
ontop = true,
|
||||||
|
placement = awful.placement.centered,
|
||||||
|
shape = gears.shape.rounded_rect
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,70 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
popup = require("awful.popup"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE
|
||||||
|
tasklist = require("awful.widget.tasklist")} --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {width = 320, height = 240} --DOC_HIDE
|
||||||
|
screen._add_screen {x = 330, y = 0, width = 320, height = 240} --DOC_HIDE
|
||||||
|
|
||||||
|
local p = awful.popup { --DOC_HIDE
|
||||||
|
widget = wibox.widget { --DOC_HIDE
|
||||||
|
text = "Parent wibox", --DOC_HIDE
|
||||||
|
forced_width = 100, --DOC_HIDE
|
||||||
|
forced_height = 50, --DOC_HIDE
|
||||||
|
widget = wibox.widget.textbox --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
border_color = "#777777", --DOC_HIDE
|
||||||
|
border_width = 2, --DOC_HIDE
|
||||||
|
ontop = true, --DOC_HIDE
|
||||||
|
screen = screen[1], --DOC_HIDE
|
||||||
|
placement = awful.placement.top, --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
p:_apply_size_now() --DOC_HIDE
|
||||||
|
|
||||||
|
local p2 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "A popup",
|
||||||
|
forced_height = 100,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = "#777777",
|
||||||
|
border_width = 2,
|
||||||
|
preferred_positions = "right",
|
||||||
|
preferred_anchors = {"front", "back"},
|
||||||
|
}
|
||||||
|
p2:move_next_to(p) --DOC_HIDE
|
||||||
|
|
||||||
|
local p3 = awful.popup { --DOC_HIDE
|
||||||
|
widget = wibox.widget { --DOC_HIDE
|
||||||
|
text = "Parent wibox2", --DOC_HIDE
|
||||||
|
forced_width = 100, --DOC_HIDE
|
||||||
|
forced_height = 50, --DOC_HIDE
|
||||||
|
widget = wibox.widget.textbox --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
border_color = "#777777", --DOC_HIDE
|
||||||
|
border_width = 2, --DOC_HIDE
|
||||||
|
ontop = true, --DOC_HIDE
|
||||||
|
screen = screen[2], --DOC_HIDE
|
||||||
|
placement = awful.placement.bottom, --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
p3:_apply_size_now() --DOC_HIDE
|
||||||
|
|
||||||
|
local p4 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "A popup2",
|
||||||
|
forced_height = 100,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = "#777777",
|
||||||
|
border_width = 2,
|
||||||
|
preferred_positions = "right",
|
||||||
|
screen = screen[2], --DOC_HIDE
|
||||||
|
preferred_anchors = {"front", "back"},
|
||||||
|
}
|
||||||
|
p4:move_next_to(p3) --DOC_HIDE
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,38 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
popup = require("awful.popup"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE
|
||||||
|
tasklist = require("awful.widget.tasklist")} --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
local p = awful.popup { --DOC_HIDE
|
||||||
|
widget = wibox.widget { --DOC_HIDE
|
||||||
|
text = "Parent wibox", --DOC_HIDE
|
||||||
|
forced_width = 100, --DOC_HIDE
|
||||||
|
forced_height = 100, --DOC_HIDE
|
||||||
|
widget = wibox.widget.textbox --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
border_color = "#777777", --DOC_HIDE
|
||||||
|
border_width = 2, --DOC_HIDE
|
||||||
|
ontop = true, --DOC_HIDE
|
||||||
|
placement = awful.placement.centered, --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
p:_apply_size_now() --DOC_HIDE
|
||||||
|
|
||||||
|
for _, v in ipairs {"left", "right", "bottom", "top"} do
|
||||||
|
local p2 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "On the "..v,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = "#777777",
|
||||||
|
border_width = 2,
|
||||||
|
preferred_positions = v,
|
||||||
|
ontop = true,
|
||||||
|
}
|
||||||
|
p2:move_next_to(p)
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,61 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
popup = require("awful.popup"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE
|
||||||
|
tasklist = require("awful.widget.tasklist")} --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local gears = { shape = require("gears.shape"), timer=require("gears.timer") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
local p = awful.popup { --DOC_HIDE
|
||||||
|
widget = wibox.widget { --DOC_HIDE
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox }, --DOC_HIDE
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox }, --DOC_HIDE
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox }, --DOC_HIDE
|
||||||
|
{ --DOC_HIDE
|
||||||
|
{ --DOC_HIDE
|
||||||
|
text = "Selected", --DOC_HIDE
|
||||||
|
widget = wibox.widget.textbox --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
bg = beautiful.bg_highlight, --DOC_HIDE
|
||||||
|
widget = wibox.container.background --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox }, --DOC_HIDE
|
||||||
|
{ text = "Item", widget = wibox.widget.textbox }, --DOC_HIDE
|
||||||
|
forced_width = 100, --DOC_HIDE
|
||||||
|
widget = wibox.layout.fixed.vertical --DOC_HIDE
|
||||||
|
}, --DOC_HIDE
|
||||||
|
border_color = "#ff0000", --DOC_HIDE
|
||||||
|
border_width = 2, --DOC_HIDE
|
||||||
|
placement = awful.placement.centered, --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
p:_apply_size_now() --DOC_HIDE
|
||||||
|
awesome.emit_signal("refresh") --DOC_HIDE
|
||||||
|
p._drawable._do_redraw() --DOC_HIDE
|
||||||
|
|
||||||
|
--DOC_HIDE Necessary as the widgets are drawn later
|
||||||
|
gears.timer.delayed_call(function() --DOC_HIDE
|
||||||
|
-- Get the 4th textbox --DOC_HIDE
|
||||||
|
local list = p:find_widgets(30, 40) --DOC_HIDE
|
||||||
|
mouse.coords {x= 120, y=125} --DOC_HIDE
|
||||||
|
mouse.push_history() --DOC_HIDE
|
||||||
|
local textboxinstance = list[#list] --DOC_HIDE
|
||||||
|
|
||||||
|
for _, v in ipairs {"left", "right"} do
|
||||||
|
local p2 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "On the "..v,
|
||||||
|
forced_height = 100,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = "#0000ff",
|
||||||
|
preferred_positions = v,
|
||||||
|
border_width = 2,
|
||||||
|
}
|
||||||
|
p2:move_next_to(textboxinstance, v)
|
||||||
|
end
|
||||||
|
end) --DOC_HIDE
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,34 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
popup = require("awful.popup"), --DOC_HIDE
|
||||||
|
placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
widget = {clienticon =require("awful.widget.clienticon"), --DOC_HIDE
|
||||||
|
tasklist = require("awful.widget.tasklist")} --DOC_HIDE
|
||||||
|
} --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
local previous = nil
|
||||||
|
|
||||||
|
for i=1, 5 do
|
||||||
|
local p2 = awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
text = "Hello world! "..i.." aaaa.",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
preferred_positions = "bottom",
|
||||||
|
border_width = 2,
|
||||||
|
preferred_anchors = "back",
|
||||||
|
placement = (not previous) and awful.placement.top or nil,
|
||||||
|
offset = {
|
||||||
|
y = 10,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p2:_apply_size_now() --DOC_HIDE
|
||||||
|
p2:move_next_to(previous)
|
||||||
|
previous = p2
|
||||||
|
previous:_apply_size_now() --DOC_HIDE
|
||||||
|
end
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,42 @@
|
||||||
|
--DOC_GEN_IMAGE --DOC_HIDE
|
||||||
|
local awful = { placement = require("awful.placement"), --DOC_HIDE
|
||||||
|
popup = require("awful.popup") } --DOC_HIDE --DOC_NO_USAGE
|
||||||
|
local gears = { shape = require("gears.shape") } --DOC_HIDE
|
||||||
|
local wibox = require("wibox") --DOC_HIDE
|
||||||
|
|
||||||
|
awful.popup {
|
||||||
|
widget = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = "foobar",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = "foobar",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
bg = "#ff00ff",
|
||||||
|
clip = true,
|
||||||
|
shape = gears.shape.rounded_bar,
|
||||||
|
widget = wibox.widget.background
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value = 0.5,
|
||||||
|
forced_height = 30,
|
||||||
|
forced_width = 100,
|
||||||
|
widget = wibox.widget.progressbar
|
||||||
|
},
|
||||||
|
layout = wibox.layout.fixed.vertical,
|
||||||
|
},
|
||||||
|
margins = 10,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
},
|
||||||
|
border_color = "#00ff00",
|
||||||
|
border_width = 5,
|
||||||
|
placement = awful.placement.top_left,
|
||||||
|
shape = gears.shape.rounded_rect,
|
||||||
|
visible = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,247 @@
|
||||||
|
--DOC_GEN_IMAGE
|
||||||
|
--DOC_HIDE_ALL
|
||||||
|
--DOC_NO_USAGE
|
||||||
|
local awful = require("awful")
|
||||||
|
local gears = require("gears")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local beautiful = require("beautiful") --DOC_HIDE
|
||||||
|
|
||||||
|
screen[1]._resize {width = 640, height = 480}
|
||||||
|
|
||||||
|
-- This example is used to show the various type of wibox awesome provides
|
||||||
|
-- and mimic the default config look
|
||||||
|
|
||||||
|
local c = client.gen_fake {hide_first=true}
|
||||||
|
|
||||||
|
c:geometry {
|
||||||
|
x = 50,
|
||||||
|
y = 350,
|
||||||
|
height = 100,
|
||||||
|
width = 150,
|
||||||
|
}
|
||||||
|
c._old_geo = {c:geometry()}
|
||||||
|
c:set_label("A client")
|
||||||
|
|
||||||
|
local wb = awful.wibar {
|
||||||
|
position = "top",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Create the same number of tags as the default config
|
||||||
|
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.layouts[1])
|
||||||
|
|
||||||
|
-- Only bother with widgets that are visible by default
|
||||||
|
local mykeyboardlayout = awful.widget.keyboardlayout()
|
||||||
|
local mytextclock = wibox.widget.textclock()
|
||||||
|
local mylayoutbox = awful.widget.layoutbox(screen[1])
|
||||||
|
local mytaglist = awful.widget.taglist(screen[1], awful.widget.taglist.filter.all, {})
|
||||||
|
local mytasklist = awful.widget.tasklist(screen[1], awful.widget.tasklist.filter.currenttags, {})
|
||||||
|
|
||||||
|
wb:setup {
|
||||||
|
layout = wibox.layout.align.horizontal,
|
||||||
|
{ -- Left widgets
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
awful.titlebar.widget.iconwidget(c), --looks close enough
|
||||||
|
mytaglist,
|
||||||
|
},
|
||||||
|
mytasklist, -- Middle widget
|
||||||
|
{ -- Right widgets
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
mykeyboardlayout,
|
||||||
|
mytextclock,
|
||||||
|
mylayoutbox,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- The popup
|
||||||
|
awful.popup {
|
||||||
|
widget = wibox.widget {
|
||||||
|
--TODO use the layoutlist for this example
|
||||||
|
awful.widget.taglist {
|
||||||
|
filter = awful.widget.taglist.filter.all,
|
||||||
|
screen = 1,
|
||||||
|
base_layout = wibox.widget {
|
||||||
|
spacing = 5,
|
||||||
|
forced_num_cols = 5,
|
||||||
|
layout = wibox.layout.grid.vertical,
|
||||||
|
},
|
||||||
|
widget_template = {
|
||||||
|
{
|
||||||
|
--TODO use the layoutlist for this example
|
||||||
|
-- {
|
||||||
|
-- id = 'icon_role',
|
||||||
|
-- forced_height = 22,
|
||||||
|
-- forced_width = 22,
|
||||||
|
-- widget = wibox.widget.imagebox,
|
||||||
|
-- },
|
||||||
|
{
|
||||||
|
id = "text_role",
|
||||||
|
forced_height = 22,
|
||||||
|
forced_width = 22,
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
margins = 4,
|
||||||
|
widget = wibox.container.margin,
|
||||||
|
},
|
||||||
|
id = 'background_role',
|
||||||
|
forced_width = 24,
|
||||||
|
forced_height = 24,
|
||||||
|
shape = gears.shape.rounded_rect,
|
||||||
|
widget = wibox.container.background,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
margins = 4,
|
||||||
|
widget = wibox.container.margin,
|
||||||
|
},
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
border_width = beautiful.border_width,
|
||||||
|
placement = awful.placement.centered,
|
||||||
|
ontop = true,
|
||||||
|
shape = gears.shape.rounded_rect
|
||||||
|
}
|
||||||
|
|
||||||
|
-- poor copy of awful.widget.calendar_widget until I fix its API to be less
|
||||||
|
-- insane.
|
||||||
|
local p10 = awful.popup {
|
||||||
|
widget = {
|
||||||
|
wibox.widget.calendar.month(os.date('*t')),
|
||||||
|
top = 30,
|
||||||
|
margins = 10,
|
||||||
|
layout = wibox.container.margin
|
||||||
|
},
|
||||||
|
preferred_anchors = "middle",
|
||||||
|
border_width = 2,
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
hide_on_right_click = true,
|
||||||
|
placement = function(d) return awful.placement.top_right(d, {
|
||||||
|
honor_workarea = true,
|
||||||
|
}) end,
|
||||||
|
shape = gears.shape.infobubble,
|
||||||
|
}
|
||||||
|
|
||||||
|
awesome.emit_signal("refresh")
|
||||||
|
p10:bind_to_widget(mytextclock)
|
||||||
|
|
||||||
|
-- The titlebar
|
||||||
|
|
||||||
|
local top_titlebar = awful.titlebar(c, {
|
||||||
|
height = 20,
|
||||||
|
bg_normal = "#ff0000",
|
||||||
|
})
|
||||||
|
|
||||||
|
top_titlebar : setup {
|
||||||
|
{ -- Left
|
||||||
|
awful.titlebar.widget.iconwidget(c),
|
||||||
|
layout = wibox.layout.fixed.horizontal
|
||||||
|
},
|
||||||
|
{ -- Middle
|
||||||
|
{ -- Title
|
||||||
|
align = "center",
|
||||||
|
widget = awful.titlebar.widget.titlewidget(c)
|
||||||
|
},
|
||||||
|
layout = wibox.layout.flex.horizontal
|
||||||
|
},
|
||||||
|
{ -- Right
|
||||||
|
awful.titlebar.widget.floatingbutton (c),
|
||||||
|
awful.titlebar.widget.maximizedbutton(c),
|
||||||
|
awful.titlebar.widget.stickybutton (c),
|
||||||
|
awful.titlebar.widget.ontopbutton (c),
|
||||||
|
awful.titlebar.widget.closebutton (c),
|
||||||
|
layout = wibox.layout.fixed.horizontal()
|
||||||
|
},
|
||||||
|
layout = wibox.layout.align.horizontal
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Normal wiboxes
|
||||||
|
|
||||||
|
wibox {
|
||||||
|
width = 50,
|
||||||
|
height = 50,
|
||||||
|
shape = gears.shape.octogon,
|
||||||
|
color = "#0000ff",
|
||||||
|
x = 570,
|
||||||
|
y = 410,
|
||||||
|
border_width = 2,
|
||||||
|
border_color = beautiful.border_color,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- The tooltip
|
||||||
|
|
||||||
|
mouse.coords{x=50, y= 100}
|
||||||
|
mouse.push_history()
|
||||||
|
|
||||||
|
local tt = awful.tooltip {
|
||||||
|
text = "A tooltip!",
|
||||||
|
visible = true,
|
||||||
|
}
|
||||||
|
tt.bg = beautiful.bg_normal
|
||||||
|
|
||||||
|
-- Extra information overlay
|
||||||
|
|
||||||
|
local overlay_w = wibox {
|
||||||
|
bg = "#00000000",
|
||||||
|
visible = true,
|
||||||
|
ontop = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
awful.placement.maximize(overlay_w)
|
||||||
|
|
||||||
|
local canvas = wibox.layout.manual()
|
||||||
|
canvas.forced_height = 480
|
||||||
|
canvas.forced_width = 640
|
||||||
|
overlay_w:set_widget(canvas)
|
||||||
|
|
||||||
|
local function create_info(text, x, y, width, height)
|
||||||
|
canvas:add_at(wibox.widget {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = text,
|
||||||
|
align = "center",
|
||||||
|
ellipsize = "none",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
margins = 10,
|
||||||
|
widget = wibox.container.margin
|
||||||
|
},
|
||||||
|
forced_width = width,
|
||||||
|
forced_height = height,
|
||||||
|
shape = gears.shape.rectangle,
|
||||||
|
shape_border_width = 1,
|
||||||
|
shape_border_color = beautiful.border_color,
|
||||||
|
bg = "#ffff0055",
|
||||||
|
widget = wibox.container.background
|
||||||
|
}, {x = x, y = y})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function create_line(x1, y1, x2, y2)
|
||||||
|
return canvas:add_at(wibox.widget {
|
||||||
|
fit = function()
|
||||||
|
return x2-x1+6, y2-y1+6
|
||||||
|
end,
|
||||||
|
draw = function(_, _, cr)
|
||||||
|
cr:set_source_rgb(0,0,0)
|
||||||
|
cr:set_line_width(1)
|
||||||
|
cr:arc(1.5, 1.5, 1.5, 0, math.pi*2)
|
||||||
|
cr:arc(x2-x1+1.5, y2-y1+1.5, 1.5, 0, math.pi*2)
|
||||||
|
cr:fill()
|
||||||
|
cr:move_to(1.5,1.5)
|
||||||
|
cr:line_to(x2-x1+1.5, y2-y1+1.5)
|
||||||
|
cr:stroke()
|
||||||
|
end,
|
||||||
|
layout = wibox.widget.base.make_widget,
|
||||||
|
}, {x=x1, y=y1})
|
||||||
|
end
|
||||||
|
|
||||||
|
create_info("awful.wibar", 200, 50, 100, 30)
|
||||||
|
create_info("awful.titlebar", 250, 350, 100, 30)
|
||||||
|
create_info("awful.tooltip", 30, 130, 100, 30)
|
||||||
|
create_info("awful.popup", 450, 240, 100, 30)
|
||||||
|
create_info("Standard `wibox1`", 420, 420, 130, 30)
|
||||||
|
|
||||||
|
create_line(250, 10, 250, 55)
|
||||||
|
create_line(75, 100, 75, 135)
|
||||||
|
create_line(545, 432, 575, 432)
|
||||||
|
create_line(500, 165, 500, 245)
|
||||||
|
create_line(390, 250, 450, 250)
|
||||||
|
create_line(190, 365, 255, 365)
|
||||||
|
|
||||||
|
--DOC_HIDE vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
Loading…
Reference in New Issue