ironbar icon indicating copy to clipboard operation
ironbar copied to clipboard

[Hyprland] wrong popup positioning with fractional scaling

Open ralencode opened this issue 1 year ago • 1 comments

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
{
  "$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": "<span font-size='40pt'>  </span>",
                  "on_click": "!shutdown now"
                },
                {
                  "type": "button",
                  "class": "power-btn",
                  "label": "<span font-size='40pt'>  </span>",
                  "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
@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
# 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,[email protected],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

ralencode avatar Jul 04 '24 21:07 ralencode

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

phisch avatar Jul 26 '24 08:07 phisch

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 avatar Aug 04 '24 15:08 JakeStanger

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 :)

JakeStanger avatar Aug 09 '24 22:08 JakeStanger