diff --git a/.config/awesome/config_laptop.lua b/.config/awesome/config_laptop.lua index 5724bc2..1e8e9f8 100644 --- a/.config/awesome/config_laptop.lua +++ b/.config/awesome/config_laptop.lua @@ -1,19 +1,32 @@ return { widgets = { - left = { + top = { + left = { + }, + mid = { + + }, + right = { + "volume", + "backlight", + "wifi", + "battery", + "clock" + } }, - mid = { - "mpd" - }, - right = { - "memory", - "cpu", - "volume", - "backlight", - "wifi", - "battery", - "clock" + bottom = { + left = { + + }, + mid = { + "mpd" + }, + right = { + "memory", + "cpu", + "thermal", + } } }, battery = "BAT1", @@ -21,5 +34,6 @@ return { volume = { options = {"Master", "-D", "pulse"}, sink = "@DEFAULT_SINK@" - } + }, + thermal_zone = "thermal_zone0" } diff --git a/.config/awesome/quake.lua b/.config/awesome/quake.lua new file mode 100644 index 0000000..01891b0 --- /dev/null +++ b/.config/awesome/quake.lua @@ -0,0 +1,168 @@ +--[[ + + Licensed under GNU General Public License v2 + * (c) 2016, Luca CPZ + * (c) 2015, unknown + +--]] + +local awful = require("awful") +local capi = { client = client } +local math = math +local string = string +local pairs = pairs +local screen = screen +local setmetatable = setmetatable + +-- Quake-like Dropdown application spawn +local quake = {} + +-- If you have a rule like "awful.client.setslave" for your terminals, +-- ensure you use an exception for QuakeDD. Otherwise, you may +-- run into problems with focus. + +function quake:display() + if self.followtag then self.screen = awful.screen.focused() end + + -- First, we locate the client + local client = nil + local i = 0 + for c in awful.client.iterate(function (c) + -- c.name may be changed! + return c.instance == self.name + end) + do + i = i + 1 + if i == 1 then + client = c + else + -- Additional matching clients, let's remove the sticky bit + -- which may persist between awesome restarts. We don't close + -- them as they may be valuable. They will just turn into + -- normal clients. + c.sticky = false + c.ontop = false + c.above = false + end + end + + if not client and not self.visible then return end + + if not client then + -- The client does not exist, we spawn it + cmd = string.format("%s %s %s", self.app, + string.format(self.argname, self.name), self.extra) + awful.spawn(cmd, { tag = self.screen.selected_tag }) + return + end + + -- Set geometry + client.floating = true + client.border_width = self.border + client.size_hints_honor = false + client:geometry(self.geometry[self.screen.index] or self:compute_size()) + + -- Set not sticky and on top + client.sticky = false + client.ontop = true + client.above = true + client.skip_taskbar = true + + -- Additional user settings + if self.settings then self.settings(client) end + + -- Toggle display + if self.visible then + client.hidden = false + client:raise() + self.last_tag = self.screen.selected_tag + client:tags({self.screen.selected_tag}) + capi.client.focus = client + else + client.hidden = true + local ctags = client:tags() + for i, t in pairs(ctags) do + ctags[i] = nil + end + client:tags(ctags) + end + + return client +end + +function quake:compute_size() + -- skip if we already have a geometry for this screen + if not self.geometry[self.screen.index] then + local geom + if not self.overlap then + geom = screen[self.screen.index].workarea + else + geom = screen[self.screen.index].geometry + end + local width, height = self.width, self.height + if width <= 1 then width = math.floor(geom.width * width) - 2 * self.border end + if height <= 1 then height = math.floor(geom.height * height) end + local x, y + if self.horiz == "left" then x = geom.x + elseif self.horiz == "right" then x = geom.width + geom.x - width + else x = geom.x + (geom.width - width)/2 end + if self.vert == "top" then y = geom.y + elseif self.vert == "bottom" then y = geom.height + geom.y - height + else y = geom.y + (geom.height - height)/2 end + self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height } + end + return self.geometry[self.screen.index] +end + +function quake:new(config) + local conf = config or {} + + conf.app = conf.app or "xterm" -- application to spawn + conf.name = conf.name or "QuakeDD" -- window name + conf.argname = conf.argname or "-name %s" -- how to specify window name + conf.extra = conf.extra or "" -- extra arguments + conf.border = conf.border or 1 -- client border width + conf.visible = conf.visible or false -- initially not visible + conf.followtag = conf.followtag or false -- spawn on currently focused screen + conf.overlap = conf.overlap or false -- overlap wibox + conf.screen = conf.screen or awful.screen.focused() + conf.settings = conf.settings + + -- If width or height <= 1 this is a proportion of the workspace + conf.height = conf.height or 0.25 -- height + conf.width = conf.width or 1 -- width + conf.vert = conf.vert or "top" -- top, bottom or center + conf.horiz = conf.horiz or "left" -- left, right or center + conf.geometry = {} -- internal use + + local dropdown = setmetatable(conf, { __index = quake }) + + capi.client.connect_signal("manage", function(c) + if c.instance == dropdown.name and c.screen == dropdown.screen then + dropdown:display() + end + end) + capi.client.connect_signal("unmanage", function(c) + if c.instance == dropdown.name and c.screen == dropdown.screen then + dropdown.visible = false + end + end) + + return dropdown +end + +function quake:toggle() + if self.followtag then self.screen = awful.screen.focused() end + local current_tag = self.screen.selected_tag + if current_tag and self.last_tag ~= current_tag and self.visible then + local c=self:display() + if c then + c:move_to_tag(current_tag) + end + else + self.visible = not self.visible + self:display() + end +end + +return setmetatable(quake, { __call = function(_, ...) return quake:new(...) end }) diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua index f4b5931..14f96ff 100644 --- a/.config/awesome/rc.lua +++ b/.config/awesome/rc.lua @@ -17,6 +17,7 @@ local hotkeys_popup = require("awful.hotkeys_popup") local vicious = require("vicious") local timer = require("gears.timer") local config = require("config_laptop") +local quake = require("quake") -- Enable hotkeys help widget for VIM and other apps -- when client with a matching name is opened: @@ -24,11 +25,46 @@ require("awful.hotkeys_popup.keys") local function round(x) if x%2 ~= 0.5 then + +client.connect_signal("mouse::move", function(c) + if switcher_mode and switcher_timer.started then + switcher_timer:again() + end +end) return math.floor(x+0.5) end return x-0.5 end +local dropdown = quake:new({ + app = "termite", + argname = "--name %s", + border = 0, + height = 0.37 +}) + +local htop = quake:new({ + app = "termite", + name = "QuakeHtop", + argname = "--name %s", + extra = "-e htop", + border = 0, + height = 0.13, + width = 0.25 +}) + +local vimpc = quake:new({ + app = "termite", + name = "QuakeVimpc", + argname = "--name %s", + extra = "-e vimpc", + border = 0, + height = 0.25, + width = 0.33, + horiz = "center", + vert = "bottom" +}) + -- {{{ Error handling -- Check if awesome encountered an error during startup and fell back to -- another config (This code will only ever execute for the fallback config) @@ -76,7 +112,7 @@ modkey = "Mod4" -- Table of layouts to cover with awful.layout.inc, order matters. awful.layout.layouts = { awful.layout.suit.spiral.dwindle, - awful.layout.suit.floating, + --awful.layout.suit.floating, awful.layout.suit.tile, --awful.layout.suit.tile.left awful.layout.suit.tile.bottom, @@ -84,8 +120,8 @@ awful.layout.layouts = { awful.layout.suit.fair, --awful.layout.suit.fair.horizontal, --awful.layout.suit.spiral, - awful.layout.suit.max, - awful.layout.suit.max.fullscreen, + --awful.layout.suit.max, + --awful.layout.suit.max.fullscreen, --awful.layout.suit.magnifier, --awful.layout.suit.corner.nw, -- awful.layout.suit.corner.ne, @@ -228,6 +264,10 @@ local volume_icon_table = { muted = "婢" } +local thermal_icon_table = { + "", "", "", "", "" +} + local function format_widget(...) local result = " " for _, v in ipairs({...}) do @@ -237,7 +277,7 @@ local function format_widget(...) end local function battery_icon(percent, charging) - local key = ""..(round(percent / 10) * 10).."" + local key = ""..math.floor(round(percent / 10) * 10).."" if charging then return battery_icon_table.charging[key] else @@ -283,10 +323,17 @@ local function format_mpd(widget, args) if args["{state}"] == "Stop" then return '' else - return format_widget("", ('%s - %s'):format(args["{Artist}"], args["{Title}"]), "") + local icon = (args["{state}"] == "Pause" and "" or "") + return format_widget(icon, + ('%s - %s'):format(args["{Artist}"], args["{Title}"]), icon) end end +local function format_thermal(widget, args) + local key = math.floor(math.min(round(math.max(args[1] - 30, 0) / 60 * 4 + 1), 5)) + return format_widget(thermal_icon_table[key], args[1]) +end + volumebox = wibox.widget.textbox() vicious.cache(vicious.widgets.volume) @@ -298,7 +345,7 @@ vicious.register(backlightbox, backlight_widget_type, format_brightness, 3) batwidget = wibox.widget.textbox() vicious.cache(vicious.widgets.bat) -vicious.register(batwidget, vicious.widgets.bat, format_battery, 61, config.battery) +vicious.register(batwidget, vicious.widgets.bat, format_battery, 20, config.battery) wifiwidget = wibox.widget.textbox() vicious.cache(vicious.widgets.wifi) @@ -313,9 +360,14 @@ vicious.cache(vicious.widgets.mem) vicious.register(memwidget, vicious.widgets.mem, format_memory, 1) mpdwidget = wibox.widget.textbox() +mpdwidget.align = 'center' vicious.cache(vicious.widgets.mpd) vicious.register(mpdwidget, vicious.widgets.mpd, format_mpd) +thermalwidget = wibox.widget.textbox() +vicious.cache(vicious.widgets.thermal) +vicious.register(thermalwidget, vicious.widgets.thermal, format_thermal, 2, config.thermal_zone) + local widget_table = { ["mpd"] = mpdwidget, ["memory"] = memwidget, @@ -324,7 +376,8 @@ local widget_table = { ["backlight"] = backlightbox, ["wifi"] = wifiwidget, ["battery"] = batwidget, - ["clock"] = mytextclock + ["clock"] = mytextclock, + ["thermal"] = thermalwidget, } local function load_widget_config(conf) @@ -348,9 +401,6 @@ awful.screen.connect_for_each_screen(function(s) -- Each screen has its own tag table. awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1]) - -- Create a promptbox for each screen - s.mypromptbox = awful.widget.prompt() - -- Create an imagebox widget which will contain an icon indicating which layout we're using. -- We need one layoutbox per screen. s.mylayoutbox = awful.widget.layoutbox(s) s.mylayoutbox:buttons(gears.table.join( @@ -373,38 +423,79 @@ awful.screen.connect_for_each_screen(function(s) } -- Create the wibox - s.mywibox = awful.wibar({ position = "top", screen = s, bg = "#00000000", visible = false }) + s.topwibox = awful.wibar({ + position = "top", + screen = s, + bg = { + type = "linear", + from = { 0, 0, 0 }, + to = { 0, 20, 0 }, + stops = { { 0, "#000000aa" }, { 0.6, "#00000066"}, { 1, "#00000000" } } + }, + visible = false + }) -- Add widgets to the wibox - s.mywibox:setup { + s.topwibox:setup { layout = wibox.layout.align.horizontal, { -- Left widgets layout = wibox.layout.fixed.horizontal, s.mytaglist, - table.unpack(load_widget_config(config.widgets.left)) + table.unpack(load_widget_config(config.widgets.top.left)) }, { layout = wibox.layout.flex.horizontal, wibox.widget { widget = wibox.widget.separator, visible = false }, - table.unpack(load_widget_config(config.widgets.mid)), + table.unpack(load_widget_config(config.widgets.top.mid)), wibox.widget { widget = wibox.widget.separator, visible = false }, }, { -- Right widgets layout = wibox.layout.fixed.horizontal, - table.unpack(load_widget_config(config.widgets.right)), + table.unpack(load_widget_config(config.widgets.top.right)), + }, + } + + s.bottomwibox = awful.wibar({ + position = "bottom", + screen = s, + bg = { + type = "linear", + from = { 0, 20, 0 }, + to = { 0, 0, 0 }, + stops = { { 0, "#000000aa" }, { 0.6, "#00000066"}, { 1, "#00000000" } } + }, + visible = false + }) + + s.bottomwibox:setup { + layout = wibox.layout.align.horizontal, + { -- Left widgets + layout = wibox.layout.fixed.horizontal, + + table.unpack(load_widget_config(config.widgets.bottom.left)) + }, + { + layout = wibox.layout.flex.horizontal, + + table.unpack(load_widget_config(config.widgets.bottom.mid)), + }, + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + + table.unpack(load_widget_config(config.widgets.bottom.right)), }, } s.dock_trigger = wibox({ bg = "#00000000", opacity = 0, ontop = true, visible = true }) - s.dock_trigger:geometry({ width = 10, height = 10 }) + s.dock_trigger:geometry({ width = 3, height = 3 }) - s.mywibox:connect_signal("mouse::enter", function() start_switcher() end) - s.mywibox:connect_signal("mouse::leave", function() switcher_timer:again() end) + s.topwibox:connect_signal("mouse::enter", function() start_switcher() end) + s.topwibox:connect_signal("mouse::leave", function() switcher_timer:again() end) s.dock_trigger:connect_signal("mouse::enter", function() start_switcher() end) s.dock_trigger:connect_signal("mouse::leave", function() switcher_timer:again() end) end) @@ -439,7 +530,8 @@ function start_switcher () -- Enable all bars for s in screen do - s.mywibox.visible = true + s.topwibox.visible = true + s.bottomwibox.visible = true end for _, c in ipairs(client.get()) do @@ -468,7 +560,8 @@ function end_switcher () -- Disable all bars for s in screen do - s.mywibox.visible = false + s.topwibox.visible = false + s.bottomwibox.visible = false end rofi_kill() @@ -556,7 +649,7 @@ globalkeys = gears.table.join( awful.spawn("xbacklight -dec 5") end), - --awful.key({ modkey }, "g", function () for s in screen do togglegaps(s, s.mywibox); s.dock_hide_timer:stop() end end), + --awful.key({ modkey }, "g", function () for s in screen do togglegaps(s, s.topwibox); s.dock_hide_timer:stop() end end), awful.key({ modkey }, "g", toggle_switcher), awful.key({ modkey }, "Tab", function () start_switcher(); awful.client.focus.byidx(1); switcher_timer:again() end), awful.key({ modkey, }, "s", hotkeys_popup.show_help, @@ -580,8 +673,14 @@ globalkeys = gears.table.join( end, {description = "focus previous by index", group = "client"} ), - awful.key({ modkey, }, "w", function () mymainmenu:show() end, - {description = "show main menu", group = "awesome"}), + awful.key({ modkey, }, "w", function () dropdown:toggle() end, + {description = "toggle dropdown terminal", group = "client"}), + + awful.key({ }, "F2", function () htop:toggle() end, + {description = "toggle dropdown htop terminal", group = "client"}), + + awful.key({ modkey, "Shift" }, "m", function () vimpc:toggle() end, + {description = "toggle dropdown vimpc terminal", group = "client"}), -- Layout manipulation awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end, @@ -614,10 +713,22 @@ globalkeys = gears.table.join( {description = "increase the number of columns", group = "layout"}), awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end, {description = "decrease the number of columns", group = "layout"}), - awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end, - {description = "select next", group = "layout"}), - awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end, - {description = "select previous", group = "layout"}), + awful.key({ modkey, }, "space", function () + start_switcher(); + awful.layout.inc( 1); + layout_table[awful.screen.focused().selected_tag] = awful.screen.focused().selected_tag.layout + switcher_timer:again() + end, {description = "select next", group = "layout"}), + awful.key({ modkey, "Shift" }, "space", function () + start_switcher(); + awful.layout.inc(-1); + layout_table[awful.screen.focused().selected_tag] = awful.screen.focused().selected_tag.layout + switcher_timer:again() + end, {description = "select previous", group = "layout"}), + + awful.key({ modkey }, "m", function() awful.spawn("mpc toggle") end), + awful.key({ modkey }, "]", function() awful.spawn("mpc next") end), + awful.key({ modkey }, "[", function() awful.spawn("mpc prev") end), awful.key({ modkey, "Control" }, "n", function () @@ -651,6 +762,7 @@ globalkeys = gears.table.join( awful.key({ modkey }, "d", function() rofi_spawn("rofi -show run") end, {description = "launch rofi", group = "launcher"}), + --[[ awful.key({ modkey, "Shift" }, "m", function (c) rofi_spawn("dmenu_script minecraft.sh") @@ -661,6 +773,7 @@ globalkeys = gears.table.join( rofi_spawn("dmenu_script factorio.sh") end , {description = "Play Factorio"}), + --]] awful.key({ modkey, "Shift" }, "g", function (c) rofi_spawn("dmenu_script lutris.sh") @@ -801,7 +914,10 @@ awful.rules.rules = { "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size. "Wpa_gui", "veromix", - "xtightvncviewer"}, + "xtightvncviewer", + "tilda", + "Tilda" + }, -- Note that the name property shown in xprop might be set slightly after creation of the client -- and the name shown there might not match defined rules here. @@ -890,11 +1006,5 @@ client.connect_signal("mouse::enter", function(c) end) -client.connect_signal("mouse::move", function(c) - if switcher_mode and switcher_timer.started then - switcher_timer:again() - end -end) - -- }}}