diff --git a/.dotter/artix-laptop.toml b/.dotter/artix-laptop.toml index 55ba8728..02bb140b 100644 --- a/.dotter/artix-laptop.toml +++ b/.dotter/artix-laptop.toml @@ -6,3 +6,6 @@ dpi = "96" font_size = "12" terminal = "alacritty" browser = "floorp" + +[files] +"config/niri/config-laptop.kdl" = "~/.config/niri/config.kdl" diff --git a/.dotter/artix-machine.toml b/.dotter/artix-machine.toml index d53ae2be..e60c9835 100644 --- a/.dotter/artix-machine.toml +++ b/.dotter/artix-machine.toml @@ -5,3 +5,6 @@ dpi = "96" font_size = "10" terminal = "alacritty" browser = "floorp" + +[files] +"config/niri/config-desktop.kdl" = "~/.config/niri/config.kdl" diff --git a/.dotter/global.toml b/.dotter/global.toml index 989cd610..cdbb2027 100644 --- a/.dotter/global.toml +++ b/.dotter/global.toml @@ -32,7 +32,7 @@ depends = [ "base", "awesome_laptop", "picom", "dunst", "rofi" ] "config/x11/xresources" = {target = "~/.config/x11/xresources", type = "template"} [wayland] -depends = [ "base", "hyprland", "dunst", "rofi", "niri", "fuzzel" ] +depends = [ "base", "hyprland", "niri", "fuzzel", "mako" ] [wayland.files] "config/zsh/.zprofile-wayland" = "~/.config/zsh/.zprofile" @@ -108,11 +108,14 @@ depends = [ "torrent", "zathura", "email" ] [dunst.files] "config/dunst/" = "~/.config/dunst/" -[niri] -depends = [ "misc", "local", "eww", "lock" ] +[mako.files] +"config/mako/" = "~/.config/mako/" -[niri.files] -"config/niri/" = "~/.config/niri/" +[niri] +depends = [ "misc", "local", "waybar", "lock" ] + +# [niri.files] +# "config/niri/" = "~/.config/niri/" [hyprland] depends = [ "misc", "local", "eww", "lock" ] @@ -132,6 +135,7 @@ depends = [ "misc", "local", "eww", "lock" ] [waybar.files] "config/waybar/" = "~/.config/waybar/" +"config/waybar/config.jsonc" = {target = "~/.config/waybar/config.jsonc", type = "template"} [lock.files] "config/gtklock/" = "~/.config/gtklock/" diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua index 2956b99a..dd6e06a6 100644 --- a/config/awesome/rc.lua +++ b/config/awesome/rc.lua @@ -5,14 +5,15 @@ pcall(require, "luarocks.loader") -- AwesomeWM Widgets local calendar_widget = require("awesome-wm-widgets.calendar-widget.calendar") local cpu_widget = require("awesome-wm-widgets.cpu-widget.cpu-widget") +-- local docker_widget = require("awesome-wm-widgets.docker-widget.docker") +local github_activity_widget = require("awesome-wm-widgets.github-activity-widget.github-activity-widget") +local github_contributions_widget = + require("awesome-wm-widgets.github-contributions-widget.github-contributions-widget") local logout_menu_widget = require("awesome-wm-widgets.logout-menu-widget.logout-menu") local net_speed_widget = require("awesome-wm-widgets.net-speed-widget.net-speed") local spotify_shell = require("awesome-wm-widgets.spotify-shell.spotify-shell") local spotify_widget = require("awesome-wm-widgets.spotify-widget.spotify") -local github_activity_widget = require("awesome-wm-widgets.github-activity-widget.github-activity-widget") -local github_contributions_widget = - require("awesome-wm-widgets.github-contributions-widget.github-contributions-widget") --- local docker_widget = require("awesome-wm-widgets.docker-widget.docker") +local volume_widget = require("awesome-wm-widgets.volume-widget.volume") -- Standard awesome library local gears = require("gears") @@ -108,9 +109,9 @@ local myawesomemenu = { hotkeys_popup.show_help(nil, awful.screen.focused()) end, }, - { "manual", terminal .. " -e man awesome" }, + { "manual", terminal .. " -e man awesome" }, { "edit config", editor_cmd .. " " .. awesome.conffile }, - { "restart", awesome.restart }, + { "restart", awesome.restart }, { "quit", function() @@ -295,6 +296,11 @@ awful.screen.connect_for_each_screen(function(s) show_tooltip = true, timeout = 1, }), + volume_widget({ + mixer_cmd = "{{terminal}} -e pulsemixer", + toggle_cmd = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + widget_type = "horizontal_bar", + }), logout_menu_widget({ font = "JetBrainsMono NF 10", onlogout = function() @@ -341,7 +347,7 @@ local globalkeys = gears.table.join( awful.key({}, "Pause", function() awful.spawn.with_shell("sp play") - end, { description = "spotify pause/play", group = "media controls" }), + end, { description = "pause/play spotify", group = "media controls" }), awful.key({}, "#117", function() awful.spawn.with_shell("sp next") @@ -357,31 +363,31 @@ local globalkeys = gears.table.join( awful.key({}, "#171", function() awful.spawn.with_shell("sp next") - end), -- play next + end, { description = "next song", group = "media controls" }), -- play next awful.key({}, "#173", function() awful.spawn.with_shell("sp previous") - end), -- play previous + end, { description = "prev song", group = "media controls" }), -- play previous awful.key({}, "#174", function() awful.spawn.with_shell("playerctl -a stop") - end), -- stop + end, { description = "stop spotify", group = "media controls" }), -- stop awful.key({}, "#172", function() - awful.spawn.with_shell("playerctl -a play-pause") - end), -- play/pause all + awful.spawn.with_shell("playerctl play-pause -a") + end, { description = "play/pause all", group = "media controls" }), -- play/pause all - awful.key({}, "#123", function() - awful.spawn.with_shell("pulsemixer --change-volume +5") - end), -- increase volume + awful.key({}, "XF86AudioRaiseVolume", function() + awful.spawn.with_shell("wpctl set-volume $(get-spotify-id) 0.05+ -l 1") + end, { description = "increase spotify volume", group = "media controls" }), -- increase volume - awful.key({}, "#122", function() - awful.spawn.with_shell("pulsemixer --change-volume -5") - end), -- decrease volume + awful.key({}, "XF86AudioLowerVolume", function() + awful.spawn.with_shell("wpctl set-volume $(get-spotify-id) 0.05-") + end, { description = "decrease spotify volume", group = "media controls" }), -- decrease volume - awful.key({}, "#121", function() - awful.spawn.with_shell("pulsemixer --toggle-mute") - end), -- mute + awful.key({}, "XF86AudioMute", function() + awful.spawn.with_shell("sp play") + end, { description = "play/pause spotify", group = "media controls" }), -- mute awful.key({ "Control" }, "#107", function() awful.spawn.with_shell("( flameshot &; ) && ( sleep 0.5s && flameshot gui )") @@ -673,9 +679,9 @@ awful.rules.rules = { rule_any = { class = { "easyeffects" } }, properties = { screen = 1, tag = "9" }, }, - { rule_any = { class = { "kdeconnect.app" } }, properties = { screen = 2, tag = "7" } }, - { rule_any = { class = { "Spotify" } }, properties = { screen = 2, tag = "9" } }, - { rule_any = { class = { "mpv" } }, properties = { fullscreen = true } }, + { rule_any = { class = { "kdeconnect.app" } }, properties = { screen = 2, tag = "7" } }, + { rule_any = { class = { "Spotify" } }, properties = { screen = 2, tag = "9" } }, + { rule_any = { class = { "mpv" } }, properties = { fullscreen = true } }, } --- Signals diff --git a/config/fuzzel/fuzzel.ini b/config/fuzzel/fuzzel.ini index 4b0546a9..964d098a 100644 --- a/config/fuzzel/fuzzel.ini +++ b/config/fuzzel/fuzzel.ini @@ -25,6 +25,7 @@ border=ebbcbaff [border] radius=20 +width=1 [dmenu] exit-immediately-if-empty=yes diff --git a/config/mako/config b/config/mako/config new file mode 100644 index 00000000..ebc2999e --- /dev/null +++ b/config/mako/config @@ -0,0 +1,23 @@ +layer=top +background-color=#1e1e2eee +border-size=2 +border-color=#74c7ec +border-radius=8 +default-timeout=5000 +font=Cantarell 12 +#output=eDP-1 + +[urgency=high] +layer=overlay +border-color=#f38ba8 + +[desktop-entry="org.telegram.desktop"] +layer=top +border-color=#74c7ec + +[desktop-entry="org.gnome.Fractal"] +layer=top +border-color=#74c7ec + +[mode=dnd] +invisible=1 diff --git a/config/niri/config-desktop.kdl b/config/niri/config-desktop.kdl new file mode 100644 index 00000000..c06c2f36 --- /dev/null +++ b/config/niri/config-desktop.kdl @@ -0,0 +1,637 @@ +// This config is in the KDL format: https://kdl.dev +// "/-" comments out the following node. +// Check the wiki for a full description of the configuration: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Introduction + +environment { + QT_QPA_PLATFORM "wayland" + XDG_SESSION_TYPE "wayland" + XDG_CURRENT_DESKTOP "niri" + XDG_SESSION_DESKTOP "niri" + WM "niri" + DISPLAY ":0" + ELECTRON_OZONE_PLATFORM_HINT "auto" +} + +// Input device configuration. +// Find the full list of options on the wiki: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Input +input { + keyboard { + xkb { + // You can set rules, model, layout, variant and options. + // For more information, see xkeyboard-config(7). + + // For example: + layout "lv" + // options "grp:win_space_toggle,compose:ralt,ctrl:nocaps" + } + + // Enable numlock on startup, omitting this setting disables it. + repeat-delay 300 + repeat-rate 50 + track-layout "global" + // numlock + } + + mouse { + // off + // natural-scroll + accel-speed -0.6 + accel-profile "flat" + // scroll-method "no-scroll" + } + + // Uncomment this to make the mouse warp to the center of newly focused windows. + warp-mouse-to-focus + + // Focus windows and outputs automatically when moving the mouse into them. + // Setting max-scroll-amount="0%" makes it work only on windows already fully on screen. + focus-follows-mouse max-scroll-amount="95%" +} + +cursor { + // xcursor-theme "breeze_cursors" + xcursor-size 16 + + hide-when-typing + hide-after-inactive-ms 1000 +} + +// You can configure outputs by their name, which you can find +// by running `niri msg outputs` while inside a niri instance. +// The built-in laptop monitor is usually called "eDP-1". +// Find more information on the wiki: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Outputs +// Remember to uncomment the node by removing "/-"! +output "DP-1" { + // Uncomment this line to disable this output. + // off + + // Resolution and, optionally, refresh rate of the output. + // The format is "x" or "x@". + // If the refresh rate is omitted, niri will pick the highest refresh rate + // for the resolution. + // If the mode is omitted altogether or is invalid, niri will pick one automatically. + // Run `niri msg outputs` while inside a niri instance to list all outputs and their modes. + mode "1920x1080@74.973" + + // You can use integer or fractional scale, for example use 1.5 for 150% scale. + scale 1 + + // Transform allows to rotate the output counter-clockwise, valid values are: + // normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270. + transform "normal" + + // Position of the output in the global coordinate space. + // This affects directional monitor actions like "focus-monitor-left", and cursor movement. + // The cursor can only move between directly adjacent outputs. + // Output scale and rotation has to be taken into account for positioning: + // outputs are sized in logical, or scaled, pixels. + // For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080, + // so to put another output directly adjacent to it on the right, set its x to 1920. + // If the position is unset or results in an overlap, the output is instead placed + // automatically. + position x=0 y=0 + + variable-refresh-rate on-demand=false + focus-at-startup + background-color "#000" + backdrop-color "#000" +} + +output "HDMI-A-1" { + // off + mode "1920x1080@60.000" + scale 1 + transform "normal" + position x=-1920 y=0 + + variable-refresh-rate on-demand=false + background-color "#000" + backdrop-color "#000" +} + +workspace "browser" { + open-on-output "DP-1" +} + +workspace "eq" { + open-on-output "DP-1" +} + +workspace "chat" { + open-on-output "HDMI-A-1" +} + +workspace "music" { + open-on-output "HDMI-A-1" +} + +// Settings that influence how windows are positioned and sized. +// Find more information on the wiki: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Layout +layout { + // Set gaps around windows in logical pixels. + gaps 4 + + // When to center a column when changing focus, options are: + // - "never", default behavior, focusing an off-screen column will keep at the left + // or right edge of the screen. + // - "always", the focused column will always be centered. + // - "on-overflow", focusing a column will center it if it doesn't fit + // together with the previously focused column. + center-focused-column "never" + + // You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between. + preset-column-widths { + // Proportion sets the width as a fraction of the output width, taking gaps into account. + // For example, you can perfectly fit four windows sized "proportion 0.25" on an output. + // The default preset widths are 1/3, 1/2 and 2/3 of the output. + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + + // Fixed sets the width in logical pixels exactly. + // fixed 1920 + } + + // You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between. + // preset-window-heights { } + + // You can change the default width of the new windows. + default-column-width { proportion 0.5; } + // If you leave the brackets empty, the windows themselves will decide their initial width. + // default-column-width {} + + // By default focus ring and border are rendered as a solid background rectangle + // behind windows. That is, they will show up through semitransparent windows. + // This is because windows using client-side decorations can have an arbitrary shape. + // + // If you don't like that, you should uncomment `prefer-no-csd` below. + // Niri will draw focus ring and border *around* windows that agree to omit their + // client-side decorations. + // + // Alternatively, you can override it with a window rule called + // `draw-border-with-background`. + + // You can change how the focus ring looks. + focus-ring { + // Uncomment this line to disable the focus ring. + off + + // How many logical pixels the ring extends out from the windows. + width 2 + + // Colors can be set in a variety of ways: + // - CSS named colors: "red" + // - RGB hex: "#rgb", "#rgba", "#rrggbb", "#rrggbbaa" + // - CSS-like notation: "rgb(255, 127, 0)", rgba(), hsl() and a few others. + + // Color of the ring on the active monitor. + active-color "#ebbcba" + + // Color of the ring on inactive monitors. + inactive-color "#6e6a86" + + // You can also use gradients. They take precedence over solid colors. + // Gradients are rendered the same as CSS linear-gradient(angle, from, to). + // The angle is the same as in linear-gradient, and is optional, + // defaulting to 180 (top-to-bottom gradient). + // You can use any CSS linear-gradient tool on the web to set these up. + // Changing the color space is also supported, check the wiki for more info. + // + // active-gradient from="#80c8ff" to="#bbddff" angle=45 + + // You can also color the gradient relative to the entire view + // of the workspace, rather than relative to just the window itself. + // To do that, set relative-to="workspace-view". + // + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can also add a border. It's similar to the focus ring, but always visible. + border { + // The settings are the same as for the focus ring. + // If you enable the border, you probably want to disable the focus ring. + // off + + width 2 + active-color "#ebbcba" + inactive-color "#6e6a86" + + // Color of the border around windows that request your attention. + urgent-color "#eb6f92" + + // active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view" + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can enable drop shadows for windows. + shadow { + // Uncomment the next line to enable shadows. + // on + + // By default, the shadow draws only around its window, and not behind it. + // Uncomment this setting to make the shadow draw behind its window. + // + // Note that niri has no way of knowing about the CSD window corner + // radius. It has to assume that windows have square corners, leading to + // shadow artifacts inside the CSD rounded corners. This setting fixes + // those artifacts. + // + // However, instead you may want to set prefer-no-csd and/or + // geometry-corner-radius. Then, niri will know the corner radius and + // draw the shadow correctly, without having to draw it behind the + // window. These will also remove client-side shadows if the window + // draws any. + // + // draw-behind-window true + + // You can change how shadows look. The values below are in logical + // pixels and match the CSS box-shadow properties. + + // Softness controls the shadow blur radius. + softness 30 + + // Spread expands the shadow. + spread 5 + + // Offset moves the shadow relative to the window. + offset x=0 y=5 + + // You can also change the shadow color and opacity. + color "#0007" + } + + // Struts shrink the area occupied by windows, similarly to layer-shell panels. + // You can think of them as a kind of outer gaps. They are set in logical pixels. + // Left and right struts will cause the next window to the side to always be visible. + // Top and bottom struts will simply add outer gaps in addition to the area occupied by + // layer-shell panels and regular gaps. + struts { + // left 64 + // right 64 + // top 64 + // bottom 64 + } +} + +// Add lines like this to spawn processes at startup. +// Note that running niri as a session supports xdg-desktop-autostart, +// which may be more convenient to use. +// See the binds section below for more spawn examples. + +// This line starts waybar, a commonly used bar for Wayland compositors. +spawn-at-startup "xwayland-satellite" +spawn-at-startup "pipewire" +spawn-at-startup "pipewire-pulse" +spawn-at-startup "wireplumber" +spawn-at-startup "mako" +spawn-at-startup "waybar" +// spawn-at-startup "dbus-update-activation-environment" "WAYLAND_DISPLAY" "XDG_CURRENT_DESKTOP" "DISPLAY" "XAUTHORITY" +spawn-at-startup "nextcloud" +spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" +spawn-at-startup "xrdb" "~/.config/x11/xresources" +spawn-at-startup "transmission-daemon" +spawn-at-startup "floorp" +spawn-at-startup "kotatogram-desktop" +spawn-at-startup "discord" +spawn-at-startup "spotify-launcher" + +// Uncomment this line to ask the clients to omit their client-side decorations if possible. +// If the client will specifically ask for CSD, the request will be honored. +// Additionally, clients will be informed that they are tiled, removing some client-side rounded corners. +// This option will also fix border/focus ring drawing behind some semitransparent windows. +// After enabling or disabling this, you need to restart the apps for this to take effect. +prefer-no-csd + +// You can change the path where screenshots are saved. +// A ~ at the front will be expanded to the home directory. +// The path is formatted with strftime(3) to give you the screenshot date and time. +screenshot-path "~/Pictures/screenshots/%Y-%m-%d_%H-%M-%S.png" + +// You can also set this to null to disable saving screenshots to disk. +// screenshot-path null + +// Animation settings. +// The wiki explains how to configure individual animations: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Animations +animations { + // Uncomment to turn off all animations. + off + + // Slow down all animations by this factor. Values below 1 speed them up instead. + // slowdown 3.0 +} + +layer-rule { + match namespace="^notifications$" + block-out-from "screencast" +} + +// Window rules let you adjust behavior for individual windows. +// Find more information on the wiki: +// https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules +// +// Work around WezTerm's initial configure bug +// by setting an empty default-column-width. +window-rule { + // This regular expression is intentionally made as specific as possible, + // since this is the default config, and we want no false positives. + // You can get away with just app-id="wezterm" if you want. + match app-id=r#"^org\.wezfurlong\.wezterm$"# + default-column-width {} +} + +// Open the Firefox picture-in-picture player as floating by default. +window-rule { + // This app-id regular expression will work for both: + // - host Firefox (app-id is "firefox") + // - Flatpak Firefox (app-id is "org.mozilla.firefox") + match app-id=r#"firefox$"# title="^Picture-in-Picture$" + match app-id=r#"floorp$"# title="^Picture-in-Picture$" + open-floating true +} + +window-rule { + match app-id="steam" title=r#"^notificationtoasts_\d+_desktop$"# + default-floating-position x=10 y=10 relative-to="bottom-right" +} + +// Example: block out two password managers from screen capture. +// (This example rule is commented out with a "/-" in front.) +window-rule { + match app-id=r#"^org\.keepassxc\.KeePassXC$"# + match app-id=r#"^org\.gnome\.World\.Secrets$"# + + block-out-from "screen-capture" + + // Use this instead if you want them visible on third-party screenshot tools. + // block-out-from "screencast" +} + +window-rule { + match at-startup=true app-id=r#"floorp$"# + open-maximized false + open-on-workspace "browser" +} + +window-rule { + match at-startup=true app-id=r#"^org\.telegram\.desktop$"# + exclude app-id=r#"^org\.telegram\.desktop$"# title="^Media viewer$" + open-on-workspace "chat" +} + +// Example: enable rounded corners for all windows. +// (This example rule is commented out with a "/-" in front.) +/-window-rule { + geometry-corner-radius 12 + clip-to-geometry true +} + +binds { + // Keys consist of modifiers separated by + signs, followed by an XKB key name + // in the end. To find an XKB name for a particular key, you may use a program + // like wev. + // + // "Mod" is a special modifier equal to Super when running on a TTY, and to Alt + // when running as a winit window. + // + // Most actions that you can bind here can also be invoked programmatically with + // `niri msg action do-something`. + + // Mod-Shift-/, which is usually the same as Mod-?, + // shows a list of important hotkeys. + Mod+Shift+Slash { show-hotkey-overlay; } + + // Suggested binds for running programs: terminal, app launcher, screen locker. + Mod+Return hotkey-overlay-title="Open a Terminal: alacritty" { spawn "alacritty"; } + Mod+P hotkey-overlay-title="Run an Application: fuzzel" { spawn "fuzzel"; } + Super+Space hotkey-overlay-title="Lock the Screen: hyprlock" { spawn "hyprlock"; } + + // You can also use a shell. Do this if you need pipes, multiple commands, etc. + // Note: the entire command goes as a single argument in the end. + // Mod+T { spawn "bash" "-c" "notify-send hello && exec alacritty"; } + + // Example volume keys mappings for PipeWire & WirePlumber. + // The allow-when-locked=true property makes them work even when the session is locked. + XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01+"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01-"; } + XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; } + + // Open/close the Overview: a zoomed-out view of workspaces and windows. + // You can also move the mouse into the top-left hot corner, + // or do a four-finger swipe up on a touchpad. + Mod+O repeat=false { toggle-overview; } + + Mod+Shift+Q { close-window; } + + Mod+H { focus-column-left; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+L { focus-column-right; } + + Mod+Shift+H { move-column-left; } + Mod+Shift+J { move-window-down; } + Mod+Shift+K { move-window-up; } + Mod+Shift+L { move-column-right; } + + // Alternative commands that move across workspaces when reaching + // the first or last window in a column. + // Mod+J { focus-window-or-workspace-down; } + // Mod+K { focus-window-or-workspace-up; } + // Mod+Ctrl+J { move-window-down-or-to-workspace-down; } + // Mod+Ctrl+K { move-window-up-or-to-workspace-up; } + + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + Mod+Ctrl+Home { move-column-to-first; } + Mod+Ctrl+End { move-column-to-last; } + + Mod+Ctrl+H { focus-monitor-left; } + Mod+Ctrl+J { focus-monitor-down; } + Mod+Ctrl+K { focus-monitor-up; } + Mod+Ctrl+L { focus-monitor-right; } + + Mod+Shift+Ctrl+H { move-column-to-monitor-left; } + Mod+Shift+Ctrl+J { move-column-to-monitor-down; } + Mod+Shift+Ctrl+K { move-column-to-monitor-up; } + Mod+Shift+Ctrl+L { move-column-to-monitor-right; } + + // Alternatively, there are commands to move just a single window: + // Mod+Shift+Ctrl+Left { move-window-to-monitor-left; } + // ... + + // And you can also move a whole workspace to another monitor: + // Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; } + // ... + + Mod+Page_Down { focus-workspace-down; } + Mod+Page_Up { focus-workspace-up; } + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + Mod+Ctrl+Page_Down { move-column-to-workspace-down; } + Mod+Ctrl+Page_Up { move-column-to-workspace-up; } + Mod+Ctrl+U { move-column-to-workspace-down; } + Mod+Ctrl+I { move-column-to-workspace-up; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+Page_Down { move-window-to-workspace-down; } + // ... + + Mod+Shift+Page_Down { move-workspace-down; } + Mod+Shift+Page_Up { move-workspace-up; } + Mod+Shift+U { move-workspace-down; } + Mod+Shift+I { move-workspace-up; } + + // You can bind mouse wheel scroll ticks using the following syntax. + // These binds will change direction based on the natural-scroll setting. + // + // To avoid scrolling through workspaces really fast, you can use + // the cooldown-ms property. The bind will be rate-limited to this value. + // You can set a cooldown on any bind, but it's most useful for the wheel. + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } + Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } + + Mod+WheelScrollRight { focus-column-right; } + Mod+WheelScrollLeft { focus-column-left; } + Mod+Ctrl+WheelScrollRight { move-column-right; } + Mod+Ctrl+WheelScrollLeft { move-column-left; } + + // Usually scrolling up and down with Shift in applications results in + // horizontal scrolling; these binds replicate that. + Mod+Shift+WheelScrollDown { focus-column-right; } + Mod+Shift+WheelScrollUp { focus-column-left; } + Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } + Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } + + // Similarly, you can bind touchpad scroll "ticks". + // Touchpad scrolling is continuous, so for these binds it is split into + // discrete intervals. + // These binds are also affected by touchpad's natural-scroll, so these + // example binds are "inverted", since we have natural-scroll enabled for + // touchpads by default. + // Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; } + // Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; } + + // You can refer to workspaces by index. However, keep in mind that + // niri is a dynamic workspace system, so these commands are kind of + // "best effort". Trying to refer to a workspace index bigger than + // the current workspace count will instead refer to the bottommost + // (empty) workspace. + // + // For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on + // will all refer to the 3rd workspace. + Mod+1 { focus-workspace 1; } + Mod+2 { focus-workspace 2; } + Mod+3 { focus-workspace 3; } + Mod+4 { focus-workspace 4; } + Mod+5 { focus-workspace 5; } + Mod+6 { focus-workspace 6; } + Mod+7 { focus-workspace 7; } + Mod+8 { focus-workspace 8; } + Mod+9 { focus-workspace 9; } + Mod+Shift+1 { move-column-to-workspace 1; } + Mod+Shift+2 { move-column-to-workspace 2; } + Mod+Shift+3 { move-column-to-workspace 3; } + Mod+Shift+4 { move-column-to-workspace 4; } + Mod+Shift+5 { move-column-to-workspace 5; } + Mod+Shift+6 { move-column-to-workspace 6; } + Mod+Shift+7 { move-column-to-workspace 7; } + Mod+Shift+8 { move-column-to-workspace 8; } + Mod+Shift+9 { move-column-to-workspace 9; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+1 { move-window-to-workspace 1; } + + // Switches focus between the current and the previous workspace. + // Mod+Tab { focus-workspace-previous; } + + // The following binds move the focused window in and out of a column. + // If the window is alone, they will consume it into the nearby column to the side. + // If the window is already in a column, they will expel it out. + Mod+Comma { consume-or-expel-window-left; } + Mod+Period { consume-or-expel-window-right; } + + // Consume one window from the right to the bottom of the focused column. + // Mod+Comma { consume-window-into-column; } + // Expel the bottom window from the focused column to the right. + // Mod+Period { expel-window-from-column; } + + Mod+R { switch-preset-column-width; } + Mod+Shift+R { switch-preset-window-height; } + Mod+Ctrl+R { reset-window-height; } + Mod+M { maximize-column; } + Mod+F { fullscreen-window; } + + // Expand the focused column to space not taken up by other fully visible columns. + // Makes the column "fill the rest of the space". + Mod+Ctrl+F { expand-column-to-available-width; } + + Mod+C { center-column; } + + // Center all fully visible columns on screen. + Mod+Ctrl+C { center-visible-columns; } + + // Finer width adjustments. + // This command can also: + // * set width in pixels: "1000" + // * adjust width in pixels: "-5" or "+5" + // * set width as a percentage of screen width: "25%" + // * adjust width as a percentage of screen width: "-10%" or "+10%" + // Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0, + // set-column-width "100" will make the column occupy 200 physical screen pixels. + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + + // Finer height adjustments when in column with other windows. + Mod+Shift+Minus { set-window-height "-10%"; } + Mod+Shift+Equal { set-window-height "+10%"; } + + // Move the focused window between the floating and the tiling layout. + Mod+Ctrl+Space { toggle-window-floating; } + Mod+Shift+V { switch-focus-between-floating-and-tiling; } + + // Toggle tabbed column display mode. + // Windows in this column will appear as vertical tabs, + // rather than stacked on top of each other. + Mod+W { toggle-column-tabbed-display; } + + // Actions to switch layouts. + // Note: if you uncomment these, make sure you do NOT have + // a matching layout switch hotkey configured in xkb options above. + // Having both at once on the same hotkey will break the switching, + // since it will switch twice upon pressing the hotkey (once by xkb, once by niri). + // Mod+Space { switch-layout "next"; } + // Mod+Shift+Space { switch-layout "prev"; } + + Print { screenshot; } + Ctrl+Print { screenshot-screen; } + Alt+Print { screenshot-window; } + + // Applications such as remote-desktop clients and software KVM switches may + // request that niri stops processing the keyboard shortcuts defined here + // so they may, for example, forward the key presses as-is to a remote machine.niri + // It's a good idea to bind an escape hatch to toggle the inhibitor, + // so a buggy application can't hold your session hostage. + // + // The allow-inhibiting=false property can be applied to other binds as well, + // which ensures niri always processes them, even when an inhibitor is active. + Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } + + // The quit action will show a confirmation dialog to avoid accidental exits. + Mod+Shift+E { quit; } + Ctrl+Alt+Delete { quit; } + + // Powers off the monitors. To turn them back on, do any input like + // moving the mouse or pressing any other key. + Mod+Shift+P { power-off-monitors; } +} + +hotkey-overlay { + skip-at-startup +} diff --git a/config/niri/config.kdl b/config/niri/config-laptop.kdl similarity index 99% rename from config/niri/config.kdl rename to config/niri/config-laptop.kdl index bfa6ebde..a4ad1fc1 100644 --- a/config/niri/config.kdl +++ b/config/niri/config-laptop.kdl @@ -309,7 +309,7 @@ prefer-no-csd // You can change the path where screenshots are saved. // A ~ at the front will be expanded to the home directory. // The path is formatted with strftime(3) to give you the screenshot date and time. -screenshot-path "~/Pictures/screenshots/%Y-%m-%d-%H%M%S_niri.png" +screenshot-path "~/Pictures/screenshots/%Y-%m-%d_%H-%M-%S.png" // You can also set this to null to disable saving screenshots to disk. // screenshot-path null diff --git a/config/waybar/config b/config/waybar/config.bak similarity index 87% rename from config/waybar/config rename to config/waybar/config.bak index 8de287db..bbb944e6 100644 --- a/config/waybar/config +++ b/config/waybar/config.bak @@ -1,8 +1,8 @@ { "layer": "top", // Waybar at top layer - /* "position": "bottom", // Waybar position (top|bottom|left|right) */ + // "position": "bottom", // Waybar position (top|bottom|left|right) "height": 30, // Waybar height (to be removed for auto height) - /* "width": 1280, // Waybar width */ + // "width": 1280, // Waybar width "spacing": 4, // Gaps between modules (4px) // Choose the order of the modules "modules-left": ["wlr/workspaces", "custom/media"], @@ -13,19 +13,19 @@ "format": "{icon}", "on-click": "activate", "format-icons": { - /* "1": "1", */ - /* "2": "2", */ - /* "3": "3", */ - /* "4": "4", */ - /* "5": "5", */ - /* "6": "6", */ - /* "7": "7", */ - /* "8": "8", */ - /* "9": "9", */ - /* "10": "10", */ - /* "urgent": "", */ - /* "active": "", */ - /* "default": "" */ + // "1": "1", + // "2": "2", + // "3": "3", + // "4": "4", + // "5": "5", + // "6": "6", + // "7": "7", + // "8": "8", + // "9": "9", + // "10": "10", + // "urgent": "", + // "active": "", + // "default": "" }, "sort-by-number": true }, @@ -109,8 +109,8 @@ }, "temperature": { - /* "thermal-zone": 2, */ - /* "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", */ + // "thermal-zone": 2, + // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", "critical-threshold": 80, "format-critical": "{temperatureC}°C ", "format": "{temperatureC}°C ", @@ -118,7 +118,7 @@ }, "backlight": { - /* "device": "acpi_video1", */ + // "device": "acpi_video1", "format": "{percent}% {icon}", "format-icons": ["", "", "", "", "", "", "", "", ""], "on-click": "brightnessctl -q set 60%", @@ -137,8 +137,8 @@ "format-charging": "{capacity}% ", "format-plugged": "{capacity}% ", "format-alt": "{time} {icon}", - /* "format-good": "", // An empty format will hide the module */ - /* "format-full": "", */ + // "format-good": "", // An empty format will hide the module + // "format-full": "", "format-icons": ["", "", "", "", ""] }, @@ -181,7 +181,7 @@ "custom/media": { "format": "{icon} {}", "return-type": "json", - /* "max-length": 40, */ + // "max-length": 40, "on-click": "playerctl play-pause", "on-click-right": "playerctl stop", "on-scroll-up": "playerctl next", @@ -193,9 +193,10 @@ "escape": true, "smooth-scrolling-threshold": 10, // This value was tested using a trackpad, it should be lowered if using a mouse. "exec": "$HOME/.config/waybar/scripts/mediaplayer.py 2> /dev/null" // Script in resources folder - /* "exec": "$HOME/.config/waybar/scripts/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name */ + // "exec": "$HOME/.config/waybar/scripts/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name */ }, + "custom/weather": { "exec": "curl 'https://wttr.in/?format=1'", "interval": 600, diff --git a/config/waybar/config.jsonc b/config/waybar/config.jsonc new file mode 100644 index 00000000..86148618 --- /dev/null +++ b/config/waybar/config.jsonc @@ -0,0 +1,240 @@ +{ + "layer": "top", // Waybar at top layer + // "position": "bottom", // Waybar position (top|bottom|left|right) + // "position": "right", + // "position": "left", + // "output": "eDP-1", + "height": 32, // Waybar height (to be removed for auto height) + "margin-top": 4, + "margin-left": 4, + "margin-right": 4, + // "width": 300, // Waybar width + "spacing": 0, // Gaps between modules (4px) + // Choose the order of the modules + "modules-left": [ + "wlr/taskbar" + ], + "modules-center": [ + "clock" + ], + "modules-right": [ + "tray", + "network", + "cpu", + "memory", + "pulseaudio", + "custom/waybar-media" + ], + // "modules-right": ["cpu", "memory", "battery", "network", "tray"], + // Modules configuration + // "sway/workspaces": { + // "disable-scroll": true, + // "all-outputs": true, + // "warp-on-scroll": false, + // "format": "{name}: {icon}", + // "format-icons": { + // "1": "", + // "2": "", + // "3": "", + // "4": "", + // "5": "", + // "urgent": "", + // "focused": "", + // "default": "" + // } + // }, + "custom/logout": { + "format": "⏻", + "tooltip": false, + "on-click": "niri msg action quit" + }, + "wlr/taskbar": { + // "all-outputs": true, + // "format": "{icon} {title} {short_state}", + "format": "{icon}", + "tooltip-format": "{title} | {app_id}", + "on-click": "activate", + "on-click-middle": "close", + "on-click-right": "fullscreen" + }, + "keyboard-state": { + "numlock": true, + "capslock": true, + "format": "{name} {icon}", + "format-icons": { + "locked": "", + "unlocked": "" + } + }, + "sway/mode": { + "format": "{}" + }, + "sway/scratchpad": { + "format": "{icon} {count}", + "show-empty": false, + "format-icons": [ + "", + "" + ], + "tooltip": true, + "tooltip-format": "{app}: {title}" + }, + "mpd": { + "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ", + "format-disconnected": "Disconnected ", + "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ", + "unknown-tag": "N/A", + "interval": 2, + "consume-icons": { + "on": " " + }, + "random-icons": { + "off": " ", + "on": " " + }, + "repeat-icons": { + "on": " " + }, + "single-icons": { + "on": "1 " + }, + "state-icons": { + "paused": "", + "playing": "" + }, + "tooltip-format": "MPD (connected)", + "tooltip-format-disconnected": "MPD (disconnected)" + }, + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "", + "deactivated": "" + } + }, + "tray": { + // "icon-size": 21, + "spacing": 10 + }, + "clock": { + "interval": 1, + "tooltip-format": "{:%Y %B}\n{calendar}", + "format": "{:%d.%m. %H:%M:%S}" + }, + "cpu": { + "format": "{usage}% 󰍛", + "tooltip": false + }, + "memory": { + "format": "{}% ", + "tooltip-format": "{used:0.1f}G/{total:0.1f}G used" + }, + "temperature": { + // "thermal-zone": 2, + // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", + "critical-threshold": 80, + // "format-critical": "{temperatureC}°C {icon}", + "format": "{temperatureC}°C {icon}", + "format-icons": [ + "", + "", + "" + ] + }, + "backlight": { + // "device": "acpi_video1", + "format": "{percent}% {icon}", + "format-icons": [ + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "battery": { + "states": { + // "good": 95, + "warning": 30, + "critical": 15 + }, + "format": "{capacity}% {icon}", + "format-charging": "{capacity}% ", + "format-plugged": "{capacity}% ", + "format-alt": "{time} {icon}", + // "format-good": "", // An empty format will hide the module + // "format-full": "", + "format-icons": [ + "", + "", + "", + "", + "" + ] + }, + "battery#bat2": { + "bat": "BAT2" + }, + "network": { + // "interface": "wlp2*", // (Optional) To force the use of this interface + "format-wifi": "", + "format-ethernet": "", + "tooltip-format": "{ifname} via {gwaddr} ", + "format-linked": "", + "format-disconnected": "⚠", + "format-alt": "{ifname}: {ipaddr}/{cidr}" + }, + "pulseaudio": { + // "scroll-step": 1, // %, can be a float + "format": "{volume}% {icon}", + "format-bluetooth": "{volume}% {icon}", + "format-bluetooth-muted": " {icon}", + "format-muted": "", + "format-source": "{volume}% ", + "format-source-muted": "", + "format-icons": { + "headphone": "", + "hands-free": "", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": [ + "", + "", + "" + ] + }, + "on-click": "{{terminal}} -e pulsemixer & disown" + }, + "custom/media": { + "format": "{icon} {}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + "exec": "$HOME/.config/waybar/scripts/mediaplayer.py 2> /dev/null" // Script in resources folder + // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + }, + "custom/waybar-media": { + "return-type": "json", + "exec": "waybar-media.py status", + "on-click": "waybar-media.py playpause", + "on-scroll-up": "waybar-media.py previous", + "on-scroll-down": "waybar-media.py next", + "escape": true + }, + "custom/gpu-usage": { + "exec": "cat /sys/devices/pci0000:00/0000:00:08.1/0000:13:00.0/gpu_busy_percent", + "format": "GPU: {}%", + "return-type": "", + "interval": 1 + } +} diff --git a/config/waybar/mediaplayer.py b/config/waybar/mediaplayer.py index 242b5a48..e5a0d9b4 100644 --- a/config/waybar/mediaplayer.py +++ b/config/waybar/mediaplayer.py @@ -1,130 +1 @@ #!/usr/bin/env python3 -import argparse -import logging -import sys -import signal -import json -import gi -from gi.repository import Playerctl, GLib -gi.require_version('Playerctl', '2.0') - -logger = logging.getLogger(__name__) - - -def write_output(text, player): - logger.info('Writing output') - - output = {'text': text, - 'class': 'custom-' + player.props.player_name, - 'alt': player.props.player_name} - - sys.stdout.write(json.dumps(output) + '\n') - sys.stdout.flush() - - -def on_play(player, status, manager): - logger.info('Received new playback status') - on_metadata(player, player.props.metadata, manager) - - -def on_metadata(player, metadata, manager): - logger.info('Received new metadata') - track_info = '' - - if player.props.player_name == 'spotify' and \ - 'mpris:trackid' in metadata.keys() and \ - ':ad:' in player.props.metadata['mpris:trackid']: - track_info = 'AD PLAYING' - elif player.get_artist() != '' and player.get_title() != '': - track_info = '{artist} - {title}'.format(artist=player.get_artist(), - title=player.get_title()) - else: - track_info = player.get_title() - - if player.props.status != 'Playing' and track_info: - track_info = ' ' + track_info - write_output(track_info, player) - - -def on_player_appeared(manager, player, selected_player=None): - if player is not None and (selected_player is None or player.name == selected_player): - init_player(manager, player) - else: - logger.debug( - "New player appeared, but it's not the selected player, skipping") - - -def on_player_vanished(manager, player): - logger.info('Player has vanished') - sys.stdout.write('\n') - sys.stdout.flush() - - -def init_player(manager, name): - logger.debug('Initialize player: {player}'.format(player=name.name)) - player = Playerctl.Player.new_from_name(name) - player.connect('playback-status', on_play, manager) - player.connect('metadata', on_metadata, manager) - manager.manage_player(player) - on_metadata(player, player.props.metadata, manager) - - -def signal_handler(sig, frame): - logger.debug('Received signal to stop, exiting') - sys.stdout.write('\n') - sys.stdout.flush() - # loop.quit() - sys.exit(0) - - -def parse_arguments(): - parser = argparse.ArgumentParser() - - # Increase verbosity with every occurrence of -v - parser.add_argument('-v', '--verbose', action='count', default=0) - - # Define for which player we're listening - parser.add_argument('--player') - - return parser.parse_args() - - -def main(): - arguments = parse_arguments() - - # Initialize logging - logging.basicConfig(stream=sys.stderr, level=logging.DEBUG, - format='%(name)s %(levelname)s %(message)s') - - # Logging is set by default to WARN and higher. - # With every occurrence of -v it's lowered by one - logger.setLevel(max((3 - arguments.verbose) * 10, 0)) - - # Log the sent command line arguments - logger.debug('Arguments received {}'.format(vars(arguments))) - - manager = Playerctl.PlayerManager() - loop = GLib.MainLoop() - - manager.connect('name-appeared', - lambda *args: on_player_appeared(*args, arguments.player)) - manager.connect('player-vanished', on_player_vanished) - - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - - for player in manager.props.player_names: - if arguments.player is not None and arguments.player != player.name: - logger.debug('{player} is not the filtered player, skipping it' - .format(player=player.name) - ) - continue - - init_player(manager, player) - - loop.run() - - -if __name__ == '__main__': - main() diff --git a/config/waybar/rose-pine-dawn.css b/config/waybar/rose-pine-dawn.css new file mode 100644 index 00000000..a85bab2e --- /dev/null +++ b/config/waybar/rose-pine-dawn.css @@ -0,0 +1,23 @@ +/* +* Variant: Rosé Pine Dawn +* Maintainer: DankChoir +*/ + +@define-color base #faf4ed; +@define-color surface #fffaf3; +@define-color overlay #f2e9e1; + +@define-color muted #9893a5; +@define-color subtle #797593; +@define-color text #575279; + +@define-color love #b4637a; +@define-color gold #ea9d34; +@define-color rose #d7827e; +@define-color pine #286983; +@define-color foam #56949f; +@define-color iris #907aa9; + +@define-color highlightLow #f4ede8; +@define-color highlightMed #dfdad9; +@define-color highlightHigh #cecacd; diff --git a/config/waybar/rose-pine-moon.css b/config/waybar/rose-pine-moon.css new file mode 100644 index 00000000..9cf8d2a8 --- /dev/null +++ b/config/waybar/rose-pine-moon.css @@ -0,0 +1,23 @@ +/* +* Variant: Rosé Pine Moon +* Maintainer: DankChoir +*/ + +@define-color base #232136; +@define-color surface #2a273f; +@define-color overlay #393552; + +@define-color muted #6e6a86; +@define-color subtle #908caa; +@define-color text #e0def4; + +@define-color love #eb6f92; +@define-color gold #f6c177; +@define-color rose #ea9a97; +@define-color pine #3e8fb0; +@define-color foam #9ccfd8; +@define-color iris #c4a7e7; + +@define-color highlightLow #2a283e; +@define-color highlightMed #44415a; +@define-color highlightHigh #56526e; diff --git a/config/waybar/rose-pine.css b/config/waybar/rose-pine.css new file mode 100644 index 00000000..0c419267 --- /dev/null +++ b/config/waybar/rose-pine.css @@ -0,0 +1,25 @@ +/* +* Variant: Rosé Pine +* Maintainer: DankChoir +*/ + +@define-color base #191724; +@define-color surface #1f1d2e; +@define-color overlay #26233a; + +@define-color muted #6e6a86; +@define-color subtle #908caa; +@define-color text #e0def4; + +@define-color love #eb6f92; +@define-color gold #f6c177; +@define-color rose #ebbcba; +@define-color pine #31748f; +@define-color foam #9ccfd8; +@define-color iris #c4a7e7; + +@define-color highlightLow #21202e; +@define-color highlightMed #403d52; +@define-color highlightHigh #524f67; + +@define-color base-transparent rgba(25, 23, 36, 0.7); diff --git a/config/waybar/scripts/mediaplayer.py b/config/waybar/scripts/mediaplayer.py old mode 100644 new mode 100755 index 1630d97c..c03ff929 --- a/config/waybar/scripts/mediaplayer.py +++ b/config/waybar/scripts/mediaplayer.py @@ -1,76 +1,85 @@ #!/usr/bin/env python3 import argparse -import logging -import sys -import signal -import gi import json -gi.require_version('Playerctl', '2.0') -from gi.repository import Playerctl, GLib +import logging +import signal +import sys + +import gi + +gi.require_version("Playerctl", "2.0") +from gi.repository import GLib, Playerctl logger = logging.getLogger(__name__) def write_output(text, player): - logger.info('Writing output') + logger.info("Writing output") - output = {'text': text, - 'class': 'custom-' + player.props.player_name, - 'alt': player.props.player_name} + output = { + "text": text, + "class": "custom-" + player.props.player_name, + "alt": player.props.player_name, + } - sys.stdout.write(json.dumps(output) + '\n') + sys.stdout.write(json.dumps(output) + "\n") sys.stdout.flush() def on_play(player, status, manager): - logger.info('Received new playback status') + logger.info("Received new playback status") on_metadata(player, player.props.metadata, manager) def on_metadata(player, metadata, manager): - logger.info('Received new metadata') - track_info = '' + logger.info("Received new metadata") + track_info = "" - if player.props.player_name == 'spotify' and \ - 'mpris:trackid' in metadata.keys() and \ - ':ad:' in player.props.metadata['mpris:trackid']: - track_info = 'AD PLAYING' - elif player.get_artist() != '' and player.get_title() != '': - track_info = '{artist} - {title}'.format(artist=player.get_artist(), - title=player.get_title()) + if ( + player.props.player_name == "spotify" + and "mpris:trackid" in metadata.keys() + and ":ad:" in player.props.metadata["mpris:trackid"] + ): + track_info = "AD PLAYING" + elif player.get_artist() != "" and player.get_title() != "": + track_info = "{artist} - {title}".format( + artist=player.get_artist(), title=player.get_title() + ) else: track_info = player.get_title() - if player.props.status != 'Playing' and track_info: - track_info = ' ' + track_info + if player.props.status != "Playing" and track_info: + track_info = " " + track_info write_output(track_info, player) def on_player_appeared(manager, player, selected_player=None): - if player is not None and (selected_player is None or player.name == selected_player): + if player is not None and ( + selected_player is None or player.name == selected_player + ): init_player(manager, player) else: logger.debug("New player appeared, but it's not the selected player, skipping") def on_player_vanished(manager, player): - logger.info('Player has vanished') - sys.stdout.write('\n') + logger.info("Player has vanished") + sys.stdout.write("\n") sys.stdout.flush() def init_player(manager, name): - logger.debug('Initialize player: {player}'.format(player=name.name)) + logger.debug("Initialize player: {player}".format(player=name.name)) player = Playerctl.Player.new_from_name(name) - player.connect('playback-status', on_play, manager) - player.connect('metadata', on_metadata, manager) + player.connect("playback-status", on_play, manager) + player.connect("metadata", on_metadata, manager) manager.manage_player(player) on_metadata(player, player.props.metadata, manager) def signal_handler(sig, frame): - logger.debug('Received signal to stop, exiting') - sys.stdout.write('\n') + logger.debug("Received signal to stop, exiting") + sys.stdout.write("\n") sys.stdout.flush() # loop.quit() sys.exit(0) @@ -80,10 +89,10 @@ def parse_arguments(): parser = argparse.ArgumentParser() # Increase verbosity with every occurrence of -v - parser.add_argument('-v', '--verbose', action='count', default=0) + parser.add_argument("-v", "--verbose", action="count", default=0) # Define for which player we're listening - parser.add_argument('--player') + parser.add_argument("--player") return parser.parse_args() @@ -92,21 +101,26 @@ def main(): arguments = parse_arguments() # Initialize logging - logging.basicConfig(stream=sys.stderr, level=logging.DEBUG, - format='%(name)s %(levelname)s %(message)s') + logging.basicConfig( + stream=sys.stderr, + level=logging.DEBUG, + format="%(name)s %(levelname)s %(message)s", + ) # Logging is set by default to WARN and higher. # With every occurrence of -v it's lowered by one logger.setLevel(max((3 - arguments.verbose) * 10, 0)) # Log the sent command line arguments - logger.debug('Arguments received {}'.format(vars(arguments))) + logger.debug("Arguments received {}".format(vars(arguments))) manager = Playerctl.PlayerManager() loop = GLib.MainLoop() - manager.connect('name-appeared', lambda *args: on_player_appeared(*args, arguments.player)) - manager.connect('player-vanished', on_player_vanished) + manager.connect( + "name-appeared", lambda *args: on_player_appeared(*args, arguments.player) + ) + manager.connect("player-vanished", on_player_vanished) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) @@ -114,9 +128,11 @@ def main(): for player in manager.props.player_names: if arguments.player is not None and arguments.player != player.name: - logger.debug('{player} is not the filtered player, skipping it' - .format(player=player.name) - ) + logger.debug( + "{player} is not the filtered player, skipping it".format( + player=player.name + ) + ) continue init_player(manager, player) @@ -124,5 +140,5 @@ def main(): loop.run() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/config/waybar/style.css b/config/waybar/style.css index 7fa77bf3..50cdbaaa 100644 --- a/config/waybar/style.css +++ b/config/waybar/style.css @@ -1,68 +1,88 @@ +@import "./rose-pine.css"; + * { - /* `otf-font-awesome` is required to be installed for icons */ - font-family: - JetBrains Mono NF, - FontAwesome, - Roboto, - Helvetica, - Arial, - sans-serif; - font-size: 13px; - color: #c0caf5; + /* `otf-font-awesome` is required to be installed for icons */ + font-family: + JetBrains Mono NF Propo, + JetBrains Mono NF, + FontAwesome, + Roboto, + Helvetica, + Arial, + sans-serif; + font-size: 14px; + /* font-feature-settings: "tnum"; */ + color: @text; + background: @base-transparent; } window#waybar { - border-top: 3px solid transparent; - color: #c0caf5; - transition-property: background-color; - transition-duration: 0.5s; - background-color: transparent; -} - -#window { - border-radius: 20px; - padding-left: 10px; - padding-right: 10px; + background: transparent; + /* background-color: rgba(30, 30, 46, 0.5); */ + /* border-bottom: 2px solid rgba(147, 153, 178, 0.5); */ + /* border: 1px solid rgba(166, 173, 200, 1.0); */ + color: #ffffff; + /* transition-property: background-color; */ + /* transition-duration: .5s; */ } window#waybar.hidden { - opacity: 0.2; + opacity: 0.2; } -window#waybar.chromium { - background-color: #000; - border: none; +/* +window#waybar.empty { + background-color: transparent; +} +window#waybar.solo { + background-color: #FFFFFF; +} +*/ + +window#waybar.termite { + background-color: red; } button { - /* Use box-shadow instead of border so the text isn't offset */ - box-shadow: inset 0 3px transparent; - /* Avoid rounded borders under each button name */ - border: none; - border-radius: 0; + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: none; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; + transition-property: none; } /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ button:hover { - background: inherit; - box-shadow: inset 0 3px #c0caf5; + background: none; + box-shadow: none; + text-shadow: none; + border: none; + -gtk-icon-effect: none; + -gtk-icon-shadow: none; } #workspaces button { - padding: 0 5px; - color: #c0caf5; + padding: 0 5px; + background-color: transparent; } -#workspaces button.active { - box-shadow: inset 0 3px #c0caf5; +#workspaces button:hover { + background: rgba(0, 0, 0, 0.2); +} + +#workspaces button.focused { + background-color: #64727d; + box-shadow: inset 0 -3px #ffffff; } #workspaces button.urgent { - background-color: #db4b4b; + background-color: #eb4d4b; } #mode { - border-bottom: 3px solid #c0caf5; + background-color: #64727d; + border-bottom: 3px solid #ffffff; } #clock, @@ -74,84 +94,249 @@ button:hover { #backlight, #network, #pulseaudio, +#wireplumber, #custom-media, #tray, #mode, #idle_inhibitor, #scratchpad, -#mpd, -#custom-wireguard, -#custom-github, -#custom-dunst { - padding: 0 10px; - font-weight: bold; - background-color: transparent; -} - -#custom-pipewire.muted { - color: #414868; +#mpd { + padding: 0 10px; + border-radius: 99px; + background-color: transparent; } #window, #workspaces { - margin: 0 4px; + margin: 0 4px; } /* If workspaces is the leftmost module, omit left margin */ .modules-left > widget:first-child > #workspaces { - margin-left: 0; + margin-left: 0; } /* If workspaces is the rightmost module, omit right margin */ .modules-right > widget:last-child > #workspaces { - margin-right: 0; + margin-right: 0; } -#battery.charging, -#battery.plugged { - color: #1abc9c; +#clock { + /* background-color: #64727D; */ + font-weight: bold; + /* background-color: rgba(0, 0, 0, 0.3); */ + /* border-radius: 99px; */ +} + +#battery { + /* background-color: #f9e2af; */ + /* color: #000000; */ + margin-left: 4px; +} + +/* +#battery.charging, #battery.plugged { + color: #ffffff; + background-color: #26A65B; } @keyframes blink { to { - color: #c0caf5; + background-color: #ffffff; + color: #000000; } } -#battery.warning:not(.charging) { - color: #e0af68; -} - #battery.critical:not(.charging) { - color: #db4b4b; + background-color: #f53c3c; + color: #ffffff; animation-name: blink; animation-duration: 0.5s; animation-timing-function: linear; animation-iteration-count: infinite; animation-direction: alternate; } +*/ + +label:focus { + background-color: #000000; +} + +#cpu { + /* background-color: #f38ba8; */ + /* color: #000000; */ + border-radius: 99px 0px 0px 99px; + padding: 0 0 0 10px; + margin-left: 4px; +} + +#memory { + /* background-color: #fab387; */ + /* color: #000000; */ + border-radius: 0px 99px 99px 0px; + /* padding: 0 10px 0 0; */ +} + +#disk { + background-color: #964b00; +} + +#backlight { + background-color: #90b1b1; +} + +#network { + /* background-color: #a6e3a1; */ + /* color: #000000; */ +} + +/* +#network.disconnected { + background-color: #f53c3c; +} +*/ + +#taskbar { + margin-left: 4px; +} + +#taskbar button { + color: #f0f0ff; + background-color: rgba(30, 30, 46, 0.6); +} + +#taskbar button:first-child { + border-radius: 99px 0 0 99px; +} + +#taskbar button:last-child { + border-radius: 0 99px 99px 0; +} + +#taskbar button:first-child:last-child { + border-radius: 99px; +} + +#taskbar button:hover { + background-color: rgba(49, 50, 68, 0.6); +} + +#taskbar button.active { + background-color: rgba(88, 91, 112, 0.6); +} + +#taskbar button.active:hover { + background-color: rgba(108, 112, 134, 0.6); +} + +#pulseaudio { + background-color: #f1c40f; + color: #000000; +} #pulseaudio.muted { - color: #414868; + background-color: #90b1b1; + color: #2a5c45; +} + +#wireplumber { + background-color: #fff0f5; + color: #000000; +} + +#wireplumber.muted { + background-color: #f53c3c; } #custom-media { - color: #41a6b5; - min-width: 100px; + background-color: #66cc99; + color: #2a5c45; + min-width: 100px; +} + +#custom-media.custom-spotify { + background-color: #66cc99; +} + +#custom-media.custom-vlc { + background-color: #ffa000; +} + +#temperature { + background-color: #f0932b; } #temperature.critical { - color: #db4b4b; + background-color: #eb4d4b; +} + +#tray { + /* background-color: #2980b9; */ } #tray > .passive { - -gtk-icon-effect: dim; + -gtk-icon-effect: dim; } #tray > .needs-attention { - -gtk-icon-effect: highlight; + -gtk-icon-effect: highlight; + background-color: #eb4d4b; } -#network.disconnected { - color: #db4b4b; +#idle_inhibitor { + background-color: #2d3436; +} + +#idle_inhibitor.activated { + background-color: #ecf0f1; + color: #2d3436; +} + +#mpd { + background-color: #66cc99; + color: #2a5c45; +} + +#mpd.disconnected { + background-color: #f53c3c; +} + +#mpd.stopped { + background-color: #90b1b1; +} + +#mpd.paused { + background-color: #51a37a; +} + +#language { + background: #00b093; + color: #740864; + padding: 0 5px; + margin: 0 5px; + min-width: 16px; +} + +#keyboard-state { + background: #97e1ad; + color: #000000; + padding: 0 0px; + margin: 0 5px; + min-width: 16px; +} + +#keyboard-state > label { + padding: 0 5px; +} + +#keyboard-state > label.locked { + background: rgba(0, 0, 0, 0.2); +} + +#scratchpad { + background: rgba(0, 0, 0, 0.2); +} + +#scratchpad.empty { + background-color: transparent; } diff --git a/config/waybar/style.css.bak b/config/waybar/style.css.bak new file mode 100644 index 00000000..effe8786 --- /dev/null +++ b/config/waybar/style.css.bak @@ -0,0 +1,157 @@ +* { + /* `otf-font-awesome` is required to be installed for icons */ + font-family: + JetBrains Mono NF, + FontAwesome, + Roboto, + Helvetica, + Arial, + sans-serif; + font-size: 13px; + color: #c0caf5; +} + +window#waybar { + border-top: 3px solid transparent; + color: #c0caf5; + transition-property: background-color; + transition-duration: 0.5s; + background-color: transparent; +} + +#window { + border-radius: 20px; + padding-left: 10px; + padding-right: 10px; +} + +window#waybar.hidden { + opacity: 0.2; +} + +window#waybar.chromium { + background-color: #000; + border: none; +} + +button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 3px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; +} + +/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ +button:hover { + background: inherit; + box-shadow: inset 0 3px #c0caf5; +} + +#workspaces button { + padding: 0 5px; + color: #c0caf5; +} + +#workspaces button.active { + box-shadow: inset 0 3px #c0caf5; +} + +#workspaces button.urgent { + background-color: #db4b4b; +} + +#mode { + border-bottom: 3px solid #c0caf5; +} + +#clock, +#battery, +#cpu, +#memory, +#disk, +#temperature, +#backlight, +#network, +#pulseaudio, +#custom-media, +#tray, +#mode, +#idle_inhibitor, +#scratchpad, +#mpd, +#custom-wireguard, +#custom-github, +#custom-dunst { + padding: 0 10px; + font-weight: bold; + background-color: transparent; +} + +#custom-pipewire.muted { + color: #414868; +} + +#window, +#workspaces { + margin: 0 4px; +} + +/* If workspaces is the leftmost module, omit left margin */ +.modules-left>widget:first-child>#workspaces { + margin-left: 0; +} + +/* If workspaces is the rightmost module, omit right margin */ +.modules-right>widget:last-child>#workspaces { + margin-right: 0; +} + +#battery.charging, +#battery.plugged { + color: #1abc9c; +} + +@keyframes blink { + to { + color: #c0caf5; + } +} + +#battery.warning:not(.charging) { + color: #e0af68; +} + +#battery.critical:not(.charging) { + color: #db4b4b; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#pulseaudio.muted { + color: #414868; +} + +#custom-media { + color: #41a6b5; + min-width: 100px; +} + +#temperature.critical { + color: #db4b4b; +} + +#tray>.passive { + -gtk-icon-effect: dim; +} + +#tray>.needs-attention { + -gtk-icon-effect: highlight; +} + +#network.disconnected { + color: #db4b4b; +} diff --git a/local/bin/get-spotify-id b/local/bin/get-spotify-id new file mode 100755 index 00000000..5c2418b2 --- /dev/null +++ b/local/bin/get-spotify-id @@ -0,0 +1,3 @@ +#!/bin/sh + +wpctl status | rg -o '^\s*\d+\.\s*spotify' | awk 'NR==2 {print $1}' | tr -d '.' diff --git a/local/bin/remaps b/local/bin/remaps index a5ff84e6..b1a0d212 100755 --- a/local/bin/remaps +++ b/local/bin/remaps @@ -14,6 +14,7 @@ killall xcape 2>/dev/null # Turn off caps lock if on since there is no longer a key for it. xset -q | grep "Caps Lock:\s*on" && xdotool key Caps_Lock # Turn on num lock -xset -q | grep "Num Lock:\s*off" && xdotool key Num_Lock +# xset -q | grep "Num Lock:\s*off" && xdotool key Num_Lock +xset -q | grep "Num Lock:\s*on" && xdotool key Num_Lock setxkbmap lv diff --git a/local/share/fonts/jetbrainsmono/AUTHORS.txt b/local/share/fonts/jetbrainsmono/AUTHORS.txt new file mode 100755 index 00000000..88149416 --- /dev/null +++ b/local/share/fonts/jetbrainsmono/AUTHORS.txt @@ -0,0 +1,10 @@ +# This is the official list of project authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS.txt file. +# See the latter for an explanation. +# +# Names should be added to this file as: +# Name or Organization + +JetBrains <> +Philipp Nurullin +Konstantin Bulenkov diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Bold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Bold.ttf new file mode 100644 index 00000000..8c93043d Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Bold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.ttf new file mode 100644 index 00000000..1ddf216d Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.ttf new file mode 100644 index 00000000..435d7a72 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.ttf new file mode 100644 index 00000000..79e616eb Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.ttf new file mode 100644 index 00000000..c131cbf2 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.ttf new file mode 100644 index 00000000..a768985b Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Italic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Italic.ttf new file mode 100644 index 00000000..ccc9d6a5 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Italic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Light.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Light.ttf new file mode 100644 index 00000000..15f15a2a Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Light.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-LightItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-LightItalic.ttf new file mode 100644 index 00000000..506208f6 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-LightItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Medium.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Medium.ttf new file mode 100644 index 00000000..97671156 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Medium.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.ttf new file mode 100644 index 00000000..415a9e34 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Regular.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Regular.ttf new file mode 100644 index 00000000..dff66cc5 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Regular.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBold.ttf new file mode 100644 index 00000000..a70e69bd Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.ttf new file mode 100644 index 00000000..968602e8 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-Thin.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-Thin.ttf new file mode 100644 index 00000000..7dbe2ac6 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-Thin.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.ttf new file mode 100644 index 00000000..c6ad6c21 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Bold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Bold.ttf new file mode 100644 index 00000000..f78f84fb Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Bold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-BoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-BoldItalic.ttf new file mode 100644 index 00000000..9fb8c832 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-BoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBold.ttf new file mode 100644 index 00000000..fe5be6a1 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBoldItalic.ttf new file mode 100644 index 00000000..59fc980b Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraBoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLight.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLight.ttf new file mode 100644 index 00000000..6da7b759 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLight.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLightItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLightItalic.ttf new file mode 100644 index 00000000..5733efc5 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ExtraLightItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Italic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Italic.ttf new file mode 100644 index 00000000..4e9c3802 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Italic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Light.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Light.ttf new file mode 100644 index 00000000..0b79b0c8 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Light.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-LightItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-LightItalic.ttf new file mode 100644 index 00000000..b5e08426 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-LightItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Medium.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Medium.ttf new file mode 100644 index 00000000..14543721 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Medium.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-MediumItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-MediumItalic.ttf new file mode 100644 index 00000000..8d63c6cc Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-MediumItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Regular.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Regular.ttf new file mode 100644 index 00000000..70d2ec9e Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Regular.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBold.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBold.ttf new file mode 100644 index 00000000..ce60a88c Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBold.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBoldItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBoldItalic.ttf new file mode 100644 index 00000000..3b3f8f69 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-SemiBoldItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Thin.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Thin.ttf new file mode 100644 index 00000000..bea837e7 Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-Thin.ttf differ diff --git a/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ThinItalic.ttf b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ThinItalic.ttf new file mode 100644 index 00000000..f0bfed7b Binary files /dev/null and b/local/share/fonts/jetbrainsmono/JetBrainsMonoNL-ThinItalic.ttf differ diff --git a/local/share/fonts/jetbrainsmono/OFL.txt b/local/share/fonts/jetbrainsmono/OFL.txt new file mode 100644 index 00000000..8bee4148 --- /dev/null +++ b/local/share/fonts/jetbrainsmono/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE.