Add application launcher and rewritten window switcher, remove rofi as its no longer needed and replaced by widgets. Fixed a lot of bugs and weird behaviour

This commit is contained in:
Rene
2022-07-29 13:21:56 +02:00
parent b2e22fdf8a
commit e727015e81
35 changed files with 964 additions and 639 deletions

View File

@@ -5,17 +5,226 @@
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local desktop_parser = require("src.tools.desktop_parser")
local gears = require("gears")
local wibox = require("wibox")
return function()
local application_list = wibox.widget {
local desktop_files = desktop_parser.Get_all_visible_desktop()
local application_grid = wibox.widget {
homogenous = true,
expand = false,
spacing = dpi(10),
layout = wibox.container.grid
id = "grid",
forced_num_cols = 8,
forced_num_rows = 7,
orientation = "vertical",
layout = wibox.layout.grid
}
-- Selected application position, default is first at 1,1
-- The typo *might* be intentional
local curser = {
x = 1,
y = 1
}
return application_list
local filter = ""
---Executes only once to create a widget from each desktop file
---@return table widgets Unsorted widget table
local function get_applications_from_file()
local list = {}
for _, file in ipairs(desktop_files) do
if not file.nodisplay then
local app_widget = wibox.widget {
{
{
{
{
{ -- Icon
valign = "center",
halign = "center",
image = xdg_icon_lookup:find_icon(file.icon, 64) or "/home/crylia/Bilder/yes.png",
resize = true,
widget = wibox.widget.imagebox
},
height = dpi(64),
width = dpi(64),
strategy = "exact",
widget = wibox.container.constraint
},
{
{ -- Name
text = file.name,
align = "center",
valign = "center",
widget = wibox.widget.textbox
},
strategy = "exact",
width = dpi(170),
-- Prevents widget from overflowing
height = dpi(40),
widget = wibox.container.constraint
},
layout = wibox.layout.fixed.vertical
},
halign = "center",
valign = "center",
widget = wibox.container.place
},
margins = dpi(10),
widget = wibox.container.margin
},
name = file.name,
comment = file.comment,
exec = file.exec,
keywords = file.keywords,
categories = file.categories,
terminal = file.terminal,
border_color = Theme_config.application_launcher.application.border_color,
border_width = Theme_config.application_launcher.application.border_width,
bg = Theme_config.application_launcher.application.bg,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(8))
end,
widget = wibox.container.background
}
-- Execute command on left click and hide launcher
app_widget:buttons(
gears.table.join(
awful.button(
{},
1,
nil,
function()
awful.spawn.with_shell(file.exec)
awesome.emit_signal("application_launcher::show")
end
)
)
)
table.insert(list, app_widget)
end
end
return list
end
-- Table to hold all application widgets unsorted
local application_list = get_applications_from_file()
---Function to filter the applications and sort them into a widget grid
---@param search_filter string Filter string from the searchbar
---@return wibox.layout.grid wibox.layout.grid Sorted grid with all applications matching the filter
local function get_applications(search_filter)
filter = search_filter or filter
--Clear grid from previous widgets
application_grid:reset()
-- Reset to first position
curser = {
x = 1,
y = 1
}
for _, application in ipairs(application_list) do
-- Match the filter
if string.match(string.lower(application.name), string.lower(filter)) or
string.match(string.lower(application.categories), string.lower(filter)) or
string.match(string.lower(application.keywords), string.lower(filter)) then
application_grid:add(application)
-- Get the current position in the grid of the application as a table
local pos = application_grid:get_widget_position(application)
-- Check if the curser is currently at the same position as the application
awesome.connect_signal(
"update::selected",
function()
if curser.y == pos.row and curser.x == pos.col then
application.border_color = Theme_config.application_launcher.application.border_color_active
else
application.border_color = Theme_config.application_launcher.application.border_color
end
end
)
awesome.emit_signal("update::selected")
Hover_signal(application, Theme_config.application_launcher.application.bg,
Theme_config.application_launcher.application.fg, application.border_color)
end
end
return application_grid
end
application_grid = get_applications(filter)
awesome.connect_signal(
"application::left",
function()
curser.x = curser.x - 1
if curser.x < 1 then
curser.x = 1
end
awesome.emit_signal("update::selected")
end
)
awesome.connect_signal(
"application::right",
function()
curser.x = curser.x + 1
local _, grid_cols = application_grid:get_dimension()
if curser.x > grid_cols then
curser.x = grid_cols
end
awesome.emit_signal("update::selected")
end
)
awesome.connect_signal(
"application::up",
function()
curser.y = curser.y - 1
if curser.y < 1 then
curser.y = 1
end
awesome.emit_signal("update::selected")
end
)
awesome.connect_signal(
"application::down",
function()
curser.y = curser.y + 1
local grid_rows, _ = application_grid:get_dimension()
if curser.y > grid_rows then
curser.y = grid_rows
end
awesome.emit_signal("update::selected")
end
)
awesome.connect_signal(
"update::application_list",
function(filter)
application_grid = get_applications(filter)
end
)
awesome.connect_signal(
"application_launcher::execute",
function()
awesome.emit_signal("searchbar::stop")
local selected_widget = application_grid:get_widgets_at(curser.y, curser.x)[1]
if selected_widget.terminal then
awful.spawn.with_shell(selected_widget.exec)
else
awful.spawn(selected_widget.exec)
end
end
)
return application_grid
end

View File

@@ -13,20 +13,26 @@ local searchbar = require("src.modules.application_launcher.searchbar")()
return function(s)
local applicaton_launcher = wibox.widget {
{
{
searchbar,
wibox.widget.inputtextbox,
application_grid,
{
application_grid,
spacing = dpi(10),
layout = require("src.lib.overflow_widget.overflow").vertical,
scrollbar_width = 0,
step = dpi(50),
id = "scroll_bar",
},
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
margins = dpi(20),
widget = wibox.container.margin
},
height = dpi(600),
width = dpi(800),
height = s.geometry.height / 100 * 60,
width = s.geometry.width / 100 * 60,
strategy = "exact",
widget = wibox.container.constraint
}
@@ -52,9 +58,14 @@ return function(s)
}
awesome.connect_signal(
"application_laucher::show",
"application_launcher::show",
function()
application_container.visible = not application_container.visible
if mouse.screen == s then
application_container.visible = not application_container.visible
end
if application_container.visible then
awesome.emit_signal("searchbar::start")
end
end
)

View File

@@ -6,42 +6,62 @@
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local gfs = gears.filesystem
local gtable = gears.table
local gdebug = gears.debug
local gstring = gears.string
local keygrabber = require("awful.keygrabber")
local wibox = require("wibox")
local icondir = awful.util.getdir("config") .. "src/assets/icons/application_launcher/searchbar/"
local kgrabber
return function()
local searchbar = wibox.widget {
{
{
{
{ -- Search icon
{ -- Search icon
{
{
resize = false,
image = icondir .. "search.svg",
valign = "center",
halign = "center",
image = gears.color.recolor_image(icondir .. "search.svg",
Theme_config.application_launcher.searchbar.icon_color),
widget = wibox.widget.imagebox
},
strategy = "exact",
widget = wibox.container.constraint
bg = Theme_config.application_launcher.searchbar.icon_background,
widget = wibox.container.background
},
strategy = "exact",
width = dpi(30),
widget = wibox.container.constraint
},
{
{
fg = Theme_config.application_launcher.searchbar.fg_hint,
text = "Search",
markup = "Search",
valign = "center",
align = "center",
widget = wibox.widget.textbox
widget = wibox.widget.textbox,
id = "search_hint"
},
widget = wibox.layout.fixed.horizontal
margins = dpi(5),
widget = wibox.container.margin,
id = "s_margin"
},
margins = dpi(5),
widget = wibox.container.margin
widget = wibox.layout.fixed.horizontal,
id = "s_layout"
},
bg = Theme_config.application_launcher.searchbar.bg,
fg = Theme_config.application_launcher.searchbar.fg,
border_color = Theme_config.application_launcher.searchbar.border_color,
border_width = Theme_config.application_launcher.searchbar.border_width,
widget = wibox.container.background
widget = wibox.container.background,
shape = Theme_config.application_launcher.searchbar.shape,
id = "s_background"
},
width = dpi(400),
height = dpi(40),
@@ -49,5 +69,184 @@ return function()
widget = wibox.container.constraint
}
local old_wibox, old_cursor
local mouse_enter = function()
local w = mouse.current_wibox
if w then
old_cursor, old_wibox = w.cursor, w
w.cursor = "xterm"
end
end
local mouse_leave = function()
old_wibox.cursor = old_cursor
old_wibox = nil
end
searchbar:disconnect_signal("mouse::enter", mouse_enter)
searchbar:disconnect_signal("mouse::leave", mouse_leave)
searchbar:connect_signal("mouse::enter", mouse_enter)
searchbar:connect_signal("mouse::leave", mouse_leave)
local function have_multibyte_char_at(text, position)
return #text:sub(position, position) == -1
end
local search_text = searchbar:get_children_by_id("search_hint")[1]
local function promt_text_with_cursor(text, cursor_pos)
local char, spacer, text_start, text_end
local cursor_color = Theme_config.application_launcher.searchbar.bg_cursor
local text_color = Theme_config.application_launcher.searchbar.fg_cursor
if text == "" then
return "<span foreground='" .. Theme_config.application_launcher.searchbar.fg_hint .. "'>Search</span>"
end
if #text < cursor_pos then
char = " "
spacer = ""
text_start = gstring.xml_escape(text)
text_end = ""
else
local offset = 0
if have_multibyte_char_at(text, cursor_pos) then
offset = 1
end
char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset))
spacer = " "
text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1))
text_end = gstring.xml_escape(text:sub(cursor_pos + offset + 1))
end
return text_start ..
"<span background='" ..
cursor_color .. "' foreground='" .. text_color .. "'>" .. char .. "</span>" .. text_end .. spacer
end
local text_string = ""
---Start a new keygrabber to simulate an input textbox
local function keygrabber_start()
local cur_pos = #text_string + 1
--Draws the string on each keypress
local function update()
search_text:set_markup(promt_text_with_cursor(text_string, cur_pos))
--Send the string over to the application to filter applications
awesome.emit_signal("update::application_list", text_string)
end
update()
kgrabber = keygrabber.run(
function(modifiers, key, event)
awesome.connect_signal("searchbar::stop", function()
keygrabber.stop(kgrabber)
awesome.emit_signal("application_launcher::kgrabber_start")
end)
local mod = {}
for _, v in ipairs(modifiers) do
mod[v] = true
end
if event ~= "press" then
return
end
--Escape cases
if (mod.Control and (key == "c" or key == "g"))
or (not mod.Control and key == "Escape") then
keygrabber.stop(kgrabber)
search_text:set_markup(promt_text_with_cursor("", 1))
text_string = ""
awesome.emit_signal("application_launcher::show")
elseif (not mod.Control and key == "Return") or
(not mod.Control and key == "KP_Enter") then
keygrabber.stop(kgrabber)
searchbar.s_background.border_color = Theme_config.application_launcher.searchbar.border_color
searchbar.s_background.fg = Theme_config.application_launcher.searchbar.fg_hint
search_text:set_markup(promt_text_with_cursor("", 1))
text_string = ""
awesome.emit_signal("application_launcher::execute")
awesome.emit_signal("application_launcher::show")
end
if mod.Control then
elseif mod.Mod1 or mod.Mod3 then
else
--Delete character to the left and move cursor
if key == "BackSpace" then
if cur_pos > 1 then
local offset = 0
if have_multibyte_char_at(text_string, cur_pos - 1) then
offset = 1
end
text_string = text_string:sub(1, cur_pos - 2 - offset) .. text_string:sub(cur_pos)
cur_pos = cur_pos - 1 - offset
end
update()
--Delete character to the right
elseif key == "Delete" then
text_string = text_string:sub(1, cur_pos - 1) .. text_string:sub(cur_pos + 1)
update()
-- Move cursor to the left
elseif key == "Left" then
--cur_pos = cur_pos - 1
awesome.emit_signal("application::left")
-- Move cursor to the right
elseif key == "Right" then
--cur_pos = cur_pos + 1
awesome.emit_signal("application::right")
elseif key == "Up" then
awesome.emit_signal("application::up")
elseif key == "Down" then
awesome.emit_signal("application::down")
else
--Add key at cursor position
if key:wlen() == 1 then
text_string = text_string:sub(1, cur_pos - 1) .. key .. text_string:sub(cur_pos)
cur_pos = cur_pos + #key
end
update()
end
--Make sure cursor can't leave string bounds
if cur_pos < 1 then
cur_pos = 1
elseif cur_pos > #text_string + 1 then
cur_pos = #text_string + 1
end
end
end
)
end
--Start the keygrabber when the searchbar is left clicked
searchbar:buttons(gears.table.join(
awful.button({}, 1, function()
if not awful.keygrabber.is_running then
keygrabber_start()
searchbar.s_background.border_color = Theme_config.application_launcher.searchbar.border_active
searchbar.s_background.fg = Theme_config.application_launcher.searchbar.fg
search_text:set_markup(promt_text_with_cursor("", 1))
end
end)
))
awesome.connect_signal(
"searchbar::start",
function()
if not awful.keygrabber.is_running then
keygrabber_start()
searchbar.s_background.border_color = Theme_config.application_launcher.searchbar.border_active
searchbar.s_background.fg = Theme_config.application_launcher.searchbar.fg
search_text:set_markup(promt_text_with_cursor("", 1))
end
end
)
return searchbar
end

View File

@@ -115,11 +115,13 @@ return function(s)
awesome.connect_signal(
"brightness::rerun",
function()
brightness_container.visible = true
if hide_brightness_osd.started then
hide_brightness_osd:again()
else
hide_brightness_osd:start()
if mouse.screen == s then
brightness_container.visible = true
if hide_brightness_osd.started then
hide_brightness_osd:again()
else
hide_brightness_osd:start()
end
end
end
)

View File

@@ -29,8 +29,8 @@ return function(screen, programs)
},
id = "icon_container",
strategy = "exact",
width = size,
height = size,
width = dpi(size),
height = dpi(size),
widget = wibox.container.constraint
},
margins = dpi(5),
@@ -58,8 +58,7 @@ return function(screen, programs)
end
end
Hover_signal(dock_element.background, Theme_config.dock.element_focused_hover_bg,
Theme_config.dock.element_focused_hover_fg)
Hover_signal(dock_element.background, Theme_config.dock.element_focused_hover_bg)
dock_element:connect_signal(
"button::press",
@@ -111,7 +110,7 @@ return function(screen, programs)
local dock_elements = { layout = wibox.layout.fixed.horizontal }
for i, p in ipairs(pr) do
dock_elements[i] = create_dock_element(desktop_parser(p), User_config.dock_icon_size)
dock_elements[i] = create_dock_element(desktop_parser.Get_desktop_values(p), User_config.dock_icon_size)
end
return dock_elements
@@ -141,10 +140,10 @@ return function(screen, programs)
local indicators = { layout = wibox.layout.flex.horizontal, spacing = dpi(5) }
local col = Theme_config.dock.indicator_bg
for i, c in ipairs(clients) do
local icon = desktop_parser(pr)
local icon = desktop_parser.Get_desktop_values(pr)
if icon then
local icon_name = icon["Icon"] or ""
if icon_name:match(string.lower(c.class or c.name or nil)) then
local icon_name = string.lower(icon["Icon"] or "")
if icon_name:match(string.lower(c.class or c.name)) then
if c == client.focus then
col = Theme_config.dock.indicator_focused_bg
elseif c.urgent then
@@ -171,7 +170,7 @@ return function(screen, programs)
container[index] = wibox.widget {
indicators,
forced_height = dpi(5),
forced_width = dpi(50),
forced_width = dpi(User_config.dock_icon_size),
left = dpi(5),
right = dpi(5),
widget = wibox.container.margin,
@@ -193,28 +192,36 @@ return function(screen, programs)
local function check_for_dock_hide(s)
local clients_on_tag = s.selected_tag:clients()
for _, client in ipairs(clients_on_tag) do
if client.fullscreen then
dock.visible = false
fakedock.visible = false
else
fakedock.visible = true
end
end
-- If there is no client on the current tag show the dock
if #clients_on_tag < 1 then
dock.visible = true
return
end
-- If there is a maximized client hide the dock and if fullscreened hide the activation area
for _, client in ipairs(clients_on_tag) do
if client.maximized or client.fullscreen then
dock.visible = false
if client.fullscreen then
fakedock.visible = false
awesome.emit_signal("notification_center_activation::toggle", s, false)
end
elseif not client.fullscreen then
fakedock.visible = true
awesome.emit_signal("notification_center_activation::toggle", s, true)
end
end
if s == mouse.screen then
local minimized = false
for _, c in ipairs(clients_on_tag) do
if c.maximized or c.fullscreen then
dock.visible = false
return
end
if c.minimized then
minimized = true
else
minimized = false
local y = c:geometry().y
local h = c.height
if (y + h) >= s.geometry.height - User_config.dock_icon_size - 35 then
@@ -245,15 +252,16 @@ return function(screen, programs)
fakedock:connect_signal(
"mouse::enter",
function()
for _, c in ipairs(screen.clients) do
if not c.fullscreen then
dock_intelligent_hide:stop()
dock.visible = true
end
end
if #screen.clients < 1 then
dock.visible = true
dock_intelligent_hide:stop()
return
end
for _, c in ipairs(screen.clients) do
if not c.fullscreen then
dock.visible = true
dock_intelligent_hide:stop()
end
end
end
)
@@ -316,8 +324,8 @@ return function(screen, programs)
dock:connect_signal(
"mouse::leave",
function()
check_for_dock_hide(screen)
dock_intelligent_hide:again()
dock.visible = false
end
)
dock:setup {

View File

@@ -19,13 +19,13 @@ awful.screen.connect_for_each_screen(
require("src.modules.powermenu")(s)
require("src.modules.volume_osd")(s)
--require("src.modules.brightness_osd")(s)
--require("src.modules.bluetooth_controller")(s)
require("src.modules.brightness_osd")(s)
require("src.modules.bluetooth_controller")(s)
require("src.modules.titlebar")
require("src.modules.volume_controller")(s)
require("src.modules.crylia_bar.init")(s)
require("src.modules.notification-center.init")(s)
require("src.modules.window_switcher.init")(s)
--require("src.modules.application_launcher.init")(s)
require("src.modules.application_launcher.init")(s)
end
)

View File

@@ -34,6 +34,15 @@ return function(s)
layout = wibox.layout.fixed.horizontal
})
awesome.connect_signal(
"notification_center_activation::toggle",
function(screen, hide)
if screen == s then
activation_area.visible = hide
end
end
)
--#endregion
--#region Widgets
@@ -70,7 +79,6 @@ return function(s)
margins = dpi(10),
widget = wibox.container.margin
},
id = "place",
widget = wibox.container.place,
valign = "bottom",
halign = "right",
@@ -193,7 +201,6 @@ return function(s)
halign = "right",
}
-- TODO: Add rubato animation. For this the widget needs to be rewritten to use a single moving square
local no_notification_widget = wibox.widget {
{
{
@@ -220,7 +227,6 @@ return function(s)
halign = "center",
widget = wibox.container.place
}
--#endregion
--#region Notification center
@@ -240,7 +246,6 @@ return function(s)
end,
}
-- TODO: Currently awesome doesn't come with a scroll container, there is a PR(#3309) and once its merged we can use it
local function notification_center_setup()
notification_center:setup({
widget = notification_center,
@@ -363,7 +368,7 @@ return function(s)
end
)
Hover_signal(clear_all_widget, Theme_config.notification_center.clear_all_button.bg,
Hover_signal(clear_all_widget.margin3.background4, Theme_config.notification_center.clear_all_button.bg,
Theme_config.notification_center.clear_all_button.fg)
--#endregion

View File

@@ -14,7 +14,8 @@ local icondir = awful.util.getdir("config") .. "src/assets/icons/notifications/"
local nl = {}
nl.notification_list = { layout = wibox.layout.overflow.vertical, scrollbar_width = 0, step = dpi(10), spacing = dpi(20) }
nl.notification_list = { layout = require("src.lib.overflow_widget.overflow").vertical, scrollbar_width = 0,
step = dpi(20), spacing = dpi(20) }
-- @param {table} notification
-- @return {widget} notifications_list
@@ -91,7 +92,6 @@ function nl.create_notification(n)
},
margins = dpi(10),
widget = wibox.container.margin,
id = "arc_margin"
}
local timer_close_widget = timer_widget
@@ -224,7 +224,7 @@ function nl.create_notification(n)
if button == 1 then
for i, b in pairs(nl.notification_list) do
if b.pk == notification.pk then
table.remove(nl.notification_list, i)
table.remove(nl.notification_list, math.tointeger(i))
awesome.emit_signal("notification_center:update::needed")
break
end
@@ -233,7 +233,7 @@ function nl.create_notification(n)
end
)
Hover_signal(close_widget.const.background, Theme_config.notification_center.notification_list.close_bg,
Hover_signal(close_widget.const.background, nil,
Theme_config.notification_center.notification_list.close_color)
notification:connect_signal(

View File

@@ -55,11 +55,11 @@ return function(s)
if stdout:match("On") then
awful.spawn.with_shell("playerctl shuffle off")
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
Theme_config.notification_center.song_info.shuffle_enabled)
Theme_config.notification_center.song_info.shuffle_disabled)
else
awful.spawn.with_shell("playerctl shuffle on")
shuffle_button.image = gears.color.recolor_image(icondir .. "shuffle.svg",
Theme_config.notification_center.song_info.shuffle_disabled)
Theme_config.notification_center.song_info.shuffle_enabled)
end
end
)
@@ -428,6 +428,7 @@ return function(s)
"curl -s " .. url .. " -o /tmp/album_art.jpg && echo /tmp/album_art.jpg && sleep 0.5",
function()
music_widget:get_children_by_id("imagebox")[1].image = gears.surface.load_uncached("/tmp/album_art.jpg")
or icondir .. "default_image.svg"
end
)
end
@@ -439,8 +440,8 @@ return function(s)
function(stdout2)
local length = stdout2:gsub("\n", "")
if length ~= "" then
local length_formated = string.format("%02d:%02d", math.floor(tonumber(length or 1) / 60000000) or 0,
(math.floor(tonumber(length or 1) / 1000000) % 60) or 0)
local length_formated = string.format("%02d:%02d", math.floor((tonumber(length) or 1) / 60000000) or 0,
(math.floor((tonumber(length) or 1) / 1000000) % 60) or 0)
music_widget:get_children_by_id("progressbar1")[1].max_value = tonumber(math.floor(tonumber(length) /
1000000))
music_widget:get_children_by_id("text1")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
@@ -467,8 +468,8 @@ return function(s)
function(stdout)
local time = stdout:gsub("\n", "")
if time ~= "" then
local time_formated = string.format("%02d:%02d", math.floor(tonumber(time or "1") / 60),
math.floor(tonumber(time or "1")) % 60)
local time_formated = string.format("%02d:%02d", math.floor((tonumber(time) or 1) / 60),
math.floor(tonumber(time) or 1) % 60)
music_widget:get_children_by_id("textbox2")[1].markup = string.format("<span foreground='%s' font='JetBrainsMono Nerd Font, Bold 14'>%s</span>"
, Theme_config.notification_center.song_info.duration_fg, time_formated)
music_widget:get_children_by_id("progressbar1")[1].value = tonumber(time)

View File

@@ -19,7 +19,7 @@ local icondir = awful.util.getdir("config") .. "src/assets/icons/"
return function()
---Creates a layout with bar widgets based on the given table
---@param widget_table string{}
---@param widget_table table
---@return table
local function create_bar_layout(widget_table)
local bar_layout = { layout = wibox.layout.flex.horizontal, spacing = dpi(10) }
@@ -388,7 +388,7 @@ return function()
"update::gpu_temp",
function(gpu_temp)
local temp_icon
local temp_num = tonumber(gpu_temp)
local temp_num = tonumber(gpu_temp) or "NaN"
if temp_num then
@@ -478,6 +478,9 @@ return function()
function(muted, volume)
local icon = icondir .. "audio/volume"
volume = tonumber(volume)
if not volume then
return
end
if muted then
icon = icon .. "-mute"
else
@@ -564,8 +567,14 @@ return function()
awesome.connect_signal(
"microphone::get",
function(muted, volume)
if not volume then
return
end
local icon = icondir .. "audio/microphone"
volume = tonumber(volume)
if not volume then
return
end
if muted or (volume < 1) then
icon = icon .. "-off"
end

View File

@@ -132,12 +132,9 @@ local create_titlebar = function(c, size)
layout = wibox.layout.align.vertical,
id = "main"
}
Hover_signal(titlebar.main.margin.spacing.closebutton, Theme_config.titlebar.close_button_bg,
Theme_config.titlebar.close_button_fg)
Hover_signal(titlebar.main.margin.spacing.maximizebutton, Theme_config.titlebar.minimize_button_bg,
Theme_config.titlebar.minimize_button_fg)
Hover_signal(titlebar.main.margin.spacing.minimizebutton, Theme_config.titlebar.maximize_button_bg,
Theme_config.titlebar.maximize_button_fg)
Hover_signal(titlebar.main.margin.spacing.closebutton, Theme_config.titlebar.close_button_bg)
Hover_signal(titlebar.main.margin.spacing.maximizebutton, Theme_config.titlebar.minimize_button_bg)
Hover_signal(titlebar.main.margin.spacing.minimizebutton, Theme_config.titlebar.maximize_button_bg)
end
local create_titlebar_dialog_modal = function(c, size)
@@ -190,10 +187,8 @@ local create_titlebar_dialog_modal = function(c, size)
layout = wibox.layout.align.vertical,
id = "main"
}
Hover_signal(titlebar.main.margin.spacing.closebutton, Theme_config.titlebar.close_button_bg,
Theme_config.titlebar.close_button_fg)
Hover_signal(titlebar.main.margin.spacing.minimizebutton, Theme_config.titlebar.minimize_button_bg,
Theme_config.titlebar.minimize_button_fg)
Hover_signal(titlebar.main.margin.spacing.closebutton, Theme_config.titlebar.close_button_bg)
Hover_signal(titlebar.main.margin.spacing.minimizebutton, Theme_config.titlebar.minimize_button_bg)
end
client.connect_signal(

View File

@@ -63,7 +63,7 @@ return function(s)
function(new_node)
if node == new_node then
device:get_children_by_id("icon")[1].image = gears.color.recolor_image(icondir .. "headphones.svg",
Theme_config.volume_controller.device_headphones_selected_icon_color)
Theme_config.volume_controller.device_icon_color)
device.bg = Theme_config.volume_controller.device_headphones_selected_bg
device.fg = Theme_config.volume_controller.device_headphones_selected_fg
else
@@ -602,6 +602,9 @@ return function(s)
.recolor_image(icondir .. "volume-mute.svg", Theme_config.volume_controller.volume_fg))
else
volume = tonumber(volume)
if not volume then
return
end
local icon = icondir .. "volume"
if volume < 1 then
icon = icon .. "-mute"
@@ -632,6 +635,9 @@ return function(s)
.. "microphone-off.svg", Theme_config.volume_controller.microphone_fg))
else
volume = tonumber(volume)
if not volume then
return
end
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.slider_margin.slider:set_value(tonumber(volume))
if volume > 0 then
volume_controller:get_children_by_id("mic_volume_margin")[1].mic_volume.icon:set_image(gears.color.recolor_image(icondir

View File

@@ -80,6 +80,9 @@ return function(s)
volume_osd_widget:get_children_by_id("progressbar1")[1].value = tonumber(0)
else
volume = tonumber(volume)
if not volume then
return
end
volume_osd_widget:get_children_by_id("progressbar1")[1].value = tonumber(volume)
local icon = icondir .. "volume"
if volume < 1 then
@@ -126,11 +129,13 @@ return function(s)
awesome.connect_signal(
"widget::volume_osd:rerun",
function()
volume_container.visible = true
if hide_volume_osd.started then
hide_volume_osd:again()
else
hide_volume_osd:start()
if mouse.screen == s then
volume_container.visible = true
if hide_volume_osd.started then
hide_volume_osd:again()
else
hide_volume_osd:start()
end
end
end
)

View File

@@ -8,264 +8,12 @@ local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
local window_elements = require("src.modules.window_switcher.window_elements")()
return function(s)
-- Variable to check if client is selected
local list_update = function(widget, buttons, label, _, objects)
widget:reset()
local function sort_objects()
local objects_sorted = {}
objects_sorted[1] = objects[1]
local index = 2
for _, object in ipairs(objects) do
if object ~= nil or object ~= 0 then
if object == client.focus then
objects_sorted[1] = object
else
objects_sorted[index] = object
index = index + 1
end
end
end
index = 2
if objects_sorted[1].pid == objects_sorted[2].pid then
table.remove(objects_sorted, 2)
end
return objects_sorted
end
local objects_sorted = sort_objects()
local selected = objects_sorted[1].pid
for _, object in ipairs(objects_sorted) do
local window_element = wibox.widget {
{
{
{
{ -- Icon
{
id = "icon",
image = object.icon,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox
},
width = dpi(100),
height = dpi(100),
id = "icon_const",
strategy = "exact",
widget = wibox.container.constraint
},
{
{
text = "Application",
id = "label",
widget = wibox.widget.textbox
},
id = "place",
valign = "center",
halign = "center",
widget = wibox.container.place
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
id = "box",
width = dpi(150),
height = dpi(150),
strategy = "exact",
widget = wibox.container.constraint
},
id = "margin",
margins = dpi(20),
widget = wibox.container.margin
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
border_color = Theme_config.window_switcher.border_color,
border_width = Theme_config.window_switcher.border_width,
fg = Theme_config.window_switcher.element_fg,
widget = wibox.container.background
}
local function create_buttons(buttons_t, object_t)
if buttons_t then
local btns = {}
for _, b in ipairs(buttons_t) do
local btn = awful.button {
modifiers = b.modifiers,
button = b.button,
on_press = function()
b:emit_signal('press', object_t)
end,
on_release = function()
b:emit_signal('release', object_t)
end
}
btns[#btns + 1] = btn
end
return btns
end
end
window_element:buttons(create_buttons(buttons, object))
local text, _ = label(object, window_element:get_children_by_id("label")[1])
local i = 1
local sel = nil
local function select_next()
if not object.valid then
return
end
if #objects_sorted >= i then
selected = objects_sorted[i].pid
sel = selected
if selected == object.pid then
window_element.border_color = Theme_config.window_switcher.selected_border_color
window_element.fg = Theme_config.window_switcher.selected_fg
window_element.bg = Theme_config.window_switcher.selected_bg
else
window_element.border_color = Theme_config.window_switcher.border_color
window_element.fg = Theme_config.window_switcher.element_fg
window_element.bg = Theme_config.window_switcher.bg
end
end
if #objects_sorted > i then
i = i + 1
else
i = 1
end
end
local function raise()
if not object.valid then
return
end
if objects_sorted[i] then
if sel == object.pid then
if not object:isvisible() and object.first_tag then
object.first_tag:view_only()
end
object:emit_signal('request::activate')
object:raise()
end
-- Reset window switcher
i = 1
selected = objects_sorted[i].pid
sel = selected
if selected == object.pid then
window_element.border_color = Theme_config.window_switcher.selected_border_color
window_element.fg = Theme_config.window_switcher.selected_fg
window_element.bg = Theme_config.window_switcher.bg
else
window_element.border_color = Theme_config.window_switcher.border_color
window_element.fg = Theme_config.window_switcher.element_fg
window_element.bg = Theme_config.window_switcher.selected_bg
end
end
awesome.disconnect_signal(
"window_switcher::select_next",
select_next
)
awesome.disconnect_signal(
"window_switcher::raise",
raise
)
end
awesome.connect_signal(
"window_switcher::select_next",
select_next
)
awesome.connect_signal(
"window_switcher::raise",
raise
)
object:connect_signal(
"unmanage",
function(c)
if object.valid then
i = 1
objects_sorted[1] = objects_sorted[#objects_sorted]
objects_sorted[#objects_sorted] = nil
for _, obj in ipairs(objects_sorted) do
if obj.valid then
if obj.pid == c.pid then
table.remove(objects_sorted, _)
break
end
end
end
end
end
)
if text == nil or text == "" then
window_element:get_children_by_id("label")[1].text = "Application"
else
local text_full = text:match(">(.-)<")
if text_full then
if object.class == nil then
text = object.name
else
text = object.class:sub(1, 20)
end
end
window_element:get_children_by_id("label")[1].text = object.name
end
if selected == object.pid then
window_element.border_color = Theme_config.window_switcher.selected_border_color
window_element.fg = Theme_config.window_switcher.selected_fg
window_element.bg = Theme_config.window_switcher.selected_bg
end
window_element:get_children_by_id("icon")[1]:set_image(xdg_icon_lookup:find_icon(object.class, 64))
widget:add(window_element)
widget:set_spacing(dpi(20))
end
return widget
end
local window_switcher = awful.widget.tasklist(
s,
awful.widget.tasklist.source.all_clients,
awful.util.table.join(
awful.button(
{},
1,
function(c)
if c == client.focus then
c.minimized = true
else
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
c:emit_signal('request::activate')
c:raise()
end
end
)
),
{},
list_update,
wibox.layout.fixed.horizontal()
)
local window_switcher_margin = wibox.widget {
window_switcher,
local window_switcher_list = wibox.widget {
window_elements,
margins = dpi(20),
widget = wibox.container.margin
}
@@ -285,6 +33,11 @@ return function(s)
border_width = Theme_config.window_switcher.border_width
}
window_switcher_container:setup {
window_switcher_list,
layout = wibox.layout.fixed.vertical
}
awesome.connect_signal(
"toggle_window_switcher",
function()
@@ -293,9 +46,4 @@ return function(s)
end
end
)
window_switcher_container:setup {
window_switcher_margin,
layout = wibox.layout.fixed.vertical
}
end

View File

@@ -0,0 +1,179 @@
---------------------------------
-- This is the window_switcher --
---------------------------------
-- Awesome Libs
local awful = require("awful")
local dpi = require("beautiful").xresources.apply_dpi
local gears = require("gears")
local wibox = require("wibox")
return function()
local elements = wibox.widget {
layout = wibox.layout.fixed.horizontal,
spacing = dpi(20),
id = "switcher"
}
local selected = 0
local function create_elements(fn)
fn = fn or ""
elements:reset()
local clients = client.get()
local clients_sorted = {}
if client.focus then
clients_sorted[1] = client.focus
end
for _, client in ipairs(clients) do
if client ~= clients_sorted[1] then
table.insert(clients_sorted, client)
end
end
selected = selected
for i, client in ipairs(clients_sorted) do
local window_element = wibox.widget {
{
{
{
{ -- Icon
{
id = "icon",
--!ADD FALLBACK ICON!--
image = xdg_icon_lookup:find_icon(client.class, 64) or client.icon,
valign = "center",
halign = "center",
widget = wibox.widget.imagebox
},
width = dpi(100),
height = dpi(100),
id = "icon_const",
strategy = "exact",
widget = wibox.container.constraint
},
{
{
text = client.name,
id = "label",
widget = wibox.widget.textbox
},
id = "place",
valign = "center",
halign = "center",
widget = wibox.container.place
},
id = "layout1",
spacing = dpi(10),
layout = wibox.layout.fixed.vertical
},
id = "box",
width = dpi(150),
height = dpi(150),
strategy = "exact",
widget = wibox.container.constraint
},
id = "margin",
margins = dpi(20),
widget = wibox.container.margin
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, dpi(12))
end,
border_color = Theme_config.window_switcher.border_color,
border_width = Theme_config.window_switcher.border_width,
bg = Theme_config.window_switcher.element_bg,
fg = Theme_config.window_switcher.element_fg,
widget = wibox.container.background
}
if i == selected then
window_element.border_color = Theme_config.window_switcher.selected_border_color
window_element.fg = Theme_config.window_switcher.selected_fg
window_element.bg = Theme_config.window_switcher.selected_bg
else
window_element.border_color = Theme_config.window_switcher.border_color
window_element.fg = Theme_config.window_switcher.element_fg
window_element.bg = Theme_config.window_switcher.bg
end
elements:add(window_element)
end
if fn == "next" then
if selected >= #clients_sorted then
selected = 1
else
selected = selected + 1
end
for i, element in ipairs(elements.children) do
if i == selected then
element.border_color = Theme_config.window_switcher.selected_border_color
element.fg = Theme_config.window_switcher.selected_fg
element.bg = Theme_config.window_switcher.selected_bg
else
element.border_color = Theme_config.window_switcher.border_color
element.fg = Theme_config.window_switcher.element_fg
element.bg = Theme_config.window_switcher.bg
end
end
elseif fn == "raise" then
local c = clients_sorted[selected]
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
c:emit_signal('request::activate')
c:raise()
--reset selected
selected = 0
end
return elements
end
elements = create_elements()
awesome.connect_signal(
"window_switcher::select_next",
function()
elements = create_elements("next")
end
)
awesome.connect_signal(
"window_switcher::raise",
function()
elements = create_elements("raise")
end
)
client.connect_signal(
"manage",
function()
elements = create_elements()
end
)
client.connect_signal(
"unmanage",
function()
elements = create_elements()
end
)
awesome.connect_signal(
"window_switcher::update",
function()
elements = create_elements()
end
)
return elements
end