switch to niri

This commit is contained in:
xenia 2025-04-30 20:29:26 +02:00
parent 6e9959802b
commit 0a44a5d372
16 changed files with 1194 additions and 10 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
backgrounds/eta-soffa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
backgrounds/eta-tak.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
backgrounds/stenpiren.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -39,9 +39,13 @@
url = "github:youwen5/signal-desktop-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
niri = {
url = "github:sodiboo/niri-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, nix-darwin, kak, unispect, ansi-utils, unambig-path, nixos-apple-silicon, signal-aarch64 }:
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, nix-darwin, kak, unispect, ansi-utils, unambig-path, nixos-apple-silicon, signal-aarch64, niri }:
let
mkPkgs = system: import nixpkgs { system = system; config.allowUnfree = true; };
mkPkgsUnstable = system: import nixpkgs-unstable { system = system; config.allowUnfree = true; };
@ -177,7 +181,7 @@
use-iwd = false;
};
graphical = mkNixOsGraphical {
inherit pkgs pkgs-unstable;
inherit pkgs pkgs-unstable niri;
background = "pan-wire-3.png";
use-display-manager = true;
};
@ -215,6 +219,7 @@
inherit system;
modules = [
nixos-apple-silicon.nixosModules.apple-silicon-support
niri.nixosModules.niri
./nixos/machines/foxhut/hardware.nix
(import ./nixos/machines/foxhut/boot.nix { inherit pkgs pkgs-unstable asahi-firmware; })
(import ./nixos/machines/foxhut/machine.nix { inherit pkgs pkgs-unstable asahi-firmware signal-aarch64; })

View File

@ -1,4 +1,5 @@
{ pkgs }:
{ config, ... }:
let
alacritty = import ./alacritty/alacritty.nix pkgs;
@ -17,11 +18,42 @@ let
'';
};
XWAYLAND_DISPLAY = ":3";
x-wayland-clipboard-daemon = pkgs.writeShellApplication {
name = "x-wayland-clipboard-daemon";
runtimeInputs = [ pkgs.python313 pkgs.wl-clipboard pkgs.xclip ];
text = ''
python3 ${../x-wayland-clipboard-daemon/x-wayland-clipboard-daemon.py}
'';
};
in rec {
home.packages = with pkgs; [
fira-code ibm-plex
networkmanagerapplet # for tray icon
nerd-fonts.roboto-mono # specifically needed for waybar
noto-fonts fira-code ibm-plex
fontconfig
inkscape
xwayland-satellite
pwvucontrol
swaybg
libnotify
blueberry
wl-clipboard xclip wev
quodlibet
xfce.thunar
puddletag
rawtherapee
brightnessctl
obs-studio
]
++ (with pkgs.kdePackages; [
gwenview okular
])
++ (if pkgs.stdenv.isDarwin then [alloy6-mac] else [pkgs.alloy6])
++ (if pkgs.stdenv.isDarwin then [] else [pkgs.keepassxc pkgs.vesktop pkgs.ares])
;
@ -36,4 +68,406 @@ in rec {
]);
extraConfig = builtins.readFile ../dotfiles/init.el;
};
home.pointerCursor =
let miku-cursor = pkgs.stdenv.mkDerivation {
name = "miku-cursor";
src = pkgs.fetchFromGitHub {
owner = "supermariofps";
repo = "hatsune-miku-windows-linux-cursors";
tag = "1.2.6";
sha256 = "sha256-OQjjOc9VnxJ7tWNmpHIMzNWX6WsavAOkgPwK1XAMwtE=";
};
buildPhase = ''
mkdir -p $out/share/icons
cp -r $src/miku-cursor-linux $out/share/icons/miku-cursor
'';
};
in {
size = 96; # size gets overwritten by niri
package = miku-cursor;
name = "miku-cursor";
};
xdg.portal = {
enable = true;
extraPortals = [
pkgs.xdg-desktop-portal-gnome
];
config.common.default = [ "gnome" ];
};
programs.niri.settings = {
debug.render-drm-device = "/dev/dri/renderD128";
input.keyboard = {
xkb = {
layout = "fox";
options = "caps:escape";
};
repeat-delay = 160;
repeat-rate = 30;
};
input.touchpad = {
tap = false;
click-method = "button-areas";
natural-scroll = false;
accel-speed = -0.1;
scroll-factor = 0.5;
};
input.mouse = {
accel-speed = -0.6;
};
outputs."eDP-1" = {
scale = 1.0;
};
binds = with config.lib.niri.actions; {
# common programs
"Mod+Shift+T" = { hotkey-overlay.title = "run alacritty"; action = spawn "alacritty"; };
"Mod+Shift+F" = { hotkey-overlay.title = "run thunar"; action = spawn "thunar"; };
"Mod+Shift+I" = { hotkey-overlay.title = "run firefox"; action = spawn "firefox"; };
"Mod+Shift+K" = { hotkey-overlay.title = "run keepass"; action = spawn "keepassxc"; };
"Mod+Space" = { hotkey-overlay.title = "rofi launcher"; action = spawn "rofi" "-modes" "drun" "-show" "drun"; };
"Mod+E" = { hotkey-overlay.title = "niri msg"; action = spawn "sh" "${./niri-action.sh}"; };
"Mod+Tab" = { hotkey-overlay.title = "focus last window"; action = focus-window-previous; };
"Mod+Comma" = { hotkey-overlay.title = "show these hotkeys"; action = show-hotkey-overlay; };
"Mod+Escape" = { hotkey-overlay.title = "quit niri"; action = quit; };
"Mod+Q" = { hotkey-overlay.title = "close window"; action = close-window; };
"Mod+F" = { hotkey-overlay.title = "switch width"; action = switch-preset-column-width; };
"Mod+T" = { hotkey-overlay.title = "switch to tabbed view"; action = toggle-column-tabbed-display; };
"Mod+Down" = { hotkey-overlay.title = "next tab"; action = focus-window-down; };
"Mod+Up" = { hotkey-overlay.title = "previous tab"; action = focus-window-up; };
"Mod+Shift+3" = { hotkey-overlay.title = "screenshot"; action = screenshot-screen { write-to-disk = false; }; };
"Mod+Shift+4" = { hotkey-overlay.title = "screenshot region"; action = screenshot; };
"Mod+Shift+5" = { hotkey-overlay.title = "screenshot window"; action = screenshot-window { write-to-disk = false; }; };
"Mod+TouchpadScrollRight" = { hotkey-overlay.title = "expand window"; action = set-window-width "+10"; };
"Mod+TouchpadScrollLeft" = { hotkey-overlay.title = "shrink window"; action = set-window-width "-10"; };
"Mod+TouchpadScrollUp" = { hotkey-overlay.title = "expand window"; action = set-window-height "+10"; };
"Mod+TouchpadScrollDown" = { hotkey-overlay.title = "shrink window"; action = set-window-height "-10"; };
"MouseForward" = { hotkey-overlay.title = "next column"; action = focus-column-right; };
"MouseBack" = { hotkey-overlay.title = "previous column"; action = focus-column-left; };
"Mod+MouseForward" = { hotkey-overlay.title = "next workspace"; action = focus-workspace-down; };
"Mod+MouseBack" = { hotkey-overlay.title = "previous workspace"; action = focus-workspace-up; };
};
switch-events = with config.lib.niri.actions; {
"lid-close" = { action = spawn "sh" "-c" "niri msg action do-screen-transition && swaylock"; };
};
spawn-at-startup = [
{ command = [ "${pkgs.xwayland-satellite}/bin/xwayland-satellite" XWAYLAND_DISPLAY ]; }
{ command = [ "${pkgs.swaybg}/bin/swaybg" "--image" "${../backgrounds/eta-tak.jpg}" ]; }
{ command = [ "${x-wayland-clipboard-daemon}" ]; }
{ command = [ "${pkgs.dbus}/bin/dbus-update-activation-environment" "--systemd" "WAYLAND_DISPLAY" "XDG_CURRENT_DESKTOP" ]; }
];
environment.DISPLAY = XWAYLAND_DISPLAY;
window-rules = [
{
draw-border-with-background = false;
geometry-corner-radius =
let rad = 15.0;
in { bottom-left = rad; bottom-right = rad; top-right = rad; top-left = rad; };
clip-to-geometry = true;
}
{
excludes = [
{ app-id = "^org.kde.gwenview$"; }
{ app-id = ''^Gimp-\d+\.\d+$''; }
{ title = '' - YouTube Mozilla Firefox$''; }
{ app-id = ''^blender$''; }
{ app-id = ''^rawtherapee$''; }
];
opacity = 0.95;
}
{
matches = [ { app-id = "om.saivert.pwvucontrol"; } ];
open-floating = true;
default-window-height.proportion = 0.2;
}
{
matches = [ { app-id = "blueberry.py"; } ];
open-floating = true;
}
{ # kicad pop-ups
matches = [
{ title = ''^Choose (Footprint|Symbol|Power Symbol) ''; } # add menus
{ title = ''^Edit \w+ Field$''; }
{ title = ''^(\w|\s)+ Properties$''; }
];
open-floating = true;
default-window-height.fixed = 400;
}
{ # gimp pop-ups
matches = [
{ app-id = ''^Gimp-\d+\.\d+$''; }
];
excludes = [ # exclude the main window
{ title = '' GIMP$''; }
{ title = ''^GNU Image Manipulation Program$''; }
];
open-floating = true;
default-window-height.fixed = 400;
}
];
cursor.size = 48;
prefer-no-csd = true;
layout = {
empty-workspace-above-first = true;
preset-column-widths = [
{ proportion = 2.0 / 3.0; }
{ proportion = 1.0 / 3.0; }
{ proportion = 1.0; }
];
tab-indicator = {
place-within-column = true;
width = 8;
gap = 10;
corner-radius = 5;
gaps-between-tabs = 5;
length.total-proportion = 1.0;
active.gradient = {
from = "red";
to = "yellow";
angle = 0;
"in'" = "oklch longer hue";
relative-to = "workspace-view";
};
inactive.gradient = {
from = "#222";
to = "#666";
angle = 0;
"in'" = "oklch longer hue";
relative-to = "workspace-view";
};
};
focus-ring = {
enable = true;
width = 5;
active.gradient = {
# from = "#a9fff5";
# to = "#ffb185";
from = "#83c6be";
to = "#a87458";
angle = 30;
"in'" = "oklch longer hue";
relative-to = "workspace-view";
};
};
shadow = {
enable = true;
color = "#00000070";
};
};
};
programs.waybar = {
enable = true;
systemd = {
enable = true;
};
settings.mainBar = {
height = 40;
spacing = 20;
layer = "top";
modules-left = [
"tray"
];
modules-center = [
"niri/window"
];
modules-right = [
"pulseaudio" "pulseaudio/slider"
"network"
"bluetooth"
"power-profiles-daemon"
"temperature"
"battery"
"clock"
];
"niri/window" = {
icon = true;
icon-size = 24;
rewrite = {
"(.*) (:? Mozilla (Firefox|Thunderbird)|- Quod Libet)" = "$1"; # remove some titles
" Discord \\| ([^|]*) \\| (.*)" = "$2 $1"; # discord formats things as Discord | Channel | Server
" Discord \\| ([^|]*)" = "$1"; # sometimes there's no server to show
# pinged versions
"\\((\\d+)\\) Discord \\| ([^|]*) \\| (.*)" = "$3 $2 ($1)";
"\\((\\d+)\\) Discord \\| ([^|]*)" = "$2 ($1)";
};
};
pulseaudio = {
format = "{icon}";
format-alt = "{volume} {icon}";
format-alt-click = "click-right";
format-muted = "🔇";
format-icons = {
default = ["" "" ""];
};
scroll-step = 10;
on-click = "pwvucontrol";
tooltip = false;
};
network = {
format = "{icon}";
format-alt = "{ipaddr}/{cidr} {icon}";
format-alt-click = "click-right";
format-icons = {
wifi = [" "];
ethernet = ["󰛳"];
};
on-click = "alacritty -e nmtui";
tooltip = false;
};
bluetooth = {
on-click = "blueberry";
format = "";
};
clock = {
format = "{:%a %d %b %H:%M}";
tooltip = false;
};
battery = {
format = "{capacity}% {icon}";
format-alt = "{time} {icon}";
format-icons = ["" "" "" "" ""];
format-charging = "{capacity}% 󰂅";
interval = 30;
states = {
warning = 25;
critical = 1;
};
tooltip = false;
};
tray = {
icon-size = 24;
spacing = 10;
};
};
style = ''
window {
color: rgba(35, 31, 32, 1);
background: rgba(197, 196, 196, 0.5);
}
.modules-left {
padding-left: 20px;
}
.modules-right {
padding-right: 20px;
}
#pulseaudio-slider {
min-width: 100px;
}
/* don't show the grabbable thing in the slider */
#pulseaudio-slider slider {
min-height: 0px;
min-width: 0px;
opacity: 0;
background-image: none;
border: none;
box-shadow: none;
}
#pulseaudio-slider trough {
min-height: 15px;
min-width: 10px;
border-radius: 5px;
background-color: rgba(35, 31, 32, 1);
}
#pulseaudio-slider highlight {
min-width: 10px;
border-radius: 5px;
background-color: rgba(247, 246, 246, 1);
}
* {
border: none;
border-radius: 0;
font-family: Roboto Mono;
font-size: 20px;
box-shadow: none;
text-shadow: none;
transition-duration: 0s;
}
/* battery icon gets cut off otherwise for some reason */
#battery {
padding-right: 10px;
}
#battery.warning {
color: rgba(255, 210, 4, 1);
}
#battery.critical {
color: rgba(238, 46, 36, 1);
}
'';
};
programs.rofi = {
enable = true;
package = pkgs.rofi-wayland;
theme = "${./rofi-theme.rasi}";
extraConfig = {
matching = "fuzzy";
};
};
services.mako = {
enable = true;
backgroundColor = "#23201fda";
borderColor = "#0f0c0aff";
borderRadius = 10;
borderSize = 2;
margin = "30";
font = "Manrope 16";
width = 600;
};
programs.swaylock = {
enable = true;
package = pkgs.swaylock-effects;
settings = {
# screenshot = true;
image = "${../backgrounds/eta-tak.jpg}";
effect-blur = "20x3";
effect-vignette = "0.4:0.2";
fade-in = 0.5;
indicator = true;
indicator-radius = 400;
indicator-image = "${../images/profile-picture.png}";
ring-color = "22222280";
key-hl-color = "ee44ee80";
line-color = "00000020";
inside-color = "00000000";
};
};
# TODO: make this work
# systemd.user.services.x-wayland-clipboard-daemon =
# {
# Unit = {
# After = "graphical-session.target";
# };
# Service = {
# ExecStart = "${x-wayland-clipboard-daemon}/bin/x-wayland-clipboard-daemon";
# Restart = "on-failure";
# Environment = [ "DISPLAY=${XWAYLAND_DISPLAY}" ];
# };
# };
}

133
home/niri-action.sh Normal file
View File

@ -0,0 +1,133 @@
#!/bin/sh
# from niri msg action help
NIRI_ACTIONS=$(cat <<EOF
quit
power-off-monitors
power-on-monitors
spawn
do-screen-transition
screenshot
screenshot-screen
screenshot-window
close-window
fullscreen-window
focus-window
focus-window-in-column
focus-window-previous
focus-column-left
focus-column-right
focus-column-first
focus-column-last
focus-column-right-or-first
focus-column-left-or-last
focus-window-or-monitor-up
focus-window-or-monitor-down
focus-column-or-monitor-left
focus-column-or-monitor-right
focus-window-down
focus-window-up
focus-window-down-or-column-left
focus-window-down-or-column-right
focus-window-up-or-column-left
focus-window-up-or-column-right
focus-window-or-workspace-down
focus-window-or-workspace-up
focus-window-top
focus-window-bottom
focus-window-down-or-top
focus-window-up-or-bottom
move-column-left
move-column-right
move-column-to-first
move-column-to-last
move-column-left-or-to-monitor-left
move-column-right-or-to-monitor-right
move-window-down
move-window-up
move-window-down-or-to-workspace-down
move-window-up-or-to-workspace-up
consume-or-expel-window-left
consume-or-expel-window-right
consume-window-into-column
expel-window-from-column
swap-window-right
swap-window-left
toggle-column-tabbed-display
set-column-display
center-column
center-window
focus-workspace-down
focus-workspace-up
focus-workspace
focus-workspace-previous
move-window-to-workspace-down
move-window-to-workspace-up
move-window-to-workspace
move-column-to-workspace-down
move-column-to-workspace-up
move-column-to-workspace
move-workspace-down
move-workspace-up
move-workspace-to-index
set-workspace-name
unset-workspace-name
focus-monitor-left
focus-monitor-right
focus-monitor-down
focus-monitor-up
focus-monitor-previous
focus-monitor-next
move-window-to-monitor-left
move-window-to-monitor-right
move-window-to-monitor-down
move-window-to-monitor-up
move-window-to-monitor-previous
move-window-to-monitor-next
move-column-to-monitor-left
move-column-to-monitor-right
move-column-to-monitor-down
move-column-to-monitor-up
move-column-to-monitor-previous
move-column-to-monitor-next
set-window-width
set-window-height
reset-window-height
switch-preset-column-width
switch-preset-window-width
switch-preset-window-height
maximize-column
set-column-width
expand-column-to-available-width
switch-layout
show-hotkey-overlay
move-workspace-to-monitor-left
move-workspace-to-monitor-right
move-workspace-to-monitor-down
move-workspace-to-monitor-up
move-workspace-to-monitor-previous
move-workspace-to-monitor-next
move-workspace-to-monitor
toggle-debug-tint
debug-toggle-opaque-regions
debug-toggle-damage
toggle-window-floating
move-window-to-floating
move-window-to-tiling
focus-floating
focus-tiling
switch-focus-between-floating-and-tiling
move-floating-window
toggle-window-rule-opacity
help
EOF
)
CHOICE=$(echo -n "$NIRI_ACTIONS" | rofi -dmenu -p "niri msg" -markup-rows -sort -sorting-method levenshtein)
if [ $? -ne 0 ] ; then
echo "No choice selected. Exiting"
exit
fi
CHOICE=$(echo "$CHOICE" | cut -d" " -f1) # first word only
niri msg action "$CHOICE"

110
home/rofi-theme.rasi Normal file
View File

@ -0,0 +1,110 @@
/* modified by meeeeeee :3 */
/* from https://github.com/newmanls/rofi-themes-collection/blob/master/themes/rounded-blue-dark.rasi */
/* ROUNDED THEME FOR ROFI */
/* Author: Newman Sanchez (https://github.com/newmanls) */
* {
font: "Manrope 18";
background-color: transparent;
text-color: @fg0;
margin: 0px;
padding: 0px;
spacing: 0px;
}
window {
location: north;
y-offset: calc(50% - 176px);
width: 800;
border-radius: 24px;
background-color: @bg0;
}
mainbox {
padding: 12px;
}
inputbar {
background-color: @bg1;
border-color: @bg3;
border: 2px;
border-radius: 16px;
padding: 8px 16px;
spacing: 16px;
children: [ prompt, entry ];
}
prompt {
text-color: @fg2;
}
entry {
placeholder: "Search";
placeholder-color: @fg3;
}
message {
margin: 12px 0 0;
border-radius: 16px;
border-color: @bg2;
background-color: @bg2;
}
textbox {
padding: 8px 24px;
}
listview {
background-color: transparent;
margin: 12px 0 0;
lines: 8;
columns: 1;
fixed-height: false;
}
element {
padding: 8px 16px;
spacing: 8px;
border-radius: 16px;
}
element normal active {
text-color: @bg3;
}
element alternate active {
text-color: @bg3;
}
element selected normal, element selected active {
background-color: @bg3;
}
element-icon {
size: 1em;
vertical-align: 0.5;
}
element-text {
text-color: inherit;
}
* {
bg0: #212121F2;
bg1: #2A2A2A;
bg2: #3D3D3D80;
bg3: #1A73E8F2;
fg0: #E6E6E6;
fg1: #FFFFFF;
fg2: #969696;
fg3: #3D3D3D;
}

BIN
images/profile-picture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

View File

@ -70,8 +70,12 @@
home-manager
git # for home-manager
iperf3 edir
];
environment.pathsToLink = [ "/share/xdg-desktop-portal" "/share/applications" ];
programs.zsh.enable = true;
programs.java = { enable = true; package = pkgs.jdk11; };

View File

@ -3,6 +3,7 @@
pkgs-unstable,
background-image ? "pan-wire-3.png",
use-display-manager,
niri,
...
}:
let start-plasma-shortcut = pkgs.writeScriptBin "desktop" ''
@ -57,10 +58,14 @@ let start-plasma-shortcut = pkgs.writeScriptBin "desktop" ''
# });
in
{
nixpkgs.overlays = [ niri.overlays.niri ];
programs.niri.enable = true;
services.xserver = {
enable = true;
displayManager.lightdm.enable = use-display-manager;
displayManager.lightdm.enable = true;
xkb = {
layout = "fox";
@ -74,8 +79,8 @@ in
};
};
services.desktopManager.plasma6.enable = true;
services.displayManager.defaultSession = "plasma";
# services.desktopManager.plasma6.enable = true;
services.displayManager.defaultSession = "niri";
services.mullvad-vpn.enable = true;
@ -96,7 +101,7 @@ in
users.users.xenia = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" "dialout" "input" ];
extraGroups = [ "wheel" "docker" "dialout" "input" "plugdev" ];
shell = pkgs.zsh;
uid = 1002;
};
@ -106,7 +111,6 @@ in
thunderbird
glxinfo
start-plasma-shortcut
remmina
libreoffice
kicad-patch

View File

@ -0,0 +1,355 @@
# https://github.com/useronym/dotfiles/blob/master/.XCompose
<Multi_key> <c> <a> <t> <space> : "🐱 "
<Multi_key> <c> <a> <t> <2> : "🐈"
<Multi_key> <p> <l> <space> : "🥺 "
<Multi_key> <p> <l> <e> <a> : "🥺"
<Multi_key> <p> <l> <e> <a> <d> <i> <n> <g> : "🥺"
<Multi_key> <f> <l> <space> : "😳 "
<Multi_key> <f> <l> <u> <s> <h> : "😳"
<Multi_key> <c> <r> <a> <b> : "🦀"
<Multi_key> <g> <e> <c> : "🦎"
<Multi_key> <a> <m> <o> <n> <g> <u> <s> : "ඩ"
<Multi_key> <e> <n> <b> <y> <space> : "⚥"
<Multi_key> <e> <n> <b> <y> <1> : "⚧"
<Multi_key> <e> <n> <b> <y> <2> : "☄"
<Multi_key> <e> <n> <b> <y> <3> : "☿"
<Multi_key> <d> <o> <t> : "·" # same as multi-cdot
<Multi_key> <b> <u> <l> <l> <e> <t> : "∙"
<Multi_key> <m> <u> <l> <t> <i> <o> <c> <u> <l> <a> <r> <o> : "ꙮ"
<Multi_key> <p> <l> <e> <a> <d> <p> <o> <i> <n> <t> : "🥺👉👈"
<Multi_key> <p> <o> <i> <n> <t> : "👉👈"
<Multi_key> <i> <n> <v> : "⁻¹"
# Supersripts and subscripts
<Multi_key> <asciicircum> <0> : "⁰"
<Multi_key> <asciicircum> <1> : "¹"
<Multi_key> <asciicircum> <2> : "²"
<Multi_key> <asciicircum> <3> : "³"
<Multi_key> <asciicircum> <4> : "⁴"
<Multi_key> <asciicircum> <5> : "⁵"
<Multi_key> <asciicircum> <6> : "⁶"
<Multi_key> <asciicircum> <7> : "⁷"
<Multi_key> <asciicircum> <8> : "⁸"
<Multi_key> <asciicircum> <9> : "⁹"
<Multi_key> <asciicircum> <a> : "ᵃ"
<Multi_key> <asciicircum> <b> : "ᵇ"
<Multi_key> <asciicircum> <c> : "ᶜ"
<Multi_key> <asciicircum> <d> : "ᵈ"
<Multi_key> <asciicircum> <e> : "ᵉ"
<Multi_key> <asciicircum> <f> : "ᶠ"
<Multi_key> <asciicircum> <g> : "ᵍ"
<Multi_key> <asciicircum> <h> : "ʰ"
<Multi_key> <asciicircum> <i> : "ⁱ"
<Multi_key> <asciicircum> <j> : "ʲ"
<Multi_key> <asciicircum> <k> : "ᵏ"
<Multi_key> <asciicircum> <l> : "ˡ"
<Multi_key> <asciicircum> <m> : "ᵐ"
<Multi_key> <asciicircum> <n> : "ⁿ"
<Multi_key> <asciicircum> <o> : "ᵒ"
<Multi_key> <asciicircum> <p> : "ᵖ"
<Multi_key> <asciicircum> <r> : "ʳ"
<Multi_key> <asciicircum> <s> : "ˢ"
<Multi_key> <asciicircum> <t> : "ᵗ"
<Multi_key> <asciicircum> <u> : "ᵘ"
<Multi_key> <asciicircum> <v> : "ᵛ"
<Multi_key> <asciicircum> <w> : "ʷ"
<Multi_key> <asciicircum> <x> : "ˣ"
<Multi_key> <asciicircum> <y> : "ʸ"
<Multi_key> <asciicircum> <z> : "ᶻ"
<Multi_key> <asciicircum> <plus> : "⁺"
<Multi_key> <asciicircum> <minus> : "⁻"
<Multi_key> <underscore> <0> : "₀"
<Multi_key> <underscore> <1> : "₁"
<Multi_key> <underscore> <2> : "₂"
<Multi_key> <underscore> <3> : "₃"
<Multi_key> <underscore> <4> : "₄"
<Multi_key> <underscore> <5> : "₅"
<Multi_key> <underscore> <6> : "₆"
<Multi_key> <underscore> <7> : "₇"
<Multi_key> <underscore> <8> : "₈"
<Multi_key> <underscore> <9> : "₉"
<Multi_key> <underscore> <a> : "ₐ"
<Multi_key> <underscore> <e> : "ₑ"
<Multi_key> <underscore> <h> : "ₕ"
<Multi_key> <underscore> <i> : "ᵢ"
<Multi_key> <underscore> <j> : "ⱼ"
<Multi_key> <underscore> <k> : "ₖ"
<Multi_key> <underscore> <l> : "ₗ"
<Multi_key> <underscore> <m> : "ₘ"
<Multi_key> <underscore> <n> : "ₙ"
<Multi_key> <underscore> <o> : "ₒ"
<Multi_key> <underscore> <p> : "ₚ"
<Multi_key> <underscore> <r> : "ᵣ"
<Multi_key> <underscore> <s> : "ₛ"
<Multi_key> <underscore> <t> : "ₜ"
<Multi_key> <underscore> <u> : "ᵤ"
<Multi_key> <underscore> <v> : "ᵥ"
<Multi_key> <underscore> <x> : "ₓ"
<Multi_key> <underscore> <plus> : "₊"
<Multi_key> <underscore> <minus> : "₋"
<Multi_key> <underscore> <equal> : "₌"
<Multi_key> <underscore> <parenleft> : "₍"
<Multi_key> <underscore> <parenright> : "₎"
# Written prose fancy characters
<Multi_key> <l> <d> <o> <t> <s> : "…" # latex \ldots
<Multi_key> <period> <period> : "…" # latex \ldots
<Multi_key> <minus> <minus> : "" # en dash
<Multi_key> <minus> <equal> : "—" # em dash
<Multi_key> <c> <h> <e> <c> <k> : "✓"
<Multi_key> <m> <u> <s> <i> <c> : "♪"
<Multi_key> <v> <e> <g> <a> <n> : "Ⓥ"
<Multi_key> <a> <n> <a> <r> <c> <h> <y> : "Ⓐ"
<Multi_key> <s> <h> <r> <u> <g> : " ¯\\_(ツ)_/ "
# Arrows
<Multi_key> <t> <o> <space> : "→ " # latex \to
<Multi_key> <m> <a> <p> <s> <t> <o> : "↦" # latex \mapsto
<Multi_key> <m> <u> <l> <t> <i> <m> <a> <p> : "⊸" # latex \multimap
<Multi_key> <g> <e> <t> <s> : "←" # latex \gets
<Multi_key> <i> <m> <p> <l> : "⇒" # latex \Rightarrow
<Multi_key> <i> <m> <p> <r> : "⇐" # latex \Leftarrow
<Multi_key> <i> <m> <p> <b> : "⇔" # latex \Leftrightarrow
<Multi_key> <u> <p> <space> : "↑ " # latex \uparrow
<Multi_key> <d> <n> : "↓" # latex \downarrow
<Multi_key> <d> <o> <w> <n> : "↓" # latex \downarrow
<Multi_key> <l> <e> <a> <d> <s> <t> <o> : "↝" # latex \leadsto
<Multi_key> <f> <r> <o> <m> <t> <o> : "⇄" # latex \leadsto
# Mathy stuffs
<Multi_key> <n> <a> <b> <l> <a> : "∇"
<Multi_key> <c> <r> <o> <s> <s> : ""
<Multi_key> <v> <e> <c> : "⃗" # combining vector above last symbol
<Multi_key> <d> <i> <f> : "∂"
<Multi_key> <f> <o> <r> <a> <l> <l> : "∀" # latex \forall
<Multi_key> <e> <x> <i> <s> <t> <s> : "∃" # latex \exists
<Multi_key> <t> <o> <p> : "" # latex \top
<Multi_key> <b> <o> <t> : "⊥" # latex \bot
<Multi_key> <s> <t> <a> <r> : "★" # latex \star
<Multi_key> <i> <n> <space> : "∈ " # latex \in
<Multi_key> <n> <i> : "∋" # latex \ni
<Multi_key> <n> <o> <i> <n> : "∉" #latex \notin
<Multi_key> <e> <m> <p> <t> <y> : "∅" # latex \empty
<Multi_key> <p> <r> <o> <d> : "∏" # latex \prod
<Multi_key> <s> <u> <m> : "∑" # latex \sum
<Multi_key> <l> <e> <space> : "≤ " # latex \le
<Multi_key> <g> <e> <q> : "≥" # latex \ge
<Multi_key> <p> <r> <e> <c> : "≺" # latex \prec
<Multi_key> <p> <r> <e> <c> <e> <q> : "⪯" # latex \preceq
<Multi_key> <p> <m> : "±" # latex \pm
<Multi_key> <plus> <plus> : "⧺" # latex ?
<Multi_key> <s> <u> <b> <s> <e> <t> : "⊂" # latex \subset
<Multi_key> <s> <u> <b> <s> <e> <q> : "⊆" # latex \subseteq
<Multi_key> <s> <u> <p> <s> <e> <t> : "⊃" # latex \supset
<Multi_key> <s> <u> <p> <s> <e> <q> : "⊇" # latex \supseteq
<Multi_key> <s> <e> <t> <m> <i> <n> <u> <s> : "" # latex \setminus
<Multi_key> <c> <a> <p> : "∩" # latex \cap
<Multi_key> <c> <u> <p> : "" # latex \cup
<Multi_key> <s> <q> <c> <u> <p> : "⊔" # latex \sqcup
<Multi_key> <s> <q> <c> <a> <p> : "⊓" # latex \sqcap
<Multi_key> <u> <p> <l> <u> <s> : "⊎" # latex \uplus
<Multi_key> <U> <p> <l> <u> <s> : "⨄" # latex \Uplus
<Multi_key> <r> <h> <d> :"⊳" # latex \rhd
<Multi_key> <l> <h> <d> :"⊲" # latex \lhd
<Multi_key> <t> <h> <e> <r> <e> <f> <o> <r> <e> : "∴" # latex \therefore
<Multi_key> <q> <e> <d> : "∎" # latex \qed
<Multi_key> <b> <N> : "" # latex \N
<Multi_key> <b> <B> : "𝔹" # latex \N
<Multi_key> <b> <Z> : "" # latex \Z
<Multi_key> <b> <C> : "" # latex \C
<Multi_key> <b> <Q> : "" # latex \Q
<Multi_key> <b> <R> : "" # latex \R
<Multi_key> <b> <E> : "𝔼" # latex \E
<Multi_key> <b> <F> : "𝔽" # latex \F
<Multi_key> <i> <n> <f> <t> <y> : "∞" # latex \infty
<Multi_key> <e> <q> <u> <i> <v> : "≡" # latex \equiv
<Multi_key> <n> <e> <q> <u> <i> <v> : "≢" # latex \not\equiv
<Multi_key> <s> <i> <m> <e> <q> : "≃" # latex \simeq
<Multi_key> <a> <p> <p> <r> <o> <x> : "≈" # latex \approx
<Multi_key> <c> <o> <n> <g> : "≅" # latex \cong
<Multi_key> <n> <e> <q> <space> : "≠ " # latex \ne
<Multi_key> <e> <q> <m> <a> <y> <b> <e> : "≟" # latex \?
<Multi_key> <p> <r> <o> <v> <e> <s> : "⊢" # latex \vdash
<Multi_key> <n> <p> <r> <o> <v> <e> <s> : "⊬" # latex \nvdash
<Multi_key> <e> <n> <t> <a> <i> <l> <s> : "⊨" # latex \vDash
<Multi_key> <f> <o> <r> <c> <e> <s> : "⊩" # latex \Vdash
<Multi_key> <p> <e> <r> <p> : "⊥" # latex \perp
<Multi_key> <v> <e> <e> : "" # latex \vee
<Multi_key> <w> <e> <d> <g> <e> : "∧" # latex \wedge
<Multi_key> <n> <o> <t> : "¬" # latex \not
<Multi_key> <c> <d> <o> <t> : "⋅" # latex \cdot
<Multi_key> <colon> <space> : "﹕ " # latex \?
<Multi_key> <b> <u> <l> <l> <e> <t> : "•" # latex \bullet
<Multi_key> <c> <i> <r> <c> : "∘" # latex \circ
<Multi_key> <t> <i> <m> <e> <s> : "×" # latex \times
# <Multi_key> <o> <p> <l> <u> <s> : "⊕" # latex \oplus
# <Multi_key> <c> <i> <r> <c> <l> <e> <d> <a> <s> <t> : "⊛" # latex \circledast
<Multi_key> <O> <plus> : "⊕" # latex \oplus
<Multi_key> <O> <x> : "⊗" # latex \otimes
<Multi_key> <O> <asterisk> : "⊛" # latex \circledast
<Multi_key> <l> <a> <n> <g> <l> <e> : "⟨" # latex \langle
<Multi_key> <r> <a> <n> <g> <l> <e> : "⟩" # latex \rangle
<Multi_key> <bracketleft> : "⟦" # latex \llbracket
<Multi_key> <bracketright> : "⟧" # latex \rrbracket
<Multi_key> <underscore> <bracketleft> : "⌊" # latex ?
<Multi_key> <underscore> <bracketright> : "⌋" # latex ?
<Multi_key> <asciicircum> <bracketleft> : "⌈" # latex ?
<Multi_key> <asciicircum> <bracketright> : "⌉" # latex ?
<Multi_key> <colon> <colon> : "∷" # latex ?
<Multi_key> <l> <o> <z> <e> <n> <g> <e> : "◊" # latex \lozenge
<Multi_key> <d> <e> <g> : "°"
<Multi_key> <comma> : "⹁" # latex ?
<Multi_key> <semicolon> : "⁏" # latex ?
<Multi_key> <b> <o> <x> : "□" # latex ?
<Multi_key> <f> <l> <a> <t> : "♭" # latex ?
<Multi_key> <s> <h> <a> <r> <p> : "♯" # latex ?
# Greek alphabet
<Multi_key> <a> <l> <p> <h> <a> : "α" # latex \alpha
<Multi_key> <b> <e> <t> <a> : "β" # latex \beta
<Multi_key> <g> <a> <m> <m> <a> : "γ" # latex \gamma
<Multi_key> <d> <e> <l> <t> <a> : "δ" # latex \delta
<Multi_key> <e> <p> <s> <i> <l> <o> <n> : "ε" # latex \epsilon
<Multi_key> <z> <e> <t> <a> : "ζ" # latex \zeta
<Multi_key> <e> <t> <a> : "η" # latex \eta
<Multi_key> <t> <h> <e> <t> <a> : "θ" # latex \theta
<Multi_key> <i> <o> <t> <a> : "ι" # latex \iota
<Multi_key> <k> <a> <p> <p> <a> : "κ" # latex \kappa
<Multi_key> <l> <a> <m> <b> <d> <a> : "λ" # latex \lambda
<Multi_key> <l> <a> <m> <b> <d> <b> : "ƛ" # latex \lambda
<Multi_key> <m> <u> <space> : "μ " # latex \mu
<Multi_key> <m> <i> <c> <r> <o> : "μ" # latex \mu
<Multi_key> <n> <u> : "ν" # latex \nu
<Multi_key> <x> <i> : "ξ" # latex \xi
<Multi_key> <o> <m> <i> <c> <r> <o> <n> : "ο" # latex \omicron
<Multi_key> <p> <i> : "π" # latex \pi
<Multi_key> <r> <h> <o> : "ρ" # latex \rho
<Multi_key> <s> <t> <i> <g> <m> <a> : "ς" # latex \stigma
<Multi_key> <s> <i> <g> <m> <a> : "σ" # latex \sigma
<Multi_key> <t> <a> <u> : "τ" # latex \tau
<Multi_key> <u> <p> <s> <i> <l> <o> <n> : "υ" # latex \upsilon
<Multi_key> <p> <h> <i> : "ϕ" # latex \phi
<Multi_key> <v> <a> <r> <p> <h> <i> : "φ" # latex \varphi
<Multi_key> <c> <h> <i> : "χ" # latex \chi
<Multi_key> <p> <s> <i> : "ψ" # latex \psi
<Multi_key> <o> <m> <e> <g> <a> : "ω" # latex \omega
<Multi_key> <A> <l> <p> <h> <a> : "Α" # latex \Alpha
<Multi_key> <B> <e> <t> <a> : "Β" # latex \Beta
<Multi_key> <G> <a> <m> <m> <a> : "Γ" # latex \Gamma
<Multi_key> <D> <e> <l> <t> <a> : "Δ" # latex \Delta
<Multi_key> <E> <p> <s> <i> <l> <o> <n> : "Ε" # latex \Epsilon
<Multi_key> <Z> <e> <t> <a> : "Ζ" # latex \Zeta
<Multi_key> <E> <t> <a> : "Η" # latex \Eta
<Multi_key> <T> <h> <e> <t> <a> : "Θ" # latex \Theta
<Multi_key> <I> <o> <t> <a> : "Ι" # latex \Iota
<Multi_key> <K> <a> <p> <p> <a> : "Κ" # latex \Kappa
<Multi_key> <L> <a> <m> <b> <d> <a> : "Λ" # latex \Lambda
<Multi_key> <M> <u> : "Μ" # latex \Mu
<Multi_key> <N> <u> : "Ν" # latex \Nu
<Multi_key> <X> <i> : "Ξ" # latex \Xi
<Multi_key> <O> <m> <i> <c> <r> <o> <n> : "Ο" # latex \Omicron
<Multi_key> <P> <i> : "Π" # latex \Pi
<Multi_key> <R> <h> <o> : "Ρ" # latex \Rho
<Multi_key> <S> <i> <g> <m> <a> : "Σ" # latex \Sigma
<Multi_key> <T> <a> <u> : "Τ" # latex \Tau
<Multi_key> <U> <p> <s> <i> <l> <o> <n> : "Υ" # latex \Upsilon
<Multi_key> <P> <h> <i> : "Φ" # latex \Phi
<Multi_key> <C> <h> <i> : "Χ" # latex \Chi
<Multi_key> <P> <s> <i> : "Ψ" # latex \Psi
<Multi_key> <O> <m> <e> <g> <a> : "Ω" # latex \Omega
# Caligraphy
<Multi_key> <c> <a> <l> <A> : "𝓐"
<Multi_key> <c> <a> <l> <B> : "𝓑"
<Multi_key> <c> <a> <l> <C> : "𝓒"
<Multi_key> <c> <a> <l> <D> : "𝓓"
<Multi_key> <c> <a> <l> <E> : "𝓔"
<Multi_key> <c> <a> <l> <F> : "𝓕"
<Multi_key> <c> <a> <l> <G> : "𝓖"
<Multi_key> <c> <a> <l> <H> : "𝓗"
<Multi_key> <c> <a> <l> <I> : "𝓘"
<Multi_key> <c> <a> <l> <J> : "𝓙"
<Multi_key> <c> <a> <l> <K> : "𝓚"
<Multi_key> <c> <a> <l> <L> : "𝓛"
<Multi_key> <c> <a> <l> <M> : "𝓜"
<Multi_key> <c> <a> <l> <N> : "𝓝"
<Multi_key> <c> <a> <l> <O> : "𝓞"
<Multi_key> <c> <a> <l> <P> : "𝓟"
<Multi_key> <c> <a> <l> <Q> : "𝓠"
<Multi_key> <c> <a> <l> <R> : "𝓡"
<Multi_key> <c> <a> <l> <S> : "𝓢"
<Multi_key> <c> <a> <l> <T> : "𝓣"
<Multi_key> <c> <a> <l> <U> : "𝓤"
<Multi_key> <c> <a> <l> <V> : "𝓥"
<Multi_key> <c> <a> <l> <W> : "𝓦"
<Multi_key> <c> <a> <l> <X> : "𝓧"
<Multi_key> <c> <a> <l> <Y> : "𝓨"
<Multi_key> <c> <a> <l> <Z> : "𝓩"
<Multi_key> <c> <a> <l> <0> : "𝟎"
<Multi_key> <c> <a> <l> <1> : "𝟏"
<Multi_key> <c> <a> <l> <2> : "𝟐"
<Multi_key> <c> <a> <l> <3> : "𝟑"
<Multi_key> <c> <a> <l> <4> : "𝟒"
<Multi_key> <c> <a> <l> <5> : "𝟓"
<Multi_key> <c> <a> <l> <6> : "𝟔"
<Multi_key> <c> <a> <l> <7> : "𝟕"
<Multi_key> <c> <a> <l> <8> : "𝟖"
<Multi_key> <c> <a> <l> <9> : "𝟗"
# Fraktur
<Multi_key> <f> <r> <a> <a> : "𝖆"
<Multi_key> <f> <r> <a> <b> : "𝖇"
<Multi_key> <f> <r> <a> <c> : "𝖈"
<Multi_key> <f> <r> <a> <d> : "𝖉"
<Multi_key> <f> <r> <a> <e> : "𝖊"
<Multi_key> <f> <r> <a> <f> : "𝖋"
<Multi_key> <f> <r> <a> <g> : "𝖌"
<Multi_key> <f> <r> <a> <h> : "𝖍"
<Multi_key> <f> <r> <a> <i> : "𝖎"
<Multi_key> <f> <r> <a> <j> : "𝖏"
<Multi_key> <f> <r> <a> <k> : "𝖐"
<Multi_key> <f> <r> <a> <l> : "𝖑"
<Multi_key> <f> <r> <a> <m> : "𝖒"
<Multi_key> <f> <r> <a> <n> : "𝖓"
<Multi_key> <f> <r> <a> <o> : "𝖔"
<Multi_key> <f> <r> <a> <p> : "𝖕"
<Multi_key> <f> <r> <a> <q> : "𝖖"
<Multi_key> <f> <r> <a> <r> : "𝖗"
<Multi_key> <f> <r> <a> <s> : "𝖘"
<Multi_key> <f> <r> <a> <t> : "𝖙"
<Multi_key> <f> <r> <a> <u> : "𝖚"
<Multi_key> <f> <r> <a> <v> : "𝖛"
<Multi_key> <f> <r> <a> <w> : "𝖜"
<Multi_key> <f> <r> <a> <x> : "𝖝"
<Multi_key> <f> <r> <a> <y> : "𝖞"
<Multi_key> <f> <r> <a> <z> : "𝖟"
<Multi_key> <f> <r> <a> <A> : "𝕬"
<Multi_key> <f> <r> <a> <B> : "𝕭"
<Multi_key> <f> <r> <a> <C> : "𝕮"
<Multi_key> <f> <r> <a> <D> : "𝕯"
<Multi_key> <f> <r> <a> <E> : "𝕰"
<Multi_key> <f> <r> <a> <F> : "𝕱"
<Multi_key> <f> <r> <a> <G> : "𝕲"
<Multi_key> <f> <r> <a> <H> : "𝕳"
<Multi_key> <f> <r> <a> <J> : "𝕴"
<Multi_key> <f> <r> <a> <I> : "𝕵"
<Multi_key> <f> <r> <a> <K> : "𝕶"
<Multi_key> <f> <r> <a> <L> : "𝕷"
<Multi_key> <f> <r> <a> <M> : "𝕸"
<Multi_key> <f> <r> <a> <N> : "𝕹"
<Multi_key> <f> <r> <a> <O> : "𝕺"
<Multi_key> <f> <r> <a> <P> : "𝕻"
<Multi_key> <f> <r> <a> <Q> : "𝕼"
<Multi_key> <f> <r> <a> <R> : "𝕽"
<Multi_key> <f> <r> <a> <S> : "𝕾"
<Multi_key> <f> <r> <a> <T> : "𝕿"
<Multi_key> <f> <r> <a> <U> : "𝖀"
<Multi_key> <f> <r> <a> <V> : "𝖁"
<Multi_key> <f> <r> <a> <W> : "𝖂"
<Multi_key> <f> <r> <a> <X> : "𝖃"
<Multi_key> <f> <r> <a> <Y> : "𝖄"
<Multi_key> <f> <r> <a> <Z> : "𝖅"

View File

@ -1,6 +1,6 @@
default
xkb_symbols "fox" {
key <TLDE> {[ comma, semicolon, VoidSymbol, VoidSymbol ]};
key <TLDE> {[ Multi_key ]};
key <AE01> {[ 1, ampersand, VoidSymbol, VoidSymbol ]};
key <AE02> {[ 2, quotedbl, at, VoidSymbol ]};
key <AE03> {[ 3, numbersign, VoidSymbol, VoidSymbol ]};

View File

@ -11,4 +11,6 @@
networking.nameservers = [ "8.8.8.8" ];
networking.resolvconf.enable = true;
networking.resolvconf.dnsExtensionMechanism = false; # edns seems to be fucky with this enabled
programs.nm-applet.enable = true;
}

View File

@ -66,7 +66,7 @@ in
MediaLayerKeys = [
{ Icon = "prev-workspace"; Action = "Finance"; } # bind me in the window manager!
{ Icon = "next-workspace"; Action = "Sport"; } # bind me in the window manager!
{ Icon = "next-workspace"; Action = "Sport"; } # bind me in the window manager!
{ Icon = "brightness_low"; Action = "BrightnessDown"; }
{ Icon = "brightness_high"; Action = "BrightnessUp"; }
{ Icon = "backlight_low"; Action = "IllumDown"; }

View File

@ -0,0 +1,137 @@
# very simple daemon that monitors the clipboard for wayland (using wl-clipboard) and X (using xclip)
# whenever one changes, clipboard-daemon ensures the other changes as well
#
# currently supports syncing text/plain and image/png mimetypes between clipboards
#
# needs wl-paste and xclip in $PATH
from typing import Optional
import subprocess
from abc import ABC
from dataclasses import dataclass
import time
INTERVAL_MS = 100
class ClipboardContents(ABC):
pass
@dataclass
class TextContents(ClipboardContents):
text: bytes
def __repr__(self):
if len(self.text) < 20:
return f"TextContents(text={self.text!r})"
else:
return f"TextContents(text={self.text[:20]!r}..)"
def __str__(self):
return repr(self)
@dataclass
class ImageContents(ClipboardContents):
png_data: bytes
def __repr__(self):
return "ImageContents(png_data=...)"
def __str__(self):
return repr(self)
def get_wayland_clipboard() -> Optional[ClipboardContents]:
formats = subprocess.run(["wl-paste", "-l"], capture_output=True).stdout.strip(b"\n")
if b"image/png" in formats:
contents = subprocess.run(["wl-paste", "-t", "image/png"], capture_output=True).stdout
return ImageContents(png_data=contents)
if b"text/plain" in formats:
contents = subprocess.run(["wl-paste", "-n", "-t", "text/plain"], capture_output=True).stdout
return TextContents(text=contents)
return None
def set_wayland_clipboard(data: ClipboardContents):
if isinstance(data, TextContents):
subprocess.run(
["wl-copy", "-t", "text/plain", "-n"],
input=data.text,
)
elif isinstance(data, ImageContents):
subprocess.run(
["wl-copy", "-t", "image/png"],
input=data.png_data,
)
else:
raise ValueError(f"Unknown clipboard data: {data}")
def get_x_clipboard() -> Optional[ClipboardContents]:
formats = subprocess.run(
["xclip", "-out", "-selection", "clipboard", "-target", "TARGETS"],
capture_output=True,
).stdout.strip(b"\n")
if b"image/png" in formats:
contents = subprocess.run(
["xclip", "-out", "-selection", "clipboard", "-target", "image/png"],
capture_output=True,
).stdout
return ImageContents(png_data=contents)
if b"text/plain" in formats:
contents = subprocess.run(
["xclip", "-out", "-selection", "clipboard", "-target", "text/plain"],
capture_output=True,
).stdout
return TextContents(text=contents)
return None
def set_x_clipboard(data: ClipboardContents):
if isinstance(data, TextContents):
subprocess.run(
["xclip", "-in", "-selection", "clipboard", "-target", "text/plain"],
input=data.text,
)
elif isinstance(data, ImageContents):
subprocess.run(
["xclip", "-in", "-selection", "clipboard", "-target", "image/png"],
input=data.png_data,
)
else:
raise ValueError(f"Unknown clipboard data: {data}")
def clipboard_sync():
last_wayland_contents = get_wayland_clipboard()
last_x_contents = get_x_clipboard()
while True:
time.sleep(INTERVAL_MS/1000)
wayland_contents = get_wayland_clipboard()
x_contents = get_x_clipboard()
if wayland_contents != last_wayland_contents:
print(f"wayland clipborad updated from {last_wayland_contents} to {wayland_contents}")
if wayland_contents is not None:
print(" sycning wayland -> x")
set_x_clipboard(wayland_contents)
x_contents = wayland_contents
else:
print(" unknown type, not syncing")
elif x_contents != last_x_contents:
print(f"x clipborad updated from {last_x_contents} to {x_contents}")
if x_contents is not None:
print(" sycning x -> wayland")
set_wayland_clipboard(x_contents)
wayland_contents_contents = x_contents
else:
print(" unknown type, not syncing")
last_wayland_contents = wayland_contents
last_x_contents = x_contents
print("starting x-wayland-clipboard-daemon")
clipboard_sync()