awesomewm-config/rc.lua

1007 lines
37 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

pcall(require, "luarocks.loader")
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
local wibox = require("wibox")
local menubar = require("menubar")
local beautiful = require("beautiful")
local naughty = require("naughty")
local my_utils = require('my_modules/my_utils')
local lain = require("lain")
local capslock = require("my_modules/capslock")
local spotify = require("my_modules/spotify")
local psi_widget = require("my_modules/psi")
local rotate_widget = require("my_modules/rotatescreen")
local touch_widget = require("my_modules/touchscreen")
local keyboard_widget = require("my_modules/keyboard")
local helpers = require("my_modules/geo_helpers")
local edid = require('my_modules/edid')
local dpi = require('beautiful').xresources.apply_dpi
hostname = io.popen("uname -n"):read()
-- debug stuff if needed
local printmore = false
-- my theme
beautiful.init("/home/gurkan/.config/awesome/my_modules/my_theme.lua")
-- print errors as naughty notifications
dofile ("/home/gurkan/.config/awesome/my_modules/rc_errorhandling.lua")
-- some fancy functions I'm using
dofile ("/home/gurkan/.config/awesome/my_modules/rc_functions.lua")
-- define tags at the beginning
dofile ("/home/gurkan/.config/awesome/my_modules/rc_tags.lua")
-- stuff related to volume/brightness OSD notifications
dofile ("/home/gurkan/.config/awesome/my_modules/rc_sliderstuff.lua")
-- stuff including usernames etc
dofile ("/home/gurkan/.config/awesome/my_modules/rc_secret.lua")
-- @Reference: disable notification system
-- package.loaded["naughty.dbus"] = {}
clientkeys = gears.table.join(
-- Increase/decrease windows sizes on tiled layout: Win + asdf
awful.key({ win }, "d", function () awful.tag.incmwfact( 0.01) end),
awful.key({ win }, "a", function () awful.tag.incmwfact(-0.01) end),
awful.key({ win }, "s", function () awful.client.incwfact( 0.01) end),
awful.key({ win }, "w", function () awful.client.incwfact(-0.01) end),
-- Quit window: Win + q
awful.key({ win }, "q", function (c) c:kill() end),
-- Swap master windows: Win + enter
awful.key({ win }, "Return", function (c) c:swap(awful.client.getmaster()) end),
-- Movement and focus:
-- Win + Arrows -> Swap focus between windows
-- Win + Shift + Arrows -> Move windows to that direction
-- Win + Ctrl + Arrows -> Expand windows to that direction
-- Win + Ctrl + Shift + Arrows -> Shrink windows from that direction
awful.key({ ctrl, win }, "Right", function (c) move_or_expand(c, "expand", "right") end),
awful.key({ win, "Shift" }, "Left", function (c) move_or_expand(c, "move", "left") end),
awful.key({ ctrl, win, "Shift" }, "Left", function (c) move_or_expand(c, "shrink", "left") end),
awful.key({ ctrl, win }, "Left", function (c) move_or_expand(c, "expand", "left") end),
awful.key({ ctrl, win, "Shift" }, "Right", function (c) move_or_expand(c, "shrink", "right") end),
awful.key({ win, "Shift" }, "Right", function (c) move_or_expand(c, "move", "right") end),
awful.key({ ctrl, win }, "Down", function (c) move_or_expand(c, "expand", "down") end),
awful.key({ ctrl, win, "Shift" }, "Up", function (c) move_or_expand(c, "shrink", "up") end),
awful.key({ ctrl, win }, "Up", function (c) move_or_expand(c, "expand", "up") end),
awful.key({ win, "Shift" }, "Down", function (c) move_or_expand(c, "move", "down") end),
awful.key({ win, "Shift" }, "Up", function (c) move_or_expand(c, "move", "up") end),
awful.key({ ctrl, win, "Shift" }, "Down", function (c) move_or_expand(c, "shrink", "down") end),
awful.key({ win }, "Right", function (c) switch_focus_without_mouse(c, "right") end),
awful.key({ win }, "Left", function (c) switch_focus_without_mouse(c, "left") end),
awful.key({ win }, "Down", function (c)
if c.sticky then
-- in case it's on top
awful.client.focus.history.previous()
else
awful.client.focus.bydirection("down")
end
end),
awful.key({ win }, "Up", function (c)
local cls = client.get()
local stickies = {}
-- Get all the stickies
for _, c in ipairs(cls) do
if c.sticky then
table.insert(stickies, c)
end
end
if my_utils.table_length(stickies) == 0 then
awful.client.focus.bydirection("up")
else
awful.client.focus.history.previous()
end
end),
-- Minimize window: Win + z
awful.key({ win }, "z", function (c) c.minimized = true end),
-- Suspend the window's app with SIGSTOP: Ctrl + Alt + s
awful.key({ ctrl, alt }, "s", function (c) suspend_toggle(c) end),
-- Shrink window and make it sticky & on top (e.g. conference call): Ctrl + Alt + w
awful.key({ ctrl, alt }, "w", function (c) float_toggle(c) end),
-- Sticky toggle for window: Ctrl + Alt + Shift + s
awful.key({ ctrl, alt, "Shift" }, "s", function (c) sticky_toggle(c) end),
-- Hide stickies to the bottom-right corner (toggle) : Win + Esc
awful.key({ win }, "Escape", function (c) hide_stickies() end),
awful.key({ }, "F7", nil, function (c) resize_screen(c.screen, screens_table, false) end),
awful.key({ }, "F8", nil, function (c) resize_screen(c.screen, screens_table, true) end)
)
my_systray = wibox.widget.systray()
my_systray:set_base_size(dpi(24))
function set_keys_after_screen_new(clientkeys, globalkeys)
if screen:count() > 1 then
-- Shortcut for moving window between screens
clientkeys = gears.table.join(clientkeys,
awful.key({ win, "Shift" }, "Left", function (c) c:move_to_screen(c.screen.index-1) end),
awful.key({ win, "Shift" }, "Right", function (c) c:move_to_screen(c.screen.index+1) end)
)
end
-- not sure why we're doing 10+ here 🤷
globalkeys = gears.table.join(
globalkeys,
awful.key({win}, "#10", function() switch_to_tag("web", printmore) end),
awful.key({win}, "#11", function() switch_to_tag("mail", printmore) end),
awful.key({win}, "#12", function() switch_to_tag("term", printmore) end),
awful.key({win}, "#13", function() switch_to_tag("chat", printmore) end),
awful.key({win, "Shift"}, "#10", function() move_focused_client_to_tag("web") end),
awful.key({win, "Shift"}, "#11", function() move_focused_client_to_tag("mail") end),
awful.key({win, "Shift"}, "#12", function() move_focused_client_to_tag("term") end),
awful.key({win, "Shift"}, "#13", function() move_focused_client_to_tag("chat") end)
)
return clientkeys, globalkeys
end
-- some aliases
terminal = "wezterm start"
browser = "firefox"
editor = os.getenv("EDITOR") or "nvim"
editor_cmd = terminal .. " -e " .. editor
greenclip_cmd = "rofi -dpi " .. dpi(80) .. " -modi 'clipboard:greenclip print' -show clipboard -run-command '{cmd}' "
rofi_cmd = "rofi -dpi " .. dpi(80) .. " -show run"
rofi_emoji_cmd = "rofi -dpi " .. dpi(80) .. " -show emoji -modi emoji"
proxified_chromium_cmd = 'chromium-browser --incognito --proxy-server="socks://127.0.0.1:8080" --host-resolver-rules="MAP * ~NOTFOUND, EXCLUDE 127.0.0.1"'
win = "Mod4"
alt = "Mod1"
ctrl = "Control"
-- dropdown terminal from lain
my_dropdown = lain.util.quake({
app = terminal,
argname = '--class %s',
name = 'myshittydropdown',
height = 0.5,
followtag = true,
visible = false
})
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ win }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ win }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end)
)
local tasklist_buttons = gears.table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
c:emit_signal(
"request::activate",
"tasklist",
{raise = true}
)
end
end),
awful.button({ }, 2, function (c)
c:kill()
end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(-1)
end)
)
separator = wibox.widget {
widget = wibox.widget.separator,
orientation = "horizontal",
forced_width = 30,
color = beautiful.separator,
shape = gears.shape.powerline
}
separator_empty = wibox.widget {
widget = wibox.widget.separator,
orientation = "horizontal",
forced_width = 10,
color = beautiful.bg_normal,
}
separator_reverse = wibox.widget {
widget = wibox.widget.separator,
orientation = "horizontal",
forced_width = 30,
span_ratio = 0.7,
color = beautiful.separator,
set_shape = function(cr, width, height)
gears.shape.powerline(cr, width, height, (height / 2) * (-1))
end
}
adapter_name = "BAT0"
if my_utils.file_exists('/sys/class/power_supply/BAT1/status') then
adapter_name = "BAT1"
end
batterytext = wibox.widget {
widget = wibox.widget.textbox,
font = beautiful.font,
markup = 'This <i>is</i> a <b>textbox</b>!!!',
}
battery_image_widget = wibox.widget {
image = beautiful.battery_icon_empty,
resize = true,
widget = wibox.widget.imagebox,
}
local battery_widget_text = lain.widget.bat({
battery = adapter_name,
full_notify = "off",
settings = function()
if bat_now.status == "Charging" then
battery_widget_color = beautiful.fg_normal_alt
battery_image = beautiful.battery_icon_charging
elseif bat_now.status == "Full" then
battery_widget_color = beautiful.fg_normal
battery_image = beautiful.battery_icon_full
else
battery_widget_color = beautiful.fg_normal_alt
if bat_now.perc > 80 then
battery_image = beautiful.battery_icon_full
elseif bat_now.perc > 40 then
battery_image = beautiful.battery_icon_medium
elseif bat_now.perc > 20 then
battery_image = beautiful.battery_icon_low
else
battery_image = beautiful.battery_icon_empty
end
end
local perc = bat_now.perc ~= "N/A" and "" .. bat_now.perc .. "%" or bat_now.perc
widget:set_markup(lain.util.markup.fontfg(beautiful.font, beautiful.fg_normal, perc .. " "))
battery_image_widget:set_image(gears.color.recolor_image(battery_image, battery_widget_color))
end
})
battery_widget = wibox.widget {
battery_image_widget,
battery_widget_text,
layout = wibox.layout.fixed.horizontal
}
battery_widget:buttons(awful.util.table.join(
-- Update battery widget with click, if we're not patient enough
awful.button({}, 1, function()
battery_widget_text:update()
end)
))
-- @Reference
-- When a new sound device is added/removed,
-- create a temporary popup to change default output device
-- function sound_device_change(signal)
-- refresh_sound_popup()
-- temp_sound_popup = sound_popup
-- primary_screen = awful.screen.focused()
-- if docked then
-- -- Use secondary screen, on the right side
-- for s in screen do
-- if not my_utils.is_screen_primary(s) then
-- primary_screen = s
-- end
-- end
-- end
-- temp_sound_popup.screen = primary_screen
-- awful.placement.top_right(temp_sound_popup, {honor_workarea=true})
-- temp_sound_popup.visible = true
-- hide_popup = gears.timer {
-- timeout = 10,
-- single_shot = true,
-- callback = function()
-- temp_sound_popup.visible = false
-- temp_sound_popup = nil
-- end
-- }
-- hide_popup:start()
-- end
-- dbus.add_match("system","type='signal',interface='org.custom.gurkan'")
-- dbus.connect_signal("org.custom.gurkan", sound_device_change)
-- Create a textclock widget and attach the calendar
mytextclock = wibox.widget{
widget = wibox.widget.textclock,
format = " %d %b %H:%M (%a) ",
refresh = 30
}
calendarwidget = lain.widget.cal({
followtag = true,
week_number = "left",
attach_to = { mytextclock },
notification_preset = {
font = beautiful.font_big,
fg = beautiful.fg_normal,
bg = beautiful.bg_focus
}
})
-- change tag names dynamically
dynamic_tagging = function()
for s = 1, screen.count() do
-- get a list of all tags
local atags = screen[s].tags
for i, t in ipairs(atags) do
local clients_on_this_tag = 0
for i, c in ipairs(t:clients()) do
if not c.skip_taskbar then
clients_on_this_tag = clients_on_this_tag + 1
end
end
original_name = my_utils.get_first_word(t.name)
t.name = original_name .. " " .. string.rep("", clients_on_this_tag)
end
end
end
-- signal function to execute when a client disappears
client.connect_signal("unmanage", function (c, startup)
dynamic_tagging()
end)
-- This is the only host with "rotatable" screen
if hostname == "innodellix" then
rotate_widget:buttons(awful.util.table.join(
awful.button({}, 1, function() -- left click
rotate_widget:toggle()
end)
))
touch_widget:buttons(awful.util.table.join(
awful.button({}, 1, function() -- left click
touch_widget:toggle()
end)
))
end
capslock:buttons(awful.util.table.join(
awful.button({}, 1, function() -- left click
capslock:toggle()
end)
))
keyboard_widget:buttons(awful.util.table.join(
awful.button({}, 1, function() -- left click
keyboard_widget:toggle()
end)
))
spotify:buttons(awful.util.table.join(
awful.button({}, 1, function() -- left click
handle_media("play-pause")
spotify:check()
end),
awful.button({}, 3, function() -- right click
spotify:raise()
end),
awful.button({}, 4, function() -- scroll up
handle_media("previous")
spotify:check()
end),
awful.button({}, 5, function() -- scroll down
handle_media("next")
spotify:check()
end)
))
psi_timer = gears.timer {
timeout = 15,
autostart = true,
callback = function()
psi_widget:check()
end
}
spotify_timer = gears.timer {
timeout = 15,
autostart = true,
call_now = true,
callback = function()
spotify:check()
end
}
local function screen_organizer(s, primary, is_extra)
debug_print("Now organizing screen: " .. s["name"], printmore)
-- Wallpaper -- one for each screen
set_wallpaper(s["object"])
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s["object"].mylayoutbox = awful.widget.layoutbox(s["object"])
s["object"].mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)
))
-- some convenience stuff
if screen:count() > 1 then
taglist_width = dpi(250)
wibar_height = dpi(25)
else
taglist_width = dpi(350)
wibar_height = dpi(23)
end
if not is_extra then
-- Create a taglist widget
s["object"].mytaglist = awful.widget.taglist {
screen = s["object"],
filter = awful.widget.taglist.filter.all,
style = {
shape = gears.shape.powerline
},
layout = {
spacing = -15,
spacing_widget = {
color = beautiful.bg_normal,
shape = gears.shape.powerline,
widget = wibox.widget.separator,
},
layout = wibox.layout.flex.horizontal,
forced_width = taglist_width
-- max_widget_width = taglist_width /50
},
widget_template = {
{
{
{
id = 'text_role',
widget = wibox.widget.textbox,
},
layout = wibox.layout.flex.horizontal,
},
left = 24,
right = 12,
widget = wibox.container.margin,
},
id = 'background_role',
widget = wibox.container.background,
},
buttons = taglist_buttons
}
-- Create a tasklist widget
s["object"].mytasklist = awful.widget.tasklist {
screen = s["object"],
filter = awful.widget.tasklist.filter.currenttags,
style = {
shape = gears.shape.powerline
},
layout = {
spacing = -15,
spacing_widget = {
color = beautiful.bg_normal,
shape = gears.shape.powerline,
widget = wibox.widget.separator,
},
layout = wibox.layout.flex.horizontal
},
widget_template = {
{
{
{
id = 'text_role',
widget = wibox.widget.textbox,
},
layout = wibox.layout.flex.horizontal,
},
left = 18,
right = 18,
widget = wibox.container.margin
},
id = 'background_role',
widget = wibox.container.background,
},
buttons = tasklist_buttons
}
end
-- Create the wibox
s["object"].mywibox = awful.wibar({
position = "top",
screen = s["object"],
height = wibar_height,
})
systray_right_widgets = {
layout = wibox.layout.fixed.horizontal
}
table.insert(systray_right_widgets, separator_empty)
if primary then
if screen:count() == 1 and hostname == "innodellix" then
table.insert(systray_right_widgets, touch_widget)
table.insert(systray_right_widgets, rotate_widget)
end
table.insert(systray_right_widgets, separator_reverse)
table.insert(systray_right_widgets, keyboard_widget)
table.insert(systray_right_widgets, separator_reverse)
table.insert(systray_right_widgets, battery_widget)
table.insert(systray_right_widgets, separator_reverse)
table.insert(systray_right_widgets, psi_widget)
table.insert(systray_right_widgets, separator_reverse)
table.insert(systray_right_widgets, spotify)
table.insert(systray_right_widgets, my_systray)
end
table.insert(systray_right_widgets, capslock)
table.insert(systray_right_widgets, mytextclock)
table.insert(systray_right_widgets, s["object"].mylayoutbox)
-- Add widgets to the wibox
if is_extra then
-- Doesn't get much stuff on this screen by default
-- Only if we move some shit to it
s["object"].mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.align.horizontal,
separator,
},
systray_right_widgets
}
else
-- Normal setup, tag and taskslists
s["object"].mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.align.horizontal,
s["object"].mytaglist,
separator,
},
s["object"].mytasklist, -- Middle widget
systray_right_widgets
}
end
end
function place_tags(properties, primary, screens_table)
if my_utils.table_length(screens_table) == 1 then
-- Only 1 screen here, no need for drama
for _, tag in pairs(root.tags()) do
table.insert(screens_table[properties["name"]]["tags"], tag)
if tag.screen ~= properties["object"] then
tag.screen = properties["object"]
end
end
else
for _, tag in pairs(root.tags()) do
local first_word = my_utils.get_first_word(tag.name)
if primary == false and ( first_word == "web" or first_word == "mail") then
if tag.screen ~= properties["object"] then
debug_print("Re-assigning " .. first_word, printmore)
tag.screen = properties["object"]
table.insert(screens_table[properties["name"]]["tags"], tag)
else
debug_print(first_word .. " is already on correct screen", printmore)
table.insert(screens_table[properties["name"]]["tags"], tag)
end
elseif primary == true and ( first_word == "term" or first_word == "chat") then
if tag.screen ~= properties["object"] then
debug_print("Re-assigning " .. first_word, printmore)
tag.screen = properties["object"]
table.insert(screens_table[properties["name"]]["tags"], tag)
else
debug_print(first_word .. " is already on correct screen", printmore)
table.insert(screens_table[properties["name"]]["tags"], tag)
end
end
end
end
-- ordering shit
for _, tag in pairs(root.tags()) do
if tag.name == "term" then
tag.index = 3
elseif tag.name == "mail" then
tag.index = 2
elseif tag.name == "web" then
tag.index = 1
else -- chat
tag.index = 4
end
end
end
function process_screens(systray, screens_table)
systray = systray or nil
debug_print("Processing screens result: " .. my_utils.dump(screens_table), printmore)
second_screen_already_processed = false
for name, properties in pairs(screens_table) do
-- In case we have more than 2 screens, we will register first
-- non-primary screen as 2nd, others won't get tags.
if properties["primary"] then
-- this is the "primary" screen so it should have the systray
systray:set_screen(properties["object"])
screen_organizer(properties, true, false, false)
debug_print("Checking tags for: " .. name .. " (primary) ", printmore)
place_tags(properties, true, screens_table)
else
screen_organizer(properties, false, second_screen_already_processed)
if second_screen_already_processed then
debug_print("Extra screen found: " .. my_utils.dump(properties["object"]), printmore)
else
debug_print("Checking tags for: " .. name .. " (not primary) ", printmore)
place_tags(properties, false, screens_table)
second_screen_already_processed = true
end
end
end
-- define rules since we have filled the screen table
dofile ("/home/gurkan/.config/awesome/my_modules/rc_rules.lua")
clientkeys, globalkeys = set_keys_after_screen_new(clientkeys, globalkeys)
dofile ("/home/gurkan/.config/awesome/my_modules/rc_clientbuttons.lua")
root.keys(globalkeys)
set_rules(clientkeys)
end
-- {{{ Mouse bindings
root.buttons(gears.table.join(
awful.button({ }, 4, awful.tag.viewprev),
awful.button({ }, 5, awful.tag.viewnext)
))
-- }}}
-- {{{ Key bindings
globalkeys = gears.table.join(
-- needed for capslock helper
capslock.key,
capslock.keyWithAlt,
capslock.keyWithWin,
capslock.keyWithCtrl,
-- Standard X11 keys, comes from Fn keys etc.
awful.key({ }, "XF86MonBrightnessUp", nil, function() set_brightness('5%+') end),
awful.key({ }, "XF86MonBrightnessDown", nil, function() set_brightness('5%-') end),
awful.key({ }, "XF86AudioRaiseVolume", nil, function() set_volume('i') end),
awful.key({ }, "XF86AudioLowerVolume", nil, function() set_volume('d') end),
awful.key({ }, "XF86AudioMute", nil, audio_mute),
awful.key({ }, "XF86AudioMicMute" , nil, mic_mute),
awful.key({ }, "XF86AudioPlay", nil, function () handle_media("play-pause") end),
awful.key({ }, "XF86AudioStop", nil, function () handle_media("stop") end),
awful.key({ }, "XF86AudioPrev", nil, function ()
handle_media("previous")
spotify:check()
end),
awful.key({ }, "XF86AudioNext", nil, function ()
handle_media("next")
spotify:check()
end),
-- Smart plug toggle
awful.key({ }, "XF86HomePage", nil, function () awful.spawn(bulb_toggle) end),
-- For laptop, which doesn't have next/prev buttons
awful.key({ ctrl }, "XF86AudioRaiseVolume", nil, function ()
handle_media("next")
spotify:check()
end),
awful.key({ ctrl }, "XF86AudioLowerVolume", nil, function ()
handle_media("previous")
spotify:check()
end),
-- Dropdown terminal: F12
awful.key({ }, "F12", nil, function () my_dropdown:toggle() end),
awful.key({ }, "Print", nil, function () awful.spawn("flameshot gui") end),
awful.key({ "Shift" }, "Print", function () awful.spawn("flameshot full -c") end),
awful.key({ ctrl }, "space", function () awful.spawn(rofi_cmd) end),
awful.key({ }, "F9", nil, function () awful.spawn(rofi_emoji_cmd) end),
awful.key({ ctrl, alt }, "c", function () awful.spawn(greenclip_cmd) end),
awful.key({ win }, "p", function () awful.spawn("rofi-pass") end),
awful.key({ ctrl, alt }, "t", function () awful.spawn(terminal) end),
awful.key({ win }, "c", function () awful.spawn("chromium-browser") end),
-- awful.key({ win }, "u", function () awful.spawn("/home/gurkan/clicky") end),
-- awful.key({ ctrl, alt }, "p", function () reset_pulse() end),
awful.key({ ctrl, alt }, "p", function () notifytest() end),
awful.key({ win }, "f", function () awful.spawn(browser) end),
awful.key({ win }, "l", function () awful.spawn("sudo slock") end),
-- awful.key({ win }, "k", function () keyboard_widget:toggle() end),
-- awful.key({ win }, "e", function () keyboard_widget:toggle() end),
-- If something goes wrong with grobi
awful.key({ win }, "m", function () awful.spawn("autorandr single") end),
-- Cycle between available layouts
awful.key({ win }, "space", function () awful.layout.inc(1) end),
awful.key({ win }, "x", function () awful.spawn("pcmanfm-qt") end),
awful.key({ win, }, "Tab", function () awful.tag.viewnext(get_screen_of_focused()) end),
awful.key({ win, "Shift" }, "Tab", function () awful.tag.viewprev(get_screen_of_focused()) end),
awful.key({ win, "Shift" }, "c", function () awful.spawn(proxified_chromium_cmd) end),
awful.key({ win, ctrl }, "q", awesome.quit),
awful.key({ win, ctrl }, "r", awesome.restart),
awful.key({ win, "Shift" }, "z", unminimize_client)
)
if hostname == "innixos" or hostname == "innodellix" then
gears.table.merge(globalkeys, gears.table.join(
awful.key({ win }, "v", function () awful.spawn("innovpn-toggle 'Innogames VPN (aw)'") end),
awful.key({ win, "Shift" }, "v", function () awful.spawn("innovpn-toggle 'Innogames VPN (af)'") end)
))
end
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c)
dynamic_tagging()
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
if not awesome.startup then awful.client.setslave(c) end
if awesome.startup
and not c.size_hints.user_position
and not c.size_hints.program_position then
-- Prevent clients from being unreachable after screen count changes.
awful.placement.no_offscreen(c)
end
-- XXX: doesn't work on awesome-git
c:buttons(gears.table.join(
c:buttons(),
awful.button({ win }, 4, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
mousegrabber.run(function (_mouse)
c.opacity = c.opacity + 0.1
return false
end, 'mouse')
end, nil),
awful.button({ win }, 5, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
mousegrabber.run(function (_mouse)
c.opacity = c.opacity - 0.1
return false
end, 'mouse')
end, nil)
))
end)
client.connect_signal("property::minimized", function(c)
-- If a sticky window is minimized, ensure it's visible on taskbar
if c.sticky then
c.skip_taskbar = false
end
end)
client.connect_signal("focus", function(c)
-- If a sticky window is unminimized, remove from taskbar
if c.sticky and not c.minimized then
c.skip_taskbar = true
end
end)
-- Screen handling
screen.connect_signal("list", function()
debug_print("List signal received", true)
if my_utils.file_age('/home/gurkan/.awesome_screen_setup_lock', true) < 4 then
debug_print("There is already another lock waiting, skipping this screen change", true)
else
os.execute('touch /home/gurkan/.awesome_screen_setup_lock')
debug_print("Sleeping for 2 secs", true)
os.execute('sleep 2')
screens_table = get_screens()
process_screens(my_systray, screens_table)
end
end)
os.execute('touch /home/gurkan/.awesome_screen_setup_lock')
screens_table = get_screens()
process_screens(my_systray, screens_table)
tag.connect_signal("request::screen", function(t)
-- recover tags on a removed screen
naughty.notify({text = "Recovering tag: " .. t.name})
for s in screen do
t.screen = s
my_dropdown.screen = s
return
end
end)
-- I only need 2 of these though 😬 max, tile or bust.
tag.connect_signal("request::default_layouts", function()
awful.layout.append_default_layouts({
awful.layout.suit.tile,
awful.layout.suit.max,
})
end)
client.connect_signal("mouse::enter", function (c)
if c.ontop and c.sticky and c.skip_taskbar and c.marked then
c.opacity = 0.9
-- Run away from mouse, to the other side of the screen
if c.x > (c.screen.geometry.x + c.screen.geometry.width - 600) then
c:relative_move(-(c.screen.geometry.width - c.width), 0, 0, 0)
else
c:relative_move((c.screen.geometry.width - c.width), 0, 0, 0)
end
end
end)
-- @Reference: Reflect click to the client below
-- Still can't "undo" click on the original client, but fun to play
-- client.connect_signal("button::press", function (c)
-- if c.ontop and c.sticky and c.skip_taskbar and c.marked then
-- next_client = awful.client.next (1, c, true)
-- helpers.async("xdotool click --window " .. next_client.window .. " 1", function(out)
-- end)
-- end
-- end)
awesome.connect_signal("exit", function (c)
-- We are about to exit / restart awesome, save our last used tag
save_current_tags(screens_table)
end)
-- Add a titlebar if titlebars_enabled is set to true in the rules.
client.connect_signal("request::titlebars", function(c)
-- buttons for the titlebar
local buttons = gears.table.join(
awful.button({ }, 1, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ }, 3, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.resize(c)
end)
)
awful.titlebar(c) : setup {
{ -- Left
awful.titlebar.widget.iconwidget(c),
buttons = buttons,
layout = wibox.layout.fixed.horizontal
},
{ -- Middle
{ -- Title
align = "center",
widget = awful.titlebar.widget.titlewidget(c)
},
buttons = buttons,
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
}
end)
tag.connect_signal("property::layout", function(t)
-- make the focused window master on layout change
local c = client.focus
if c and awful.layout.get(t.screen).name == "max" then
awful.client.setmaster(c)
c:raise()
end
end)
client.connect_signal("property::size", function(c)
-- workaround for exiting fullscreen on floating windows
-- some params do not stay as they should, so we enforce them
if c.floating and c.skip_taskbar and not c.fullscreen then
c.sticky=true
c.ontop=true
end
end)
client.connect_signal("focus", function(c)
-- border setup
c.border_color = beautiful.border_focus
end)
client.connect_signal("unfocus", function(c)
-- border setup
c.border_color = beautiful.border_normal
-- auto-hide dropdown
if c.instance == my_dropdown.name then
my_dropdown.visible = not my_dropdown.visible
my_dropdown:display()
end
end)
-- Git version workaround, shit is not complete (e.g. slack does not switch to)
-- alerting chat etc. but at least hovers the app itself
-- https://github.com/awesomeWM/awesome/issues/3182 waiting for proper fix
-- naughty.connect_signal("destroyed", function(n, reason)
-- if not n.clients then return end
-- if reason == require(
-- "naughty.constants"
-- ).notification_closed_reason.dismissed_by_user then
-- local jumped = false
-- for _, c in ipairs(n.clients) do
-- c.urgent = true
-- if jumped then
-- c:activate{
-- context = "client.jumpto"
-- }
-- else
-- c:jump_to()
-- jumped = true
-- end
-- end
-- end
-- end)
-- Show OSD notification of current status on volume:change signal
awesome.connect_signal("volume::change", function()
-- check if it's muted first
awful.spawn.easy_async(
"pamixer --get-mute",
function(stdout, stderr, reason, exit_code)
-- f*king whitespaces
stdout = stdout:gsub("%s+", "")
if stdout == 'true' then
-- muted, only show state
triggerwibox('mute')
return
else
helpers.async("pamixer --get-volume", function(out)
vb_slider.widget.value = tonumber(out)
triggerwibox('volume')
end)
end
end)
end)
-- Show OSD notification of current brightness on brightness:change signal
awesome.connect_signal("brightness:change", function()
awful.spawn.easy_async("brightnessctl -q get", function(current)
awful.spawn.easy_async("brightnessctl -q max", function(max)
vb_slider.widget.value = 100 * tonumber(current) / tonumber(max)
triggerwibox('brightness')
end)
end)
end)
-- When switching to a tag with urgent clients, raise them.
awful.tag.attached_connect_signal(s, "property::selected", function ()
local urgent_clients = function (c)
return awful.rules.match(c, { urgent = true })
end
for c in awful.client.iterate(urgent_clients) do
if c.first_tag == mouse.screen.selected_tag then
client.focus = c
c:raise()
end
end
end)
awesome.connect_signal("startup", function(s, state)
run_once("sleep 3 && firefox", "firefox")
-- only makes sense on this laptop
if hostname == "innodellix" then
run_once("sleep 5 && slack -s", "slack")
run_once("sleep 8 && thunderbird", "thunderbird")
end
run_once("XDG_CURRENT_DESKTOP=gnome telegram-desktop", "telegram")
run_once("pasystray")
run_once("wezterm start --class mainqterm", "mainqterm", "term")
-- run_once("wezterm connect default --class mainqterm", "mainqterm", "term")
-- one day wezterm will have tmux support 🤞
run_once("picom")
run_once("alttab -w 1 -t 400x300 -frame \"" .. string.upper(beautiful.fg_normal) .. "\" -i 100x100 -font xft:firacode-20")
end)
debug_print("Last state of the screens table is: \n" .. my_utils.dump(screens_table), printmore)
load_last_active_tags(screens_table, printmore)
-- vim: set ts=2 sw=2 tw=0 noet :