Hyprland
Hyprland copied to clipboard
Hyprland crashes when used with kanshi on NixOS
Hello, I'm relatively new to NixOS and hyprland. I'm trying to setup kanshi with hyprland so that when I connect my laptop to my monitors, the internal screen is disabled. But this seems to crash hyprland. Attaching the logs here:
@fufexan tagging you since its NixOS related.
Unfortunately I can't make my NixOS config open but this is the kanshi flake
{ config, lib, pkgs, ... }:
{
services = {
kanshi = {
enable = true;
systemdTarget = "xdg-desktop-portal-hyprland.service";
profiles = {
laptop = {
outputs = [
{
criteria = "eDP-1";
}
];
};
home = {
outputs = [
{
criteria = "Dell Inc. DELL S2722QC FL7WLD3";
mode = "[email protected]";
position = "0,0";
scale = 2.0;
}
{
criteria = "Dell Inc. DELL S2722QC C77WLD3";
mode = "[email protected]";
position = "1920,0";
scale = 2.0;
}
{
criteria = "eDP-1";
status = "disable";
}
];
};
};
};
};
}
My hyprland nix config
{ config, lib, pkgs, ... }:
let
hyprlandConf = ''
exec-once=${pkgs.swaybg}/bin/swaybg -m stretch -i $HOME/.config/wall
exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
exec-once=systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
exec-once=${pkgs.networkmanagerapplet}/bin/nm-applet --indicator
exec-once=${pkgs.waybar}/bin/waybar
exec-once=${pkgs.blueman}/bin/blueman-applet
monitor=eDP-1, highres, 0x0, 1.0
input {
kb_layout = us
kb_options = ctrl:nocaps
follow_mouse = 1
touchpad {
natural_scroll = no
}
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}
bind=SUPER SHIFT, P, exec,${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" - | ${pkgs.swappy}/bin/swappy -f - -o ~/Pictures/$(date +%Hh_%Mm_%Ss_%d_%B_%Y).png && notify-send "Saved to ~/Pictures/$(date +%Hh_%Mm_%Ss_%d_%B_%Y).png"
bind=,XF86AudioLowerVolume,exec,${pkgs.pamixer}/bin/pamixer -d 10
bind=,XF86AudioRaiseVolume,exec,${pkgs.pamixer}/bin/pamixer -i 10
bind=,XF86AudioMute,exec,${pkgs.pamixer}/bin/pamixer -t
bind=,XF86AudioMicMute,exec,${pkgs.pamixer}/bin/pamixer --default-source -t
bind=,XF86MonBrightnessDown,exec,${pkgs.light}/bin/light -U 10
bind=,XF86MonBrightnessUP,exec,${pkgs.light}/bin/light -A 10
general {
gaps_in = 5
gaps_out = 5
border_size=1
no_border_on_floating = true
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
col.inactive_border = rgba(595959aa)
layout = dwindle
}
decoration {
rounding = 8
multisample_edges = true
active_opacity = 1.0
inactive_opacity = 1.0
blur = true
blur_size = 3
blur_passes = 3
blur_new_optimizations = true
drop_shadow = false
# drop_shadow = true
# shadow_ignore_window = true
# shadow_offset = 2 2
# shadow_range = 4
# shadow_render_power = 2
# col.shadow = 0x66000000
blurls = gtk-layer-shell
# blurls = waybar
blurls = lockscreen
}
animations {
enabled = true
# enabled = true
# bezier = overshot, 0.05, 0.9, 0.1, 1.05
# bezier = smoothOut, 0.36, 0, 0.66, -0.56
# bezier = smoothIn, 0.25, 1, 0.5, 1
# animation = windows, 1, 5, overshot, slide
# animation = windowsOut, 1, 4, smoothOut, slide
# animation = windowsMove, 1, 4, default
# animation = border, 1, 10, default
# animation = fade, 1, 10, smoothIn
# animation = fadeDim, 1, 10, smoothIn
# animation = workspaces, 1, 6, default
}
dwindle {
no_gaps_when_only = false
pseudotile = true # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # you probably want this
}
windowrule = float, file_progress
windowrule = float, confirm
windowrule = float, dialog
windowrule = float, download
windowrule = float, notification
windowrule = float, error
windowrule = float, splash
windowrule = float, confirmreset
windowrule = float, title:Open File
windowrule = float, title:branchdialog
windowrule = float, Lxappearance
windowrule = float, Rofi
windowrule = animation none,Rofi
windowrule = float, viewnior
windowrule = float, Viewnior
windowrule = float, feh
windowrule = float, pavucontrol-qt
windowrule = float, pavucontrol
windowrule = float, file-roller
windowrule = fullscreen, wlogout
windowrule = float, title:wlogout
windowrule = fullscreen, title:wlogout
windowrule = idleinhibit focus, mpv
windowrule = idleinhibit fullscreen, firefox
windowrule = float, title:^(Media viewer)$
windowrule = float, title:^(Volume Control)$
windowrule = float, title:^(Picture-in-Picture)$
windowrule = size 800 600, title:^(Volume Control)$
windowrule = move 75 44%, title:^(Volume Control)$
bind = SUPER SHIFT, O, exec, ${pkgs.swaylock}/bin/swaylock
bind = SUPER, Return, exec, ${pkgs.alacritty}/bin/alacritty
bind = SUPER, E, exec, thunar
bind = SUPER, D, exec, ${pkgs.rofi}/bin/rofi -show drun -theme ~/.config/rofi/global/rofi.rasi
#bind = SUPER, D, exec, "killall rofi; and ${pkgs.rofi}/bin/rofi -show drun"
bind = SUPER, escape, exec, wlogout --protocol layer-shell -b 5 -T 400 -B 400
bind = SUPER, Slash, exec, dunstctl close
bind = SUPER, Period, exec, dunstctl action
bind = SUPER, Grave, exec, dunstctl history-pop
bind = SUPER, Q, killactive,
#bind = SUPER, E, exec, ${pkgs.pcmanfm}/bin/pcmanfm
bind = SUPER, T, exec, ${pkgs.emacs}/bin/emacsclient -c
bind = SUPER SHIFT, E, exit
bind = SUPER SHIFT, Q, killactive
bind = SUPER, F, fullscreen,
bind = SUPER, Space, togglefloating,
bind = SUPER, P, pseudo, # dwindle
bind = SUPER, S, togglesplit, # dwindle
bind = SUPER, TAB, workspace, previous
bind = SUPER SHIFT, Comma, movecurrentworkspacetomonitor, -1
bind = SUPER SHIFT, Period, movecurrentworkspacetomonitor, +1
bind = SUPER, left, movefocus, l
bind = SUPER, right, movefocus, r
bind = SUPER, up, movefocus, u
bind = SUPER, down, movefocus, d
bind = SUPER, J, movefocus, l
bind = SUPER, semicolon, movefocus, r
bind = SUPER, L, movefocus, u
bind = SUPER, K, movefocus, d
bind = SUPER SHIFT, left, movewindow, l
bind = SUPER SHIFT, right, movewindow, r
bind = SUPER SHIFT, up, movewindow, u
bind = SUPER SHIFT, down, movewindow, d
bind = SUPER SHIFT, H, movewindow, l
bind = SUPER SHIFT, L, movewindow, r
bind = SUPER SHIFT, K, movewindow, u
bind = SUPER SHIFT, J, movewindow, d
bind = SUPER CTRL, left, resizeactive, -20 0
bind = SUPER CTRL, right, resizeactive, 20 0
bind = SUPER CTRL, up, resizeactive, 0 -20
bind = SUPER CTRL, down, resizeactive, 0 20
bind= SUPER, w, togglegroup
bind= SUPER, z, changegroupactive
bind = SUPER, c, togglespecialworkspace
bind = SUPERSHIFT, c, movetoworkspace, special
bind = SUPER, 1, workspace, 1
bind = SUPER, 2, workspace, 2
bind = SUPER, 3, workspace, 3
bind = SUPER, 4, workspace, 4
bind = SUPER, 5, workspace, 5
bind = SUPER, 6, workspace, 6
bind = SUPER, 7, workspace, 7
bind = SUPER, 8, workspace, 8
bind = SUPER, 9, workspace, 9
bind = SUPER, 0, workspace, 10
bind = SUPER ALT, up, workspace, e+1
bind = SUPER ALT, down, workspace, e-1
bind = SUPER SHIFT, 1, movetoworkspace, 1
bind = SUPER SHIFT, 2, movetoworkspace, 2
bind = SUPER SHIFT, 3, movetoworkspace, 3
bind = SUPER SHIFT, 4, movetoworkspace, 4
bind = SUPER SHIFT, 5, movetoworkspace, 5
bind = SUPER SHIFT, 6, movetoworkspace, 6
bind = SUPER SHIFT, 7, movetoworkspace, 7
bind = SUPER SHIFT, 8, movetoworkspace, 8
bind = SUPER SHIFT, 9, movetoworkspace, 9
bind = SUPER SHIFT, 0, movetoworkspace, 10
bindm = SUPER, mouse:272, movewindow
bindm = SUPER, mouse:273, resizewindow
bind = SUPER, mouse_down, workspace, e+1
bind = SUPER, mouse_up, workspace, e-1
'';
in
{
xdg.configFile."hypr/hyprland.conf".text = hyprlandConf;
programs.swaylock.settings = {
ignore-empty-password = true;
show-failed-attempts = true;
indicator-caps-lock = true;
image = "$HOME/.config/wall";
scaling = "fill";
font = "Iosevka Nerd Font";
font-size = 45;
indicator-radius = 170;
indicator-thicknes = 15;
bs-hl-color = "94E2D5";
key-hl-color = "94E2D5";
caps-lock-bs-hl-color = "94E2D5";
caps-lock-key-hl-color = "94E2D5";
inside-color = "1E1E2E";
inside-clear-color = "1E1E2E";
inside-caps-lock-color = "1E1E2E";
inside-ver-color = "1E1E2E";
inside-wrong-color = "1E1E2E";
line-color = "00000000";
line-clear-color = "00000000";
line-caps-lock-color = "00000000";
line-ver-color = "00000000";
line-wrong-color = "00000000";
ring-color = "FAB387";
ring-clear-color = "F9E2AF";
ring-caps-lock-color = "FAB387";
ring-ver-color = "A6E3A1";
ring-wrong-color = "F38BA8";
separator-color = "00000000";
text-color = "94E2D5";
text-clear-color = "94E2D5";
text-ver-color = "94E2D5";
text-wrong-color = "94E2D5";
text-caps-lock-color = "94E2D5";
};
services.swayidle = {
enable = true;
events = [
{ event = "before-sleep"; command = "${pkgs.swaylock}/bin/swaylock -f"; }
{ event = "lock"; command = "lock"; }
];
timeouts = [
{ timeout = 300; command = "${pkgs.swaylock}/bin/swaylock -f";}
{ timeout = 480; command = "systemctl suspend"; }
];
systemdTarget = "xdg-desktop-portal-hyprland.service";
};
}
Hyprland crash logo
--------------------------------------------
Hyprland Crash Report
--------------------------------------------
I don't feel so good...
Hyprland received signal 6 (Aborted)
System info:
System name: Linux
Node name: personal
Release: 6.2.6
Version: #1-NixOS SMP PREEMPT_DYNAMIC Mon Mar 13 09:26:43 UTC 2023
GPU:
04:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Lucienne [1002:164c] (rev c1) (prog-if 00 [VGA controller])
os-release:
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="23.05.20230315.ac718d0"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 23.05 (Stoat)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="23.05 (Stoat)"
VERSION_CODENAME=stoat
VERSION_ID="23.05"
Backtrace:
#0 | Hyprland() [0x49a69d]
#1 | Hyprland() [0x515e6f]
#2 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x3dbf0) [0x7f561903dbf0]
#3 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x8abc7) [0x7f561908abc7]
#4 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(raise+0x16) [0x7f561903db46]
#5 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(abort+0xd7) [0x7f56190284b5]
#6 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x283d9) [0x7f56190283d9]
#7 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x367b6) [0x7f56190367b6]
#8 | /nix/store/wflz2jwax6pirbr0gf25i4cwmcm9z4j7-wlroots-hyprland-hidpi-2023-03-02_5ae17de/lib/libwlroots.so.12(+0x6b2f3) [0x7f5619c9d2f3]
#9 | /nix/store/wflz2jwax6pirbr0gf25i4cwmcm9z4j7-wlroots-hyprland-hidpi-2023-03-02_5ae17de/lib/libwlroots.so.12(wlr_output_damage_attach_render+0x3d) [0x7f5619cbdbad]
#10 | Hyprland() [0x514391]
#11 | Hyprland() [0x4b7c7b]
#12 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_signal_emit_mutable+0x7c) [0x7f5619d508fc]
#13 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_event_loop_dispatch_idle+0x1b) [0x7f5619d526fb]
#14 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_event_loop_dispatch+0xfa) [0x7f5619d5281a]
#15 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_display_run+0x25) [0x7f5619d50335]
#16 | Hyprland() [0x42e26c]
#17 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x2924e) [0x7f561902924e]
#18 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(__libc_start_main+0x89) [0x7f5619029309]
#19 | Hyprland() [0x444375]
Log tail:
[LOG] Framebuffer created, status 36053
[LOG] LayerSurface 3290d60 destroyed
[LOG] Callback 328cc78 -> 328cc70, layerSurface removed.
[LOG] Callback 328cb40 -> 328cb38, layerSurface removed.
[LOG] Callback 328cba8 -> 328cba0, layerSurface removed.
[LOG] Callback 328cc10 -> 328cc08, layerSurface removed.
[LOG] Callback 328cce0 -> 328ccd8, layerSurface removed.
[LOG] LayerSurface 32b3c40 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor eDP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] LayerSurface 3047be0 unmapped
[LOG] Framebuffer created, status 36053
[LOG] LayerSurface 3047be0 destroyed
[LOG] Callback 32b3e38 -> 32b3e30, layerSurface removed.
[LOG] Callback 32b3d00 -> 32b3cf8, layerSurface removed.
[LOG] Callback 32b3d68 -> 32b3d60, layerSurface removed.
[LOG] Callback 32b3dd0 -> 32b3dc8, layerSurface removed.
[LOG] Callback 32b3ea0 -> 32b3e98, layerSurface removed.
[LOG] Monitor eDP-1 layers arranged: reserved: 0.000000 0.000000 0.000000 0.000000
[LOG] Removed monitor eDP-1!
[LOG] [hookSystem] New hook event registered: monitorRemoved
[LOG] moveWorkspaceToMonitor: Moving 1 to monitor 1
[LOG] moveWorkspaceToMonitor: Plugging gap with new 4
[LOG] moveWorkspaceToMonitor: Plugging gap with existing 4
[LOG] Changed to workspace 1
[LOG] [hookSystem] New hook event registered: workspace
[LOG] Changed to workspace 4
[LOG] moveWorkspaceToMonitor: SWITCHINGISACTIVE, active 2 -> 1
[LOG] [hookSystem] New hook event registered: moveWorkspace
[LOG] Destroying workspace ID 4
[LOG] [hookSystem] New hook event registered: destroyWorkspace
[LOG] Applying monitor rule for HDMI-A-1
[LOG] Monitor HDMI-A-1: requested [email protected], found available mode: 3840x2160@60000mHz, applying.
[LOG] Monitor HDMI-A-1 -> destroyed all render data
[LOG] LayerSurface 32ae180 arranged: x: 1920 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 32890e0 arranged: x: 1920 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor HDMI-A-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Monitor HDMI-A-1 data dump: res [email protected], scale 2.00, transform 0, pos 1920x0, 10b 0
[LOG] LayerSurface 32ae180 arranged: x: 1920 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 32890e0 arranged: x: 1920 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor HDMI-A-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Applying monitor rule for DP-1
[LOG] Monitor DP-1: requested [email protected], found available mode: 3840x2160@59997mHz, applying.
[LOG] Monitor DP-1 -> destroyed all render data
[LOG] LayerSurface 2d895b0 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 328e570 arranged: x: 0 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor DP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Monitor DP-1 data dump: res [email protected], scale 2.00, transform 0, pos 0x0, 10b 0
[LOG] LayerSurface 2d895b0 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 328e570 arranged: x: 0 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor DP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
Kanshi config
profile home {
output eDP-1 enable mode 1920x1200 position 0,0 scale 1
}
profile home {
output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2
output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2
output eDP-1 disable
}
hyprctl monitors output
~> hyprctl monitors
Monitor eDP-1 (ID 0):
[email protected] at 0x0
description: LG Display 0x0683 (eDP-1)
make: LG Display
model: 0x0683
serial:
active workspace: 3 (3)
reserved: 0 41 0 0
scale: 1.00
transform: 0
focused: no
dpmsStatus: 1
vrr: 0
Monitor HDMI-A-1 (ID 1):
[email protected] at 1920x0
description: Dell Inc. DELL S2722QC C77WLD3 (HDMI-A-1)
make: Dell Inc.
model: DELL S2722QC
serial: C77WLD3
active workspace: 2 (2)
reserved: 0 41 0 0
scale: 1.50
transform: 0
focused: yes
dpmsStatus: 1
vrr: 0
Monitor DP-1 (ID 2):
[email protected] at 5760x0
description: Dell Inc. DELL S2722QC FL7WLD3 (DP-1)
make: Dell Inc.
model: DELL S2722QC
serial: FL7WLD3
active workspace: 4 (4)
reserved: 0 41 0 0
scale: 1.50
transform: 0
focused: no
dpmsStatus: 1
vrr: 0
I don't understand, do you use kanshi through Home Manager or manually write its config file? The one you sent (code block 3) does not correspond to something that would be generated by Home Manager using the code provided in (code block 1). Also, it seems to have a typo in the second monitor's config.
I don't understand, do you use kanshi through Home Manager or manually write its config file? The one you sent (code block 3) does not correspond to something that would be generated by Home Manager using the code provided in (code block 1). Also, it seems to have a typo in the second monitor's config.
If you're referring to the name of the profiles, it was just me testing out stuff with two laptops. So they're the same, let me edit it to avoid confusion (sorry in the first place, didn't notice it).
Also, it seems to have a typo in the second monitor's config.
Hmm where ? Either ways I was trying out things to make it work. The weird part is that hyprland shouldn't crash right?
profile home {
output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2
> output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2
output eDP-1 disable
}
Refresh rate and positon are not space separated here, not sure if kanshi can still parse it.
Anyway, I've used kanshi with Hyprland in the past with no issues, so no, it shouldn't crash. I'll test again tomorrow if I have time and report back.
profile home { output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2 > output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2 output eDP-1 disable }
Refresh rate and positon are not space separated here, not sure if kanshi can still parse it.
Yeah this is my bad in copying, like I said I was playing around to make it work. The actual config is generated by HomeManager Knanshi and wouldn't have this issue.
Anyway, I've used kanshi with Hyprland in the past with no issues, so no, it shouldn't crash. I'll test again tomorrow if I have time and report back.
What do you use now? I'm not stuck to kanshi, but it has been the best way to switch from dock to standalone mode for my laptop! But anyways thanks for your time and sorry for the confusion.
I don't use external monitors much nowadays so I ditched it and just use anyrun's randr
mode which lets me position/mirror monitors in Hyprland.
I don't use external monitors much nowadays so I ditched it and just use anyrun's
randr
mode which lets me position/mirror monitors in Hyprland.
Neat, but I think this wouldn't work for me much, I keep switching between the two modes and Kanshi works great for me. Happy to help with more logs or such if needed! Until which, I'll have to disable Kanshi :D
Ok I've re-enabled kanshi, seems to work. What doesn't seem to work in your case is disabling the internal screen. I will try that now.
With this config, it all seems to work fine up until disconnecting all remaining active monitors.
services.kanshi = {
enable = true;
profiles = {
undocked = {
outputs = [
{
criteria = "eDP-1";
position = "0,0";
}
];
};
docked-all = {
outputs = [
{
criteria = "eDP-1";
position = "1366,0";
}
{
criteria = "DP-1";
position = "0,0";
}
{
criteria = "DP-2";
position = "1600,0";
}
];
};
docked1 = {
outputs = [
{
criteria = "eDP-1";
status = "disable";
}
{
criteria = "DP-1";
position = "0,0";
}
];
};
docked2 = {
outputs = [
{
criteria = "eDP-1";
status = "disable";
}
{
criteria = "DP-2";
position = "0,0";
}
];
};
};
systemdTarget = "graphical-session.target";
};
Tested the docked2
profile. After unplugging the external screen, kanshi didn't re-check the active profile and left the internal screen disabled, so Hyprland crashed with no active output.
I have a similar issue when using binds to enable/disable my laptop's internal display on open/close respectively. Display correctly turns off and on, but if I disconnect the external monitor while the laptop lid is still closed, Hyprland crashes and I get thrown back to the tty. Kanshi seems to be the proper way to do this, but it's unfortunate that it faces a similar issue.
This seems likely to be the same issue as the one experienced when using Kanshi.
Here's how I have my scripts configured in NixOS:
let
# when lid closed, if at least one external display connected, disable internal display
closeLid = pkgs.writeShellScriptBin "closeLid" ''
if [ $(hyprctl monitors | wc -l) -gt 15 ] && [ ! -z "$(hyprctl monitors | grep eDP-1)" ]; then
hyprctl keyword monitor "eDP-1, disable"
fi
'';
# when lid opened, if internal display disabled, re-enable display and reload Hyprland
openLid = pkgs.writeShellScriptBin "openLid" ''
if [ -z "$(hyprctl monitors | grep eDP-1)" ]; then
hyprctl keyword monitor "eDP-1, preferred, auto, 1"
systemctl --user restart waybar
hyprctl reload
fi
'';
in {
wayland.windowManager.hyprland = {
...
extraConfig = ''
...
bindl=,switch:on:Lid Switch,exec,${closeLid}/bin/closeLid
bindl=,switch:off:Lid Switch,exec,${openLid}/bin/openLid
'';
};
}
I think the problem could easily be solved by Hyprland. It would only have to enable any remaining monitor when all the others are gone. Should only crash when there are no displays left (not disabled).
Weirdly, I had other issues with NixOS and moved to Arch for the time-being and now Hyprland and Kanshi work without any issues.
From my side, I won't be able to test it anymore with NixOS and might come back to this when I have more time to setup NixOS, the issue can be closed, unless someone else has the same issue.
Weirdly, I had other issues with NixOS and moved to Arch for the time-being and now Hyprland and Kanshi work without any issues.
It's surprising to me that on arch you don't experience these issues. This suggests that it is NixOS specific...
It's probably not home-manager as I am only installing kanshi through home-manager, but the configuration is done through a non-generated kanshi config file.
home.packages = [ pkgs.kanshi ]
The config file looks like this
~/.config/kanshi
profile {
output eDP-1 enable
}
profile {
output eDP-1 disable
output "Samsung Electric Company U28H75x HTPJ700579" enable scale 1.5
}
When disconnecting the external monitor, the internal monitor doesn't turn on again and after interacting with hyprland (switching workspaces) hyprland crashes.
Interesting, but I have no clue how to debug this.
When disconnecting the external monitor, the internal monitor doesn't turn on again and after interacting with hyprland (switching workspaces) hyprland crashes.
Can confirm. There is a log of kanshi, probably can clarify smth
Jul 25 19:27:42 thinkpad-x1-gen9 systemd[4311]: Started Dynamic output configuration.
-------- INITIAL CONFIGURATION, NOTHING CONNECTED TO LAPTOP ----------
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: applying profile 'laptopOnly'
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'laptopOnly' applied
-------- PLUG IN EXTERNAL MONITOR ----------
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile 'withDellDisplay'
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'Dell Inc. DELL U2723QE JSJ91P3' on connected head 'DP-3'
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'withDellDisplay' cancelled, retrying
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile 'withDellDisplay'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'Dell Inc. DELL U2723QE JSJ91P3' on connected head 'DP-3'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'withDellDisplay' applied
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: no profile matched
-------- DISCONNECT MONITOR ----------
Jul 25 21:09:49 thinkpad-x1-gen9 kanshi[4501]: no profile matched
Jul 25 21:09:58 thinkpad-x1-gen9 kanshi[4501]: no profile matched
Moreover, when I run kanshi after e-DP is turned off it prints: no profile matched
seems like hyprland not report that output if it already disabled. I guess hyprland not reports turned off outputs and therefore kanshi can't detect e-DP output after external monitor disconnect
❯ hyprctl monitors
Monitor DP-3 (ID 1):
[email protected] at 0x0
description: Dell Inc. DELL U2723QE JSJ91P3 (DP-3)
make: Dell Inc.
model: DELL U2723QE
serial: JSJ91P3
active workspace: 3 (3)
special workspace: 0 ()
reserved: 0 34 0 0
scale: 1.00
transform: 0
focused: yes
dpmsStatus: 1
vrr: 0
```
@pltanton Thanks for the insight.
It seems that this is a general problem in how hyprland handles monitors. This has nothing to do with kanshi in particular.
The problem is that when disabling a monitor, there is no way (I know of) to reenable it again, as hyprland doesn't list this monitor anymore.
Look at this
> hyprctl monitors
Monitor eDP-1 (ID 0):
[email protected] at 0x0
description: Samsung Display Corp. 0x4165 (eDP-1)
make: Samsung Display Corp.
model: 0x4165
serial:
active workspace: 1 (1)
special workspace: 0 ()
reserved: 0 0 0 35
scale: 2.00
transform: 0
focused: no
dpmsStatus: 1
vrr: 0
Monitor DP-2 (ID 1):
[email protected] at 3840x0
description: Samsung Electric Company U28H75x HTPJ700579 (DP-2)
make: Samsung Electric Company
model: U28H75x
serial: HTPJ700579
active workspace: 2 (2)
special workspace: 0 ()
reserved: 0 0 0 35
scale: 1.50
transform: 0
focused: yes
dpmsStatus: 1
vrr: 0
> hyprctl keyword monitor "eDP-1,disable"
ok
> hyprctl monitors
Monitor DP-2 (ID 1):
[email protected] at 3840x0
description: Samsung Electric Company U28H75x HTPJ700579 (DP-2)
make: Samsung Electric Company
model: U28H75x
serial: HTPJ700579
active workspace: 2 (2)
special workspace: 0 ()
reserved: 0 0 0 35
scale: 1.50
transform: 0
focused: yes
dpmsStatus: 1
vrr: 0
> hyprctl keyword monitor "eDP-1,enable"
Err: stoi
The only way I know is to run hyprctl reload
This behavior is imho expected on Hyprland: https://wiki.hyprland.org/Configuring/Monitors/#disabling-a-monitor .
To disable output without removing it from Hyprland, one should use DPMS instead. Not sure how to achieve that with kanshi though. You'd probably have to leverage the exec
directive.
@jficz DPMS is not what we want here, because this only turns the screen off, without actually removing the monitor logically. All workspaces stay on the turned off screen.
I'm inclined to disagree that this is how hyprland should behave. It should still be possible to re-enable the monitor and bring it back.
Also kanshi works through the wlr-output-management protocol. Apparently there is a discrepancy how kanshi and hyprland understanding this protocol.
Good point. Didn't realize how DPMS behaves.
I didn't mean to infer how Hyprland should work, I was merely suggesting that the current behavior is expected given Hyprland "specs".
I did a naive test and it seems that kanshi can actually enable a monitor that has been previously disabled but not under all circumstances. My tests (eDP-1 and DP-1 are connected at the beginning, I'm using kanshi as a user systemd service):
This brings a disabled monitor back up as long as proper profile exists in kanshi, works for both monitors (not at the same time):
hyprctl keyword monitor 'DP-1,disable'
systemctl --user restart kanshi
But this doesn't:
hyprctl keyword monitor 'DP-1,disable'
<disconnect DP-1 physically (USB-C dock in my case)>
<connect it back>
The monitor doesn't come back up, even if kanshi is restarted, until hyprctl reload
is executed. That is suboptimal but at least consistently reproducible. According to kanshi logs, the disable
command doesn't register with kanshi and after DP-1 is disabled, the physical disconnect doesn't register with kanshi either. It is only when I reconnect the dock again when kanshi pick it up but even then, it doesn't see DP-1 and just applies the eDP-1-only
profile. After hyprctl reload
is executed, kanshi picks up the correct config on its own.
If the disabled monitor in the latter case is eDP-1, Hyprland crashes*)
I have no solid knowledge how any of kanshi, Hyprland and wlr protocols work so I'm not going to draw any conclusions here, just offering an observation.
This is definitely a bug, Hyprland shouldn't crash. It should, at least, shut down gracefully but somehow I feel that if the discrepancy between the two above described cases is understood, the fix could possibly be inferred, though it could be in kanshi and not Hyprland. Or both.
edit: *) eDP-1 screen is just off after disconnect but nothing happens until I actually reconnect DP-1 back. It is only then when Hyprland crashes. Same if I use similar kanshi profile as OP (that is, eDP-1 off when other screens exist).
It should still be possible to re-enable the monitor and bring it back.
It's possible with wlr-randr
at least.
It should still be possible to re-enable the monitor and bring it back.
It's possible with
wlr-randr
at least.
with the same limitations as kanshi has, as I described above
Just tested it, wlr-randr doesn't see the output if disabled, disconnected and then reconnected again, exactly the same as kanshi.
@LU15W1R7H
I'm inclined to disagree that this is how hyprland should behave. It should still be possible to re-enable the monitor and bring it back.
This comment posted in another issue might be relevant to this: https://github.com/hyprwm/Hyprland/issues/1274#issuecomment-1573388218
Seems like "out of spec" behaviour
After going through other discussions I need to revisit my previous opinion. I still think that this is "on spec" behavior for Hyprland (because it is documented as such) but is indeed "out of spec" relative to wlr protocols and the fix imho needs to be introduced on Hyprland side.
However, it's off-topic for this specific issue as this issue, unrelated to Kanshi, requires a different kind of fix - the fallback kind of fix. Imo something like this: if no more outputs are enabled, try to enable any output available regardless of their state and only fail [not crash] when there is no more outputs that can be enabled. Or possibly do not even fail, just log the situation to the console so the user can solve the issue by connecting a new monitor for example. Or, if a no-crash-fail path is taken, don't even try to enable available displays, just log the issue and wait, because that may in fact be what the user intended by their configuration. Not sure though if this situation is supported by wlr. Is it possible to lose all heads and still have active session in Wayland?
On the other hand, if #1274 is fixed "properly", this issue may no longer be too relevant so long as Kanshi has enough time to enable the previously disabled display before Hyprland crashes due to lack of displays.
i'm still having the same issue, any way of "fixing it"?
- using hyprctrl: disabling the monitor and re-enabling works
- using kanshi: disabling the monitor works, but re-enabling doesn't works as expected.
My findings:
the output wlr-randr
of kanshi vs hyprctrl when disabling the monitor are different
// hyprctl keyword monitor "eDP-1,disable"
eDP-1 ....
Enabled: no
when using kanshi the enable attribute is set to yes
@vaxerski @fufexan any idea why this behaviour? shouldn't both be using wlr-output-management
?
EDIT: with kanshi 1.5.0 it works and it doesn't crash.
THO to time to time my laptop display doesn't re-enable itself but it doesn't crash, in fact connecting the hdmi back again i still have my hyprland session up.
@alexandru0-dev weird. I am on Kanshi 1.5.1, but the issue persists. It doesn't seem like it is a Kanshi bug, but I might be wrong
@AlexNabokikh try building hyprland from the last master as at some point it was introduced a regression which broke this again and then got it fixed recently
U can check: https://github.com/hyprwm/Hyprland/issues/4725 https://github.com/hyprwm/Hyprland/issues/4728
@AlexNabokikh if u are using nixos (I seen your config in your repos) use the hyprland flake, it's highly recommended (u can follow the wiki)
This will also allow you to build from master or a pinned tag/commit
@alexandru0-dev Thank you! I can confirm that the issue is not present when building from the latest commit on the master branch.
Just to add a datapoint: on Fedora 39 and Hyprland v0.35.0 starting Kanshi would crash Hyprland. After uprgrading to Hyprland 81fe2ae Kanshi works.