awful.titlebar: more buttons added

This is a new version of 'titlebar.lua'. There are now additional buttons for:
- setting the 'ontop' attribute
- setting the 'sticky' attribute
- maximizing the client
In addition to changing the state of the client the buttons also show if the
corresponding state is active for a client. All new buttons now require 4
images for:
- unfocused window, state inactive (i.e. ontop == false)
- unfocused window, state active (i.e. ontop == true)
- focused window, state inactive (i.e. ontop == false)
- focused window, state active (i.e. ontop == true)
It's not difficult to add more buttons with any kind of functionality. User
configuration is currently restricted to theming of the buttons. Buttons are
disabled simply by not configuring them in the theme.  The icons for the new
buttons are taken from kde4. They're not really pretty but they're OK to
demonstrate the new features.

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Thomas Brunko 2009-04-12 13:54:29 +02:00 committed by Julien Danjou
parent 46ffccd8e2
commit 991c795629
21 changed files with 249 additions and 49 deletions

View File

@ -28,6 +28,9 @@ module("awful.titlebar")
-- Privata data
local data = otable()
-- Predeclaration for buttons
local button_groups
--- Create a standard titlebar.
-- @param c The client.
-- @param args Arguments.
@ -71,52 +74,28 @@ function add(c, args)
local appicon = capi.widget({ type = "imagebox", align = "left" })
appicon.image = c.icon
-- Also redirect events for appicon (So the entire titlebar behaves consistently)
appicon:buttons(bts)
function appicon.mouse_enter(s) hooks.user.call('mouse_enter', c) end
local closef
if theme.titlebar_close_button_focus then
closef = widget.button({ align = "right",
image = image(theme.titlebar_close_button_focus) })
-- for each button group, call create for the client.
-- if a button set is created add the set to the
-- data[c].button_sets for late updates and add the
-- individual buttons to the array part of the widget
-- list
local widget_list = { appicon = appicon, title = title }
local iw = #widget_list
local is = 1
data[c].button_sets = {}
for i = 1, #button_groups do
local set = button_groups[i].create(c, modkey, theme)
if (set) then
data[c].button_sets[is] = set
is = is + 1
for n,b in pairs(set) do
widget_list[iw] = b
iw = iw + 1
end
local close
if theme.titlebar_close_button_normal then
close = widget.button({ align = "right",
image = image(theme.titlebar_close_button_normal) })
end
if close or closef then
-- Bind kill button, also allow moving and resizing on this widget
local bts =
{
capi.button({ }, 1, nil, function (t) t.client:kill() end),
capi.button({ args.modkey }, 1, function (t) mouse.client.move(t.client) end),
capi.button({ args.modkey }, 3, function (t) mouse.client.resize(t.client) end)
}
if close then
local rbts = close:buttons()
for k, v in pairs(rbts) do
bts[#bts + 1] = v
end
close:buttons(bts)
function close.mouse_enter(s) hooks.user.call('mouse_enter', c) end
end
if closef then
local rbts = closef:buttons()
for k, v in pairs(rbts) do
bts[#bts + 1] = v
end
closef:buttons(bts)
-- Needed for sloppy focus beheaviour
function closef.mouse_enter(s) hooks.user.call('mouse_enter', c) end
end
end
tb.widgets = { appicon = appicon, title = title,
closef = closef, close = close }
tb.widgets = widget_list
c.titlebar = tb
update(c)
@ -140,13 +119,15 @@ function update(c, prop)
if capi.client.focus == c then
c.titlebar.fg = data[c].fg_focus
c.titlebar.bg = data[c].bg_focus
if widgets.closef then widgets.closef.visible = true end
if widgets.close then widgets.close.visible = false end
else
c.titlebar.fg = data[c].fg
c.titlebar.bg = data[c].bg
if widgets.closef then widgets.closef.visible = false end
if widgets.close then widgets.close.visible = true end
end
-- iterated of all registered button_sets and update
local sets = data[c].button_sets
for i = 1, #sets do
sets[i].update(c,prop)
end
end
end
@ -158,6 +139,205 @@ function remove(c)
data[c] = nil
end
-- Create a new button for the toolbar
-- @param c The client of the titlebar
-- @param name The base name of the button (i.e. close)
-- @param modkey ... you know that one, don't you?
-- @param theme The theme from beautifull. Used to get the image paths
-- @param state The state the button is associated to. Containse path the action and info about the image
local function button_new(c, name, modkey, theme, state)
local bts =
{
capi.button({ }, 1, nil, state.action),
capi.button({ modkey }, 1, function (t) mouse.client.move(t.client) end),
capi.button({ modkey }, 3, function (t) mouse.client.resize(t.client) end)
}
-- get the image path from the theme. Only return a button if we find an image
local img
img = "titlebar_" .. name .. "_button_" .. state.img
img = theme[img]
if not img then return end
img = image(img)
if not img then return end
-- now create the button
local bname = name .. "_" .. state.idx
local button = widget.button({ image = img })
if not button then return end
local rbts = button:buttons()
for k, v in pairs(rbts) do
bts[#bts + 1] = v
end
button:buttons(bts)
function button.mouse_enter(s) hooks.user.call('mouse_enter', c) end
button.visible = false
return button
end
-- Update the buttons in a button group
-- @param s The button group to update
-- @param c The client of the titlebar
-- @param p The property that has changed
local function button_group_update(s,c,p)
-- hide the currently active button, get the new state and show the new button
local n = s.select_state(c,p)
if n == nil then return end
if (s.active ~= nil) then s.active.visible = false end
s.active = s.buttons[n]
s.active.visible = true
end
-- Create all buttons in a group
-- @param c The client of the titlebar
-- @param group The button group to create the buttons for
-- @param modkey ...
-- @param theme Theme for the image paths
local function button_group_create(c, group, modkey, theme )
local s = {}
s.name = group.name
s.select_state = group.select_state
s.buttons = {}
for n,state in pairs(group.states) do
s.buttons[n] = button_new(c, s.name, modkey, theme, state)
if (s.buttons[n] == nil) then return end
for a,v in pairs(group.attributes) do
s.buttons[n][a] = v
end
end
function s.update(c,p) button_group_update(s,c,p) end
return s
end
-- Builds a new button group
-- @param name The base name for the buttons in the group (i.e. "close")
-- @param attrs Common attributes for the buttons (i.e. {align = "right")
-- @param sfn State select function.
-- @param args The states of the button
local function button_group(name, attrs, sfn, ...)
local s = {}
s.name = name
s.select_state = sfn
s.attributes = attrs
s.states = {}
for i = 1, #arg do
local state = arg[i]
s.states[state.idx] = state
end
function s.create(c,modkey, theme) return button_group_create(c,s,modkey, theme) end
return s
end
-- Select a state for a client based on an attribute of the client and whether it has focus
-- @param c The client of the titlebar
-- @param p The property that has changed
-- @param a The property to check
local function select_state(c,p,a)
if (c == nil) then return "n/i" end
if capi.client.focus == c then
if c[a] then
return "f/a"
else
return "f/i"
end
else
if c[a] then
return "n/a"
else
return "n/i"
end
end
end
-- Select a state for a client based on whether it's maximized or not
-- @param c The client of the titlebar
-- @param p The property that has changed
local function select_state_maximized(c,p)
if (c == nil) then return "n/i" end
if capi.client.focus == c then
if c.maximized_horizontal or c.maximized_vertical then
return "f/a"
else
return "f/i"
end
else
if c.maximized_horizontal or c.maximized_vertical then
return "n/a"
else
return "n/i"
end
end
end
-- Select a state for a client based on whether it has focus or not
-- @param c The client of the titlebar
-- @param p The property that has changed
local function select_state_focus(c,p)
if c and capi.client.focus == c then
return "f"
end
return "n"
end
-- These are the predefined button groups
-- A short explanation using 'close_buttons' as an example:
-- "close" : name of the button, the images for this button are taken from the
-- theme variables titlebar_close_button_...
-- { align ... : attributes of all the buttons
-- select_state_focus : This function returns a short string used to describe
-- the state. In this case either "n" or "f" depending on
-- the focus state of the client. These strings can be
-- choosen freely but the< must match one of the idx fuekds
-- of the states below
-- { idx = "n" ... : This is the state of the button for the 'unfocussed'
-- (normal) state. The idx = "n" parameter connects this
-- button to the return value of the 'select_state_focus'
-- function. The img = "normal" parameter is used to
-- determine its image. In this case the iamge is taken from
-- the theme variable "titlebar_close_button_normal".
-- Finally the last parameter is the action for mouse
-- button 1
local close_buttons = button_group("close",
{ align = "left"},
select_state_focus,
{ idx = "n", img = "normal", action = function (t) t.client:kill() end},
{ idx = "f", img = "focus", action = function (t) t.client:kill() end}
)
local ontop_buttons = button_group("ontop",
{ align = "right"},
function(c,p) return select_state(c, p, "ontop") end,
{ idx = "n/i", img = "normal_inactive", action = function(t) t.client.ontop = true ; update(t.client) end},
{ idx = "f/i", img = "focus_inactive", action = function(t) t.client.ontop = true ; update(t.client) end},
{ idx = "n/a", img = "normal_active", action = function(t) t.client.ontop = false ; update(t.client) end},
{ idx = "f/a", img = "focus_active", action = function(t) t.client.ontop = false ; update(t.client) end}
)
local sticky_buttons = button_group("sticky",
{ align = "right"},
function(c,p) return select_state(c,p,"sticky") end,
{ idx = "n/i", img = "normal_inactive", action = function(t) t.client.sticky = true ; update(t.client) end},
{ idx = "f/i", img = "focus_inactive", action = function(t) t.client.sticky = true ; update(t.client) end},
{ idx = "n/a", img = "normal_active", action = function(t) t.client.sticky = false ; update(t.client) end},
{ idx = "f/a", img = "focus_active", action = function(t) t.client.sticky = false ; update(t.client) end}
)
local maximized_buttons = button_group("maximized",
{ align = "right"},
select_state_maximized,
{ idx = "n/i", img = "normal_inactive", action = function(t) t.client.maximized_horizontal = true ; t.client.maximized_vertical = true ; update(t.client) end},
{ idx = "f/i", img = "focus_inactive", action = function(t) t.client.maximized_horizontal = true ; t.client.maximized_vertical = true ; update(t.client) end},
{ idx = "n/a", img = "normal_active", action = function(t) t.client.maximized_horizontal = false ; t.client.maximized_vertical = false ; update(t.client) end},
{ idx = "f/a", img = "focus_active", action = function(t) t.client.maximized_horizontal = false ; t.client.maximized_vertical = false ; update(t.client) end}
)
button_groups = { ontop_buttons, sticky_buttons, maximized_buttons, close_buttons}
-- Register standards hooks
hooks.focus.register(update)
hooks.unfocus.register(update)

View File

@ -46,8 +46,28 @@ menu_width = 100
#bg_widget = #cc0000
# Define the image to load
titlebar_close_button_normal = @AWESOME_THEMES_PATH@/default/titlebar/close.png
titlebar_close_button_focus = @AWESOME_THEMES_PATH@/default/titlebar/closer.png
titlebar_close_button_normal = @AWESOME_THEMES_PATH@/default/titlebar/close_normal.png
titlebar_close_button_focus = @AWESOME_THEMES_PATH@/default/titlebar/close_focus.png
titlebar_ontop_button_normal_inactive = @AWESOME_THEMES_PATH@/default/titlebar/ontop_normal_inactive.png
titlebar_ontop_button_focus_inactive = @AWESOME_THEMES_PATH@/default/titlebar/ontop_focus_inactive.png
titlebar_ontop_button_normal_active = @AWESOME_THEMES_PATH@/default/titlebar/ontop_normal_active.png
titlebar_ontop_button_focus_active = @AWESOME_THEMES_PATH@/default/titlebar/ontop_focus_active.png
titlebar_sticky_button_normal_inactive = @AWESOME_THEMES_PATH@/default/titlebar/sticky_normal_inactive.png
titlebar_sticky_button_focus_inactive = @AWESOME_THEMES_PATH@/default/titlebar/sticky_focus_inactive.png
titlebar_sticky_button_normal_active = @AWESOME_THEMES_PATH@/default/titlebar/sticky_normal_active.png
titlebar_sticky_button_focus_active = @AWESOME_THEMES_PATH@/default/titlebar/sticky_focus_active.png
titlebar_floating_button_normal_inactive = @AWESOME_THEMES_PATH@/default/titlebar/floating_normal_inactive.png
titlebar_floating_button_focus_inactive = @AWESOME_THEMES_PATH@/default/titlebar/floating_focus_inactive.png
titlebar_floating_button_normal_active = @AWESOME_THEMES_PATH@/default/titlebar/floating_normal_active.png
titlebar_floating_button_focus_active = @AWESOME_THEMES_PATH@/default/titlebar/floating_focus_active.png
titlebar_maximized_button_normal_inactive = @AWESOME_THEMES_PATH@/default/titlebar/maximized_normal_inactive.png
titlebar_maximized_button_focus_inactive = @AWESOME_THEMES_PATH@/default/titlebar/maximized_focus_inactive.png
titlebar_maximized_button_normal_active = @AWESOME_THEMES_PATH@/default/titlebar/maximized_normal_active.png
titlebar_maximized_button_focus_active = @AWESOME_THEMES_PATH@/default/titlebar/maximized_focus_active.png
# You can use your own command to set your wallpaper
wallpaper_cmd = awsetbg @AWESOME_THEMES_PATH@/default/background.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B