fix: screen sharing on wayland; add:safeeyes

this did not work due to a missing/wrong implementation of pipewire
and xdg-portal. Now screensharing works in Microsoft Teams, Firefox as
well as Discord.

This also adds the safeeyes service.
This commit is contained in:
Swarsel 2024-08-10 16:40:35 +02:00
parent dfe2c3922d
commit 5bb6e6038e
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
13 changed files with 231 additions and 43 deletions

View file

@ -243,7 +243,7 @@ Do not that =syncthingtray= is also not mentioned here. It is installed as a hom
#+begin_src nix :tangle no :noweb-ref startupnixos #+begin_src nix :tangle no :noweb-ref startupnixos
{ command = "nextcloud --background"; } { command = "nextcloud --background"; }
{ command = "discord --start-minimized"; } { command = "vesktop --start-minimized"; }
{ command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } { command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; }
{ command = "ANKI_WAYLAND=1 anki"; } { command = "ANKI_WAYLAND=1 anki"; }
{ command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }
@ -4396,7 +4396,7 @@ As such, I also define three additional overlays:
#+begin_src shell :tangle scripts/swarselcheck.sh #+begin_src shell :tangle scripts/swarselcheck.sh
kitty=0 kitty=0
element=0 element=0
discord=0 vesktop=0
spotifyplayer=0 spotifyplayer=0
while :; do while :; do
case ${1:-} in case ${1:-} in
@ -4404,7 +4404,7 @@ As such, I also define three additional overlays:
;; ;;
-e|--element) element=1 -e|--element) element=1
;; ;;
-d|--discord) discord=1 -d|--vesktop) vesktop=1
;; ;;
-s|--spotifyplayer) spotifyplayer=1 -s|--spotifyplayer) spotifyplayer=1
;; ;;
@ -4431,12 +4431,12 @@ As such, I also define three additional overlays:
else else
exec swaymsg '[app_id=Element]' kill exec swaymsg '[app_id=Element]' kill
fi fi
elif [[ $discord -eq 1 ]]; then elif [[ $vesktop -eq 1 ]]; then
STR=$(swaymsg -t get_tree | grep discord || true) STR=$(swaymsg -t get_tree | grep vesktop || true)
if [ "$STR" == "" ]; then if [ "$STR" == "" ]; then
exec discord exec vesktop
else else
exec swaymsg '[app_id=discord]' kill exec swaymsg '[app_id=vesktop]' kill
fi fi
elif [[ $spotifyplayer -eq 1 ]]; then elif [[ $spotifyplayer -eq 1 ]]; then
STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true) STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true)
@ -4453,11 +4453,11 @@ As such, I also define three additional overlays:
#+end_src #+end_src
#+begin_src nix :tangle pkgs/swarselcheck/default.nix #+begin_src nix :tangle pkgs/swarselcheck/default.nix
{ writeShellApplication, kitty, element-desktop-wayland, discord, spotify-player, sway, jq}: { writeShellApplication, kitty, element-desktop-wayland, vesktop, spotify-player, sway, jq}:
writeShellApplication { writeShellApplication {
name = "swarselcheck"; name = "swarselcheck";
runtimeInputs = [ kitty element-desktop-wayland discord spotify-player jq ]; runtimeInputs = [ kitty element-desktop-wayland vesktop spotify-player jq ];
text = builtins.readFile ../../scripts/swarselcheck.sh; text = builtins.readFile ../../scripts/swarselcheck.sh;
} }
@ -4842,7 +4842,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a
config.swarselsystems.startup = lib.mkIf (!config.swarselsystems.isNixos) [ config.swarselsystems.startup = lib.mkIf (!config.swarselsystems.isNixos) [
{ command = "sleep 60 && nixGL nextcloud --background"; { command = "sleep 60 && nixGL nextcloud --background";
} }
{ command = "sleep 60 && nixGL discord --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland"; } { command = "sleep 60 && nixGL vesktop --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland"; }
{ command = "sleep 60 && nixGL syncthingtray --wait"; } { command = "sleep 60 && nixGL syncthingtray --wait"; }
{ command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki"; } { command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki"; }
{ command = "nm-applet --indicator"; } { command = "nm-applet --indicator"; }
@ -4880,7 +4880,7 @@ in
type = types.listOf (types.attrsOf types.str); type = types.listOf (types.attrsOf types.str);
default = [ default = [
{ command = "nextcloud --background"; } { command = "nextcloud --background"; }
{ command = "discord --start-minimized"; } { command = "vesktop --start-minimized"; }
{ command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } { command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; }
{ command = "ANKI_WAYLAND=1 anki"; } { command = "ANKI_WAYLAND=1 anki"; }
{ command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }
@ -4946,12 +4946,14 @@ First, we enable the use of =home-manager= as a NixoS module
./network.nix ./network.nix
./time.nix ./time.nix
./hardware.nix ./hardware.nix
./pipewire.nix
./sops.nix ./sops.nix
./packages.nix ./packages.nix
./programs.nix ./programs.nix
./zsh.nix ./zsh.nix
./syncthing.nix ./syncthing.nix
./blueman.nix ./blueman.nix
./safeeyes.nix
./networkdevices.nix ./networkdevices.nix
./gvfs.nix ./gvfs.nix
./interceptiontools.nix ./interceptiontools.nix
@ -4960,11 +4962,30 @@ First, we enable the use of =home-manager= as a NixoS module
./stylix.nix ./stylix.nix
./power-profiles-daemon.nix ./power-profiles-daemon.nix
# ./impermanence.nix # ./impermanence.nix
./nvd-rebuild.nix
./nix-ld.nix ./nix-ld.nix
./gnome-keyring.nix ./gnome-keyring.nix
./sway.nix
./xdg-portal.nix
]; ];
nix.settings.trusted-users = [ "swarsel" ]; nix = let
flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs;
in {
settings = {
experimental-features = [
"nix-command"
"flakes"
"ca-derivations"
];
trusted-users = [ "swarsel" ];
flake-registry = "";
warn-dirty = false;
};
channel.enable = false;
registry = lib.mapAttrs (_: flake: {inherit flake;}) flakeInputs;
nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
};
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;
@ -5137,8 +5158,10 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
keyboard.qmk.enable = true; keyboard.qmk.enable = true;
pulseaudio = { pulseaudio = {
enable = true; enable = lib.mkIf (!config.services.pipewire.enable) true;
package = pkgs.pulseaudioFull; package = pkgs.pulseaudioFull;
}; };
@ -5159,6 +5182,24 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
} }
#+end_src #+end_src
**** Pipewire
#+begin_src nix :tangle profiles/common/nixos/pipewire.nix
_ : {
security.rtkit.enable = true; # this is required for pipewire real-time access
services.pipewire = {
enable = true;
pulse.enable = true;
jack.enable = true;
audio.enable = true;
alsa = {
enable = true;
support32Bit = true;
};
};
}
#+end_src
**** Common network settings **** Common network settings
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: h:7d696b64-debe-4a95-80b5-1e510156a6c6 :CUSTOM_ID: h:7d696b64-debe-4a95-80b5-1e510156a6c6
@ -5525,6 +5566,8 @@ Mostly used to install some compilers and lsp's that I want to have available wh
ledger-live-desktop ledger-live-desktop
# pinentry # pinentry
dbus
swaylock-effects
# secure boot # secure boot
sbctl sbctl
@ -5703,6 +5746,17 @@ Enables the blueman service including the nice system tray icon.
} }
#+end_src #+end_src
***** safeeyes
Enables the blueman service including the nice system tray icon.
#+begin_src nix :tangle profiles/common/nixos/safeeyes.nix
_ :
{
services.safeeyes.enable = true;
}
#+end_src
***** Network devices ***** Network devices
In this section we enable compatibility with several network devices I have at home, mainly printers and scanners. In this section we enable compatibility with several network devices I have at home, mainly printers and scanners.
@ -6113,6 +6167,65 @@ Used for storing sessions in e.g. Nextcloud
} }
#+end_src #+end_src
**** Sway
#+begin_src nix :tangle profiles/common/nixos/sway.nix
{ pkgs, ... }:
{
programs.sway = {
enable = true;
package = pkgs.swayfx;
wrapperFeatures = {
base = true;
gtk = true;
};
extraOptions = [
"--unsupported-gpu"
];
extraSessionCommands = ''
export XDG_SESSION_DESKTOP=sway
export SDL_VIDEODRIVER=wayland
export QT_QPA_PLATFORM=wayland-egl
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export MOZ_ENABLE_WAYLAND=1
export MOZ_DISABLE_RDD_SANDBOX=1
'';
};
}
#+end_src
**** xdg-portal
#+begin_src nix :tangle profiles/common/nixos/xdg-portal.nix
{ pkgs, ... }:
{
xdg.portal = {
enable = true;
config = {
common = {
default = "wlr";
};
};
wlr.enable = true;
wlr.settings.screencast = {
output_name = "eDP-1";
chooser_type = "simple";
chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or";
};
};
}
#+end_src
*** Optional *** Optional
@ -6363,7 +6476,7 @@ Programming languages and default lsp's are defined here: [[#h:0e7e8bea-ec58-499
xournalpp xournalpp
obsidian obsidian
spotify spotify
discord vesktop # discord client
stable.nextcloud-client stable.nextcloud-client
spotify-player spotify-player
element-desktop-wayland element-desktop-wayland
@ -7440,18 +7553,21 @@ The rest of this configuration is found here:
#+begin_src nix :tangle profiles/common/home/waybar.nix #+begin_src nix :tangle profiles/common/home/waybar.nix
{ config, lib, ... }: { config, lib, pkgs, ... }:
{ {
programs.waybar = { programs.waybar = {
enable = true; enable = true;
# systemd.enable = true; systemd = {
enable = true;
target = "sway-sessions.target";
};
settings = { settings = {
mainBar = { mainBar = {
layer = "top"; layer = "top";
position = "top"; position = "top";
modules-left = [ "sway/workspaces" "custom/outer-right-arrow-dark" "sway/window" ]; modules-left = [ "sway/workspaces" "custom/outer-right-arrow-dark" "sway/window" ];
modules-center = [ "sway/mode" "custom/configwarn" ]; modules-center = [ "sway/mode" "custom/configwarn" "custom/nix-updates" ];
"sway/mode" = { "sway/mode" = {
format = "<span style=\"italic\" font-weight=\"bold\">{}</span>"; format = "<span style=\"italic\" font-weight=\"bold\">{}</span>";
}; };
@ -7873,7 +7989,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
wayland.windowManager.sway = { wayland.windowManager.sway = {
enable = true; enable = true;
checkConfig = false; # delete this line once SwayFX is fixed upstream checkConfig = false; # delete this line once SwayFX is fixed upstream
package = lib.mkIf config.swarselsystems.isNixos pkgs.swayfx; package = lib.mkIf config.swarselsystems.isNixos null;
systemd = { systemd = {
enable = true; enable = true;
xdgAutostart = true; xdgAutostart = true;
@ -8002,7 +8118,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
{ title = "(?:Open|Save) (?:File|Folder|As)"; } { title = "(?:Open|Save) (?:File|Folder|As)"; }
{ title = "^Add$"; } { title = "^Add$"; }
{ title = "com-jgoodies-jdiskreport-JDiskReport"; } { title = "com-jgoodies-jdiskreport-JDiskReport"; }
{ app_id = "discord"; } { app_id = "vesktop"; }
{ window_role = "pop-up"; } { window_role = "pop-up"; }
{ window_role = "bubble"; } { window_role = "bubble"; }
{ window_role = "dialog"; } { window_role = "dialog"; }
@ -8067,7 +8183,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
{ {
command = "resize set width 60 ppt height 60 ppt, sticky enable"; command = "resize set width 60 ppt height 60 ppt, sticky enable";
criteria = { criteria = {
app_id = "discord"; app_id = "vesktop";
}; };
} }
{ {
@ -12016,7 +12132,7 @@ Special things to note here: We are running xcape to allow =CAPS= to act as =CTR
startup = [ startup = [
{ command = "sleep 60 && nixGL nextcloud --background";} { command = "sleep 60 && nixGL nextcloud --background";}
# { command = "sleep 60 && nixGL spotify";} # { command = "sleep 60 && nixGL spotify";}
{ command = "sleep 60 && nixGL discord --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland";} { command = "sleep 60 && nixGL vesktop --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland";}
# { command = "sleep 60 && nixGL schildichat-desktop --hidden";} # { command = "sleep 60 && nixGL schildichat-desktop --hidden";}
{ command = "sleep 60 && nixGL syncthingtray --wait"; } { command = "sleep 60 && nixGL syncthingtray --wait"; }
{ command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki";} { command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki";}

View file

@ -5,7 +5,7 @@
{ {
command = "sleep 60 && nixGL nextcloud --background"; command = "sleep 60 && nixGL nextcloud --background";
} }
{ command = "sleep 60 && nixGL discord --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland"; } { command = "sleep 60 && nixGL vesktop --start-minimized -enable-features=UseOzonePlatform -ozone-platform=wayland"; }
{ command = "sleep 60 && nixGL syncthingtray --wait"; } { command = "sleep 60 && nixGL syncthingtray --wait"; }
{ command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki"; } { command = "sleep 60 && ANKI_WAYLAND=1 nixGL anki"; }
{ command = "nm-applet --indicator"; } { command = "nm-applet --indicator"; }

View file

@ -8,7 +8,7 @@ in
type = types.listOf (types.attrsOf types.str); type = types.listOf (types.attrsOf types.str);
default = [ default = [
{ command = "nextcloud --background"; } { command = "nextcloud --background"; }
{ command = "discord --start-minimized"; } { command = "vesktop --start-minimized"; }
{ command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } { command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; }
{ command = "ANKI_WAYLAND=1 anki"; } { command = "ANKI_WAYLAND=1 anki"; }
{ command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }

View file

@ -1,7 +1,7 @@
{ writeShellApplication, kitty, element-desktop-wayland, discord, spotify-player, sway, jq }: { writeShellApplication, kitty, element-desktop-wayland, vesktop, spotify-player, sway, jq }:
writeShellApplication { writeShellApplication {
name = "swarselcheck"; name = "swarselcheck";
runtimeInputs = [ kitty element-desktop-wayland discord spotify-player jq ]; runtimeInputs = [ kitty element-desktop-wayland vesktop spotify-player jq ];
text = builtins.readFile ../../scripts/swarselcheck.sh; text = builtins.readFile ../../scripts/swarselcheck.sh;
} }

View file

@ -121,7 +121,7 @@
startup = [ startup = [
{ command = "nextcloud --background"; } { command = "nextcloud --background"; }
{ command = "discord --start-minimized"; } { command = "vesktop --start-minimized"; }
{ command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } { command = "element-desktop --hidden -enable-features=UseOzonePlatform -ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; }
{ command = "ANKI_WAYLAND=1 anki"; } { command = "ANKI_WAYLAND=1 anki"; }
{ command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }

View file

@ -16,7 +16,7 @@ in
wayland.windowManager.sway = { wayland.windowManager.sway = {
enable = true; enable = true;
checkConfig = false; # delete this line once SwayFX is fixed upstream checkConfig = false; # delete this line once SwayFX is fixed upstream
package = lib.mkIf config.swarselsystems.isNixos pkgs.swayfx; package = lib.mkIf config.swarselsystems.isNixos null;
systemd = { systemd = {
enable = true; enable = true;
xdgAutostart = true; xdgAutostart = true;
@ -112,6 +112,7 @@ in
Return = "mode default"; Return = "mode default";
Right = "resize grow width 10 px or 10 ppt"; Right = "resize grow width 10 px or 10 ppt";
Up = "resize shrink height 10 px or 10 ppt"; Up = "resize shrink height 10 px or 10 ppt";
Tab = "move position center, resize set width 50 ppt height 50 ppt";
}; };
}; };
defaultWorkspace = "workspace 1:"; defaultWorkspace = "workspace 1:";
@ -147,7 +148,7 @@ in
{ title = "(?:Open|Save) (?:File|Folder|As)"; } { title = "(?:Open|Save) (?:File|Folder|As)"; }
{ title = "^Add$"; } { title = "^Add$"; }
{ title = "com-jgoodies-jdiskreport-JDiskReport"; } { title = "com-jgoodies-jdiskreport-JDiskReport"; }
{ app_id = "discord"; } { app_id = "vesktop"; }
{ window_role = "pop-up"; } { window_role = "pop-up"; }
{ window_role = "bubble"; } { window_role = "bubble"; }
{ window_role = "dialog"; } { window_role = "dialog"; }
@ -212,7 +213,7 @@ in
{ {
command = "resize set width 60 ppt height 60 ppt, sticky enable"; command = "resize set width 60 ppt height 60 ppt, sticky enable";
criteria = { criteria = {
app_id = "discord"; app_id = "vesktop";
}; };
} }
{ {
@ -255,23 +256,26 @@ in
in in
" "
exec_always autotiling exec_always autotiling
set $exit \"exit: [s]leep, [p]oweroff, [r]eboot, [l]ogout\" set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\"
mode $exit { mode $exit {
bindsym --to-code { bindsym --to-code {
s exec \"systemctl suspend\", mode \"default\" s exec \"systemctl suspend\", mode \"default\"
l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize && systemctl suspend \", mode \"default \"
p exec \"systemctl poweroff\" p exec \"systemctl poweroff\"
r exec \"systemctl reboot\" r exec \"systemctl reboot\"
l exec \"swaymsg exit\" u exec \"swaymsg exit\"
Return mode \"default\" Return mode \"default\"
Escape mode \"default\" Escape mode \"default\"
${modifier}+x mode \"default\" ${modifier}+Escape mode \"default\"
} }
} }
exec systemctl --user import-environment exec systemctl --user import-environment
${swayfxSettings} ${swayfxSettings}
"; ";

View file

@ -1,15 +1,18 @@
{ config, lib, ... }: { config, lib, pkgs, ... }:
{ {
programs.waybar = { programs.waybar = {
enable = true; enable = true;
# systemd.enable = true; systemd = {
enable = true;
target = "sway-sessions.target";
};
settings = { settings = {
mainBar = { mainBar = {
layer = "top"; layer = "top";
position = "top"; position = "top";
modules-left = [ "sway/workspaces" "custom/outer-right-arrow-dark" "sway/window" ]; modules-left = [ "sway/workspaces" "custom/outer-right-arrow-dark" "sway/window" ];
modules-center = [ "sway/mode" "custom/configwarn" ]; modules-center = [ "sway/mode" "custom/configwarn" "custom/nix-updates" ];
"sway/mode" = { "sway/mode" = {
format = "<span style=\"italic\" font-weight=\"bold\">{}</span>"; format = "<span style=\"italic\" font-weight=\"bold\">{}</span>";
}; };

View file

@ -14,8 +14,10 @@
keyboard.qmk.enable = true; keyboard.qmk.enable = true;
pulseaudio = { pulseaudio = {
enable = true; enable = lib.mkIf (!config.services.pipewire.enable) true;
package = pkgs.pulseaudioFull; package = pkgs.pulseaudioFull;
}; };

View file

@ -0,0 +1,14 @@
_: {
security.rtkit.enable = true; # this is required for pipewire real-time access
services.pipewire = {
enable = true;
pulse.enable = true;
jack.enable = true;
audio.enable = true;
alsa = {
enable = true;
support32Bit = true;
};
};
}

View file

@ -0,0 +1,4 @@
_:
{
services.safeeyes.enable = true;
}

View file

@ -0,0 +1,26 @@
{ pkgs, ... }:
{
programs.sway = {
enable = true;
package = pkgs.swayfx;
wrapperFeatures = {
base = true;
gtk = true;
};
extraOptions = [
"--unsupported-gpu"
];
extraSessionCommands = ''
export XDG_SESSION_DESKTOP=sway
export SDL_VIDEODRIVER=wayland
export QT_QPA_PLATFORM=wayland-egl
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export MOZ_ENABLE_WAYLAND=1
export MOZ_DISABLE_RDD_SANDBOX=1
'';
};
}

View file

@ -0,0 +1,19 @@
{ pkgs, ... }:
{
xdg.portal = {
enable = true;
config = {
common = {
default = "wlr";
};
};
wlr.enable = true;
wlr.settings.screencast = {
output_name = "eDP-1";
chooser_type = "simple";
chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or";
};
};
}

View file

@ -1,6 +1,6 @@
kitty=0 kitty=0
element=0 element=0
discord=0 vesktop=0
spotifyplayer=0 spotifyplayer=0
while :; do while :; do
case ${1:-} in case ${1:-} in
@ -8,7 +8,7 @@ while :; do
;; ;;
-e|--element) element=1 -e|--element) element=1
;; ;;
-d|--discord) discord=1 -d|--vesktop) vesktop=1
;; ;;
-s|--spotifyplayer) spotifyplayer=1 -s|--spotifyplayer) spotifyplayer=1
;; ;;
@ -35,12 +35,12 @@ elif [[ $element -eq 1 ]]; then
else else
exec swaymsg '[app_id=Element]' kill exec swaymsg '[app_id=Element]' kill
fi fi
elif [[ $discord -eq 1 ]]; then elif [[ $vesktop -eq 1 ]]; then
STR=$(swaymsg -t get_tree | grep discord || true) STR=$(swaymsg -t get_tree | grep vesktop || true)
if [ "$STR" == "" ]; then if [ "$STR" == "" ]; then
exec discord exec vesktop
else else
exec swaymsg '[app_id=discord]' kill exec swaymsg '[app_id=vesktop]' kill
fi fi
elif [[ $spotifyplayer -eq 1 ]]; then elif [[ $spotifyplayer -eq 1 ]]; then
STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true) STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true)