Skip to content

Commit

Permalink
feat: window switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
MobSenpai committed Jul 3, 2023
1 parent bd860a7 commit 146ec7f
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 22 deletions.
5 changes: 3 additions & 2 deletions home/yashraj/modules/desktop/wm/awesome/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@ in {

file = {
# Setup
".config/awesome/configuration/".source = ./. + "/${theme}";
".config/awesome/configuration".source = ./. + "/${theme}";
".config/awesome/rc.lua".source = ./rc.lua;
".config/awesome/helpers.lua".source = ./helpers.lua;
".config/awesome/keys.lua".source = ./keys.lua;

# Modules
".config/awesome/module/json.lua".source = ./module/json.lua;
".config/awesome/module/lockscreen/".source = ./module/lockscreen;
".config/awesome/module/lockscreen".source = ./module/lockscreen;
".config/awesome/module/window_switcher.lua".source = ./module/window_switcher.lua;
};
};

Expand Down
30 changes: 15 additions & 15 deletions home/yashraj/modules/desktop/wm/awesome/default/theme.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ theme.orange = "#d65d0e"

-- Background Colors
theme.bg_normal = theme.background
theme.bg_focus = theme.color0
theme.bg_urgent = theme.color8
theme.bg_minimize = theme.color8
theme.bg_focus = theme.color4 .. 70
theme.bg_urgent = theme.color3
theme.bg_minimize = theme.background .. 55

-- Foreground Colors
theme.fg_normal = theme.foreground
theme.fg_focus = theme.color5
theme.fg_urgent = theme.color3
theme.fg_minimize = theme.color8
theme.fg_focus = theme.color7
theme.fg_urgent = theme.color1
theme.fg_minimize = theme.foreground .. 55

--- ░█░█░▀█▀░░░█▀▀░█░░░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀
--- ░█░█░░█░░░░█▀▀░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█
Expand Down Expand Up @@ -111,11 +111,11 @@ theme.tasklist_bg_focus = theme.color0
theme.tasklist_fg_focus = theme.color2
theme.tasklist_bg_normal = theme.color0
theme.tasklist_fg_normal = theme.foreground
theme.tasklist_bg_minimize = theme.color0 .. 55
theme.tasklist_fg_minimize = theme.foreground .. 55
theme.tasklist_bg_minimize = theme.bg_minimize
theme.tasklist_fg_minimize = theme.fg_minimize
theme.tasklist_disable_task_name = false
theme.tasklist_bg_urgent = theme.color0
theme.tasklist_fg_urgent = theme.color1
theme.tasklist_bg_urgent = theme.bg_urgent
theme.tasklist_fg_urgent = theme.fg_urgent
theme.tasklist_align = "center"

--- Titlebar
Expand All @@ -127,10 +127,10 @@ theme.titlebar_enabled = false
-- ===================================================================
theme.menu_height = dpi(30)
theme.menu_width = dpi(150)
theme.menu_bg_normal = theme.background
theme.menu_fg_normal = theme.color7
theme.menu_bg_focus = theme.color4 .. 70
theme.menu_fg_focus = theme.color7
theme.menu_bg_normal = theme.bg_normal
theme.menu_fg_normal = theme.fg_normal
theme.menu_bg_focus = theme.bg_focus
theme.menu_fg_focus = theme.fg_focus
-- theme.menu_font = theme.font
theme.menu_border_width = theme.border_width / 2
theme.menu_border_color = theme.color8
Expand All @@ -148,7 +148,7 @@ theme.wibar_position = "top"
theme.wibar_height = dpi(25)
theme.wibar_bg = theme.color0
-- theme.wibar_fg =
--theme.wibar_opacity = 0.7
--theme.wibar_opacity =
-- theme.wibar_border_color =
theme.wibar_border_width = dpi(0)
theme.wibar_border_radius = dpi(0)
Expand Down
4 changes: 3 additions & 1 deletion home/yashraj/modules/desktop/wm/awesome/keys.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local awful = require("awful")
local hotkeys_popup = require("awful.hotkeys_popup")
local naughty = require("naughty")
local helpers = require("helpers")

local keys = {}
mod = "Mod4"
alt = "Mod1"
Expand Down Expand Up @@ -364,7 +365,8 @@ keys.clientkeys = gears.table.join(

-- Switch clients
awful.key({ alt }, "Tab", function()
awful.client.focus.byidx(1)
awesome.emit_signal("window_switcher::turn_on")
-- awful.client.focus.byidx(1)
end, { description = "focus next by index", group = "client" }),

-- Toggle floating
Expand Down
285 changes: 285 additions & 0 deletions home/yashraj/modules/desktop/wm/awesome/module/window_switcher.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local dpi = beautiful.xresources.apply_dpi

local window_switcher_first_client -- The client that was focused when the window_switcher was activated
local window_switcher_minimized_clients = {} -- The clients that were minimized when the window switcher was activated
local window_switcher_grabber

local get_num_clients = function()
local minimized_clients_in_tag = 0
local matcher = function(c)
return awful.rules.match(c, {
minimized = true,
skip_taskbar = false,
hidden = false,
first_tag = awful.screen.focused().selected_tag,
})
end
for c in awful.client.iterate(matcher) do
minimized_clients_in_tag = minimized_clients_in_tag + 1
end
return minimized_clients_in_tag + #awful.screen.focused().clients
end

local window_switcher_hide = function(window_switcher_box)
-- Add currently focused client to history
if client.focus then
local window_switcher_last_client = client.focus
awful.client.focus.history.add(window_switcher_last_client)
-- Raise client that was focused originally
-- Then raise last focused client
if window_switcher_first_client and window_switcher_first_client.valid then
window_switcher_first_client:raise()
window_switcher_last_client:raise()
end
end

-- Minimize originally minimized clients
local s = awful.screen.focused()
for _, c in pairs(window_switcher_minimized_clients) do
if c and c.valid and not (client.focus and client.focus == c) then
c.minimized = true
end
end
-- Reset helper table
window_switcher_minimized_clients = {}

-- Resume recording focus history
awful.client.focus.history.enable_tracking()
-- Stop and hide window_switcher
awful.keygrabber.stop(window_switcher_grabber)
window_switcher_box.visible = false
window_switcher_box.widget = nil
collectgarbage("collect")
end

local function draw_widget(mouse_keys)
local tasklist_widget = awful.widget.tasklist({
screen = awful.screen.focused(),
filter = awful.widget.tasklist.filter.currenttags,
buttons = mouse_keys,
style = {
font = beautiful.font,
bg_normal = beautiful.bg_normal,
bg_focus = beautiful.bg_focus,
fg_normal = beautiful.fg_normal,
fg_focus = beautiful.fg_focus,
shape = gears.shape.rounded_rect,
},
layout = {
layout = wibox.layout.fixed.horizontal,
},
widget_template = {
{
{
{
awful.widget.clienticon,
forced_height = dpi(80),
forced_width = dpi(80),
halign = "center",
valign = "center",
widget = wibox.container.place,
},
{
{
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
fps = 60,
speed = 75,
{
id = "text_role",
widget = wibox.widget.textbox,
},
},
halign = "center",
valign = "center",
widget = wibox.container.place,
},
spacing = dpi(15),
layout = wibox.layout.fixed.vertical,
},
margins = dpi(15),
widget = wibox.container.margin,
},
forced_width = dpi(150),
forced_height = dpi(150),
id = "background_role",
widget = wibox.container.background,
},
})

return wibox.widget({
{
tasklist_widget,
margins = dpi(15),
widget = wibox.container.margin,
},
bg = beautiful.background,
shape = gears.shape.rounded_rect,
widget = wibox.container.background,
})
end

local enable = function()
local hide_window_switcher_key = "Escape"

local select_client_key = 1
local minimize_key = "n"
local unminimize_key = "N"
local kill_client_key = "q"

local cycle_key = "Tab"

local previous_key = "Left"
local next_key = "Right"

local vim_previous_key = "h"
local vim_next_key = "l"

local scroll_previous_key = 4
local scroll_next_key = 5

local window_switcher_box = awful.popup({
bg = "#00000000",
visible = false,
ontop = true,
placement = awful.placement.centered,
screen = awful.screen.focused(),
widget = wibox.container.background, -- A dummy widget to make awful.popup not scream
widget = draw_widget(),
})

local mouse_keys = gears.table.join(
awful.button({
modifiers = { "Any" },
button = select_client_key,
on_press = function(c)
client.focus = c
end,
}),

awful.button({
modifiers = { "Any" },
button = scroll_previous_key,
on_press = function()
awful.client.focus.byidx(-1)
end,
}),

awful.button({
modifiers = { "Any" },
button = scroll_next_key,
on_press = function()
awful.client.focus.byidx(1)
end,
})
)

local keyboard_keys = {
[hide_window_switcher_key] = function()
window_switcher_hide(window_switcher_box)
end,

[minimize_key] = function()
if client.focus then
client.focus.minimized = true
end
end,
[unminimize_key] = function()
if awful.client.restore() then
client.focus = awful.client.restore()
end
end,
[kill_client_key] = function()
if client.focus then
client.focus:kill()
end
end,

[cycle_key] = function()
awful.client.focus.byidx(1)
end,

[previous_key] = function()
awful.client.focus.byidx(1)
end,
[next_key] = function()
awful.client.focus.byidx(-1)
end,

[vim_previous_key] = function()
awful.client.focus.byidx(1)
end,
[vim_next_key] = function()
awful.client.focus.byidx(-1)
end,
}

window_switcher_box:connect_signal("property::width", function()
if window_switcher_box.visible and get_num_clients() == 0 then
window_switcher_hide(window_switcher_box)
end
end)

window_switcher_box:connect_signal("property::height", function()
if window_switcher_box.visible and get_num_clients() == 0 then
window_switcher_hide(window_switcher_box)
end
end)

awesome.connect_signal("window_switcher::turn_on", function()
local number_of_clients = get_num_clients()
if number_of_clients == 0 then
return
end

-- Store client that is focused in a variable
window_switcher_first_client = client.focus

-- Stop recording focus history
awful.client.focus.history.disable_tracking()

-- Go to previously focused client (in the tag)
awful.client.focus.history.previous()

-- Track minimized clients
-- Unminimize them
-- Lower them so that they are always below other
-- originally unminimized windows
local clients = awful.screen.focused().selected_tag:clients()
for _, c in pairs(clients) do
if c.minimized then
table.insert(window_switcher_minimized_clients, c)
c.minimized = false
c:lower()
end
end

-- Start the keygrabber
window_switcher_grabber = awful.keygrabber.run(function(_, key, event)
if event == "release" then
-- Hide if the modifier was released
-- We try to match Super or Alt or Control since we do not know which keybind is
-- used to activate the window switcher (the keybind is set by the user in keys.lua)
if key:match("Super") or key:match("Alt") or key:match("Control") then
window_switcher_hide(window_switcher_box)
end
-- Do nothing
return
end

-- Run function attached to key, if it exists
if keyboard_keys[key] then
keyboard_keys[key]()
end
end)

window_switcher_box.widget = draw_widget(mouse_keys)
window_switcher_box.visible = true
end)
end

return { enable = enable }
Loading

0 comments on commit 146ec7f

Please sign in to comment.