JakeStanger / ironbar

Customisable Wayland gtk bar written in Rust.
https://crates.io/crates/ironbar
MIT License
645 stars 57 forks source link

[Hyprland] wrong popup positioning with fractional scaling #657

Closed ralencode closed 3 months ago

ralencode commented 4 months ago

Describe the bug

A clear and concise description of what the bug is. popups position themself wrong when fractional scaling is used To Reproduce Steps to reproduce the behavior:

  1. latest hyprland-git and ironbar-git on archlinux
  2. use my configs
  3. click on any widget having popup, fe time
  4. popup positions itself wrong

Expected behavior

A clear and concise description of what you expected to happen. popup positions itself right under the widget System information:

  • Distro: Arch Linux
  • Compositor: Hyprland
  • Ironbar version: ironbar 0.16.0-pre (ironbar-git)

Configuration

Share your bar configuration and stylesheet as applicable:

Config ```json { "$schema": "https://f.jstanger.dev/github/ironbar/schema.json", "anchor_to_edges": true, "position": "top", "height": 16, "popup_gap": 0, "icon_theme": "Fluent-teal-dark", "start": [ { "type": "workspaces", "all_monitors": false, "name_map": { "special:magic": "S" } }, { "type": "launcher", "favorites": [ "thunar", "firefox", "mgba", "PPSSPPSDL", "lutris" ], "show_names": false, "show_icons": true } ], "center": [ { "type": "clock" } ], "end": [ { "type": "volume", "format": "{icon} {percentage}%", "max_volume": 100, "on_click_right": "amixer -D pipewire sset Master toggle", "on_scroll_up": "amixer -D pipewire sset Master playback 5%-", "on_scroll_down": "amixer -D pipewire sset Master playback 5%+", "icons": { "volume_high": "󰕾", "volume_medium": "󰖀", "volume_low": "󰕿", "muted": "󰝟" } }, { "type": "clipboard", "max_items": 3, "on_click_right": "kitty", "truncate": { "mode": "end", "length": 50 } }, { "type": "custom", "class": "power-menu", "bar": [ { "type": "button", "name": "power-btn", "label": "", "on_click": "popup:toggle" } ], "popup": [ { "type": "box", "orientation": "vertical", "widgets": [ { "type": "label", "name": "header", "label": "Power menu" }, { "type": "box", "widgets": [ { "type": "button", "class": "power-btn", "label": "", "on_click": "!shutdown now" }, { "type": "button", "class": "power-btn", "label": "", "on_click": "!reboot" } ] }, { "type": "label", "name": "uptime", "label": "Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}" } ] } ], "tooltip": "Up: {{30000:uptime -p | cut -d ' ' -f2-}}" }, { "type": "upower", "format": "{percentage}%" }, { "type": "notifications", "show_count": true, "icons": { "closed_none": "󰍥", "closed_some": "󱥂", "closed_dnd": "󱅯", "open_none": "󰍡", "open_some": "󱥁", "open_dnd": "󱅮" } } ] } ```
Styles ```css @define-color color_bg rgba(0, 0, 0, 1); @define-color color_bg_dark rgba(64, 0, 128, 1); @define-color color_shadow_active rgba(128, 0, 255, 1); @define-color color_border rgba(0, 0, 255, 1); @define-color color_border_active rgba(0, 128, 255, 1); @define-color color_text rgba(200, 185, 255, 1); @define-color color_urgent rgba(255, 0, 128, 1); @define-color color_transparent rgba(0, 0, 0, 0); /* -- base styles -- */ * { font-family: JetBrains Mono Nerd Font; font-size: 16px; border: none; border-radius: 0; } box, menubar, button, .background { background-color: @color_bg; background-image: none; box-shadow: none; } box { background-color: @color_transparent; } button, label { color: @color_text; } button:hover, label:hover { box-shadow: inset 0 2px @color_shadow_active; } .upower:hover .contents { background-color: @color_transparent; } scale trough { min-width: 1px; min-height: 2px; } #bar { border-bottom: 1px solid @color_border; } .popup { border: 1px solid @color_border; padding: 1em; } /* -- clipboard -- */ .clipboard { margin-left: 5px; font-size: 1.1em; } .popup-clipboard .item { padding-bottom: 0.3em; border-bottom: 1px solid @color_border; } /* -- clock -- */ .clock { font-weight: bold; margin-left: 5px; } .popup-clock .calendar-clock { color: @color_text; font-size: 2.5em; padding-bottom: 0.1em; } .popup-clock .calendar { background-color: @color_bg; color: @color_text; } .popup-clock .calendar .header { padding-top: 1em; border-top: 1px solid @color_border; font-size: 1.5em; } .popup-clock .calendar:selected { background-color: @color_border_active; } /* -- launcher -- */ .launcher .item { margin-right: 4px; } .launcher .ifix examtem:not(.focused):hover { background-color: @color_bg_dark; } .launcher .open { border-top: 1px solid @color_border; } .launcher .focused { border-top: 2px solid @color_border_active; } .launcher .urgent { border-top-color: @color_urgent; } .popup-launcher { padding: 0; } .popup-launcher .popup-item:not(:first-child) { border-top: 1px solid @color_border; } /* -- music -- */ .music:hover * { background-color: @color_bg_dark; } .popup-music .album-art { margin-right: 1em; } .popup-music .icon-box { margin-right: 0.4em; } .popup-music .title .icon, .popup-music .title .label { font-size: 1.7em; } .popup-music .controls *:disabled { color: @color_border; } .popup-music .volume .slider slider { border-radius: 100%; } .popup-music .volume .icon { margin-left: 4px; } .popup-music .progress .slider slider { border-radius: 100%; } /* notifications */ .notifications .count { font-size: 0.6rem; background-color: @color_text; color: @color_bg; border-radius: 100%; margin-right: 3px; margin-top: 3px; padding-left: 4px; padding-right: 4px; opacity: 0.7; } /* -- script -- */ .script { padding-left: 10px; } /* -- sys_info -- */ .sysinfo { margin-left: 10px; } .sysinfo .item { margin-left: 5px; } /* -- tray -- */ .tray { margin-left: 10px; } /* -- volume -- */ .popup-volume .device-box { border-right: 1px solid @color_border; } /* -- workspaces -- */ .workspaces .item.focused { border-top: 1px solid @color_border; } /* -- custom: power menu -- */ .popup-power-menu #header { font-size: 1.4em; padding-bottom: 0.4em; margin-bottom: 0.6em; border-bottom: 1px solid @color_border; } .popup-power-menu .power-btn { border: 1px solid @color_border; padding: 0.6em 1em; } .popup-power-menu #buttons > *:nth-child(1) .power-btn { margin-right: 1em; } ```
Hyprland config ```hyprlang # See https://wiki.hyprland.org/Configuring/Monitors/ # monitor=,2880x1620@120,auto,auto monitor=,2880x1620,auto,1.5 #,vrr,0,bitdepth,10 monitor=HDMI-A-1,3840x2160@60.00Hz,auto-up,2.0,bitdepth,10 monitor=WL-1,1920x1080,auto,1.0 # See https://wiki.hyprland.org/Configuring/Keywords/ for more # Execute your favorite apps at launch # exec-once = waybar & hyprpaper & firefox exec-once = ~/.config/hypr/xdg-portal-hyprland.sh env = XCURSOR_THEME,GoogleDot-Black env = XCURSOR_SIZE,24 env = HYPRCURSOR_THEME,GoogleDot-Violet env = HYPRCURSOR_SIZE,24 env = SDL_VIDEODRIVER,wayland env = PATH,/home/ralen/.cargo/bin:$PATH exec-once = gsettings set org.gnome.desktop.interface cursor-theme 'GoogleDot-Black' exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 exec-once = wl-paste exec-once = wl-copy exec-once = hyprpm reload -n exec-once = while :; do swaybg -i /home/ralen/Pictures/Wallpapers/spring2024/spring$(shuf -i 1-11 -n1).png & (sleep $(shuf -i 60-300 -n1) && killall swaybg); done exec-once = ironbar exec-once = swaync exec-once = nm-applet exec-once = blueman-applet # Source a file (multi-file configs) # source = ~/.config/hypr/myColors.conf # Set programs that you use $terminal = kitty $fileManager = thunar $menu = fuzzel # $menu = pgrep -x "ags" > /dev/null && ags -t launcher # Some default env vars. env = XCURSOR_SIZE,24 env = QT_QPA_PLATFORMTHEME,qt6ct # change to qt6ct if you have that # env = QT_STYLE_OVERRIDE,qt6ct env = PATH,/home/ralen/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl # For all categories, see https://wiki.hyprland.org/Configuring/Variables/ input { kb_layout = lar_dv,cyr_dv kb_variant = kb_model = kb_options = terminate:ctrl_alt_bksp,grp:alt_shift_toggle,lv3:ralt_switch,caps:escape kb_rules = follow_mouse = 1 touchpad { natural_scroll = yes } sensitivity = 0 # -1.0 - 1.0, 0 means no modification. } general { # See https://wiki.hyprland.org/Configuring/Variables/ for more gaps_in = 5 gaps_out = 10 gaps_workspaces = 50 border_size = 2 col.active_border = rgba(33ccffee) rgba(9900ffee) 45deg col.inactive_border = rgba(595959aa) layout = dwindle # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on allow_tearing = false } xwayland { force_zero_scaling = true } decoration { # See https://wiki.hyprland.org/Configuring/Variables/ for more rounding = 10 blur { enabled = true size = 3 passes = 1 } drop_shadow = yes shadow_range = 12 shadow_render_power = 3 col.shadow = rgba(1a1a1aee) # screen_shader = $HOME/git/.files/.config/hypr/shaders/crt-mod.frag } animations { enabled = yes # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more bezier = myBezier, 0.05, 0.9, 0.1, 1.05 bezier = linear, 0.0, 0.0, 1.0, 1.0 animation = windows, 1, 7, myBezier animation = windowsOut, 1, 7, default, popin 80% animation = border, 1, 10, default animation = borderangle, 1, 40, linear, loop animation = fade, 1, 7, default animation = workspaces, 1, 6, default } dwindle { # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below preserve_split = yes # you probably want this } master { # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more new_status = master } gestures { # See https://wiki.hyprland.org/Configuring/Variables/ for more workspace_swipe = on workspace_swipe_forever = on } misc { # See https://wiki.hyprland.org/Configuring/Variables/ for more force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers } # Example windowrule v1 windowrule = float, ^(thunar)$ windowrule = float, ^(Matplotlib)$ windowrule = float, ^(python3)$ # Example windowrule v2 windowrulev2 = float,class:^(kitty)$,title:^(nvim)$ # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more layerrule = blur, gtk-layer-shell layerrule = ignorezero, gtk-layer-shell # See https://wiki.hyprland.org/Configuring/Keywords/ for more $mainMod = SUPER # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more bind = $mainMod, F, exec, xdg-open https:// bind = $mainMod, T, exec, telegram-desktop bind = $mainMod, RETURN, exec, $terminal bind = $mainMod, Q, killactive, bind = $mainMod, C, exec, mate-calc bind = $mainMod, M, exit, bind = $mainMod, L, exec, hyprlock || zsh, bind = $mainMod, E, exec, $fileManager bind = $mainMod Shift, R, exec, ironbar reload bind = $mainMod, V, togglefloating, bind = $mainMod, R, exec, $menu bind = $mainMod, P, pseudo, # dwindle bind = $mainMod, J, togglesplit, # dwindle bind = , Print, exec, grim -g "$(slurp)" - | swappy -f - # take a screenshot bind = $mainMod, F11, fullscreen # Volume & brightness binde = ,XF86AudioMute, exec, amixer sset Master toggle binde = ,XF86AudioLowerVolume, exec, amixer -D pipewire sset Master playback 5%- binde = ,XF86AudioRaiseVolume, exec, amixer -D pipewire sset Master playback 5%+ binde = ,XF86MonBrightnessDown, exec, brightnessctl s 5%- binde = ,XF86MonBrightnessUp, exec, brightnessctl s 5%+ # binde = ,XF86AudioRaiseVolume, exec, amixer -D pipewire sset Master 5%+ # binde = ,XF86AudioLowerVolume, exec, amixer -D pipewire sset Master 5%- # binde = ,XF86MonBrightnessUp, exec, brightnessctl s 1%+ # binde = ,XF86MonBrightnessDown, exec, brightnessctl s 1%- # Move focus with mainMod + arrow keys bind = $mainMod, left, movefocus, l bind = $mainMod, right, movefocus, r bind = $mainMod, up, movefocus, u bind = $mainMod, down, movefocus, d # Swap windows with mainMod + SHIFT + arrow keys bind = $mainMod SHIFT, left, swapwindow, l bind = $mainMod SHIFT, right, swapwindow, r bind = $mainMod SHIFT, up, swapwindow, u bind = $mainMod SHIFT, down, swapwindow, d # Resize windows with mainMod + CTRL + arrow keys binde = $mainMod CTRL, right, resizeactive, 20 0 binde = $mainMod CTRL, left, resizeactive, -20 0 binde = $mainMod CTRL, up, resizeactive, 0 -20 binde = $mainMod CTRL, down, resizeactive, 0 20 # Switch workspaces with mainMod + [0-9] bind = $mainMod, 1, workspace, 1 bind = $mainMod, 2, workspace, 2 bind = $mainMod, 3, workspace, 3 bind = $mainMod, 4, workspace, 4 bind = $mainMod, 5, workspace, 5 bind = $mainMod, 6, workspace, 6 bind = $mainMod, 7, workspace, 7 bind = $mainMod, 8, workspace, 8 bind = $mainMod, 9, workspace, 9 bind = $mainMod, 0, workspace, 10 # Move active window to a workspace with mainMod + SHIFT + [0-9] bind = $mainMod SHIFT, 1, movetoworkspace, 1 bind = $mainMod SHIFT, 2, movetoworkspace, 2 bind = $mainMod SHIFT, 3, movetoworkspace, 3 bind = $mainMod SHIFT, 4, movetoworkspace, 4 bind = $mainMod SHIFT, 5, movetoworkspace, 5 bind = $mainMod SHIFT, 6, movetoworkspace, 6 bind = $mainMod SHIFT, 7, movetoworkspace, 7 bind = $mainMod SHIFT, 8, movetoworkspace, 8 bind = $mainMod SHIFT, 9, movetoworkspace, 9 bind = $mainMod SHIFT, 0, movetoworkspace, 10 # Example special workspace (scratchpad) bind = $mainMod, S, togglespecialworkspace, magic bind = $mainMod SHIFT, S, movetoworkspace, special:magic # Scroll through existing workspaces with mainMod + scroll bind = $mainMod, mouse_down, workspace, e+1 bind = $mainMod, mouse_up, workspace, e-1 # Move/resize windows with mainMod + LMB/RMB and dragging bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:273, resizewindow ```

Additional context

Add any other context about the problem here. if you think this is hyprland issue tell me ill open it there Screenshots If applicable, add screenshots to help explain your problem. wrong positioning image

right positioning image

phisch commented 4 months ago

Same issue happens on niri. It looks like popup positions are based on integer scale, rather than the used fractional scale.

JakeStanger commented 3 months ago

Yep, looks like wl_output and GTK both only report an integer scale. I don't currently take this into account anyway, but this gets rounded up so a 1.25x scale becomes 2x.

I'll need to write a client for the fractional scaling protocol, which shouldn't be too bad.

JakeStanger commented 3 months ago

Definitely didn't just spend two days implementing the fractional scaling protocol only to find I can't use it, and wl_output gives me the number I need anyway.

Fixed in git :)