Nimbin[12]?Sway / SwAS / commits / 9f42169

SwAS git · main

SwAS - app switcher for sway (SVG/PNG icons, themeable)

sway wayland c launcher · first commit 2026-08-08 · last commit 2026-09-20 (19 days ago) · synced 3 days ago · upstream: github.com/nimbin2/SwAS

C 97.5% Markdown 1.6%
git clone https://git.christianimmanuel.de/sway/SwAS.gitwget https://git.christianimmanuel.de/sway/SwAS/archive/SwAS.tar.gz

Rename to SwAS And stuff

Christian Immanuel · 2026-08-28 15:33 · 9f421697e6031978d116dcdd0ac321624d6d21b0

 .gitignore                  |   2 +-
 Makefile                    |  24 +++---
 README.md                   |  78 ++++++++++-------
 appwheel-static-old_version | Bin 2803472 -> 0 bytes
 appwheel.config.example     |  66 ---------------
 config.example              |  24 +++---
 sw_theme.h                  |  10 +--
 appwheel.c => swas.c        | 200 ++++++++++++++++++++++++++++----------------
 8 files changed, 208 insertions(+), 196 deletions(-)

diff --git a/.gitignore b/.gitignore
index 25ff09f..d7ab970 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-appwheel
+swas
diff --git a/Makefile b/Makefile
index 1d2cf58..d3d3b3a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
-# appwheel — Makefile
+# swas — Makefile
 #
-#   make            build (SDL3 linked dynamically, via pkg-config)   -> ./appwheel
+#   make            build (SDL3 linked dynamically, via pkg-config)   -> ./swas
 #   make static     build with SDL3 baked in (no libSDL3.so needed at runtime)
 #   make strict     build with -Wall -Wextra (for hacking on it)
 #   make run        build and run
 #   make install    install to $(PREFIX)/bin           (default: ~/.local)
-#   make config     write a default config to ~/.config/appwheel/config
+#   make config     write a default config to ~/.config/swas/config
 #   make clean
 #
 # Requires: a C compiler, pkg-config, and SDL3 dev files.
@@ -23,9 +23,9 @@ CFLAGS      ?= -O2
 PREFIX      ?= $(HOME)/.local
 bindir      ?= $(PREFIX)/bin
 
-BUILD       := $(shell md5sum appwheel.c 2>/dev/null | cut -c1-8)
-SRC         := appwheel.c
-BIN         := appwheel
+BUILD       := $(shell md5sum swas.c 2>/dev/null | cut -c1-8)
+SRC         := swas.c
+BIN         := swas
 
 SDL_CFLAGS  := $(shell $(PKG_CONFIG) --cflags sdl3)
 SDL_LIBS    := $(shell $(PKG_CONFIG) --libs sdl3)
@@ -38,19 +38,19 @@ SDL_STATIC_EXTRA := $(filter-out -lSDL3,$(shell $(PKG_CONFIG) --static --libs sd
 all: $(BIN)
 
 $(BIN): $(SRC) stb_truetype.h stb_image.h sw_theme.h
-	$(CC) $(CFLAGS) -DAPPWHEEL_BUILD='"$(BUILD)"' $(SDL_CFLAGS) $(SRC) -o $(BIN) $(SDL_LIBS) -lm
+	$(CC) $(CFLAGS) -DSWAS_BUILD='"$(BUILD)"' $(SDL_CFLAGS) $(SRC) -o $(BIN) $(SDL_LIBS) -lm
 	@./$(BIN) --version
 
 # Link libSDL3.a statically while keeping system libs dynamic.
 static: $(SRC) stb_truetype.h stb_image.h sw_theme.h
-	$(CC) $(CFLAGS) -DAPPWHEEL_BUILD='"$(BUILD)"' $(SDL_CFLAGS) $(SRC) -o $(BIN) \
+	$(CC) $(CFLAGS) -DSWAS_BUILD='"$(BUILD)"' $(SDL_CFLAGS) $(SRC) -o $(BIN) \
 	  $(SDL_LDPATH) -Wl,-Bstatic -lSDL3 -Wl,-Bdynamic $(SDL_STATIC_EXTRA) -lm
 	@echo "built ./$(BIN) with SDL baked in:"; \
 	 ldd $(BIN) | grep -qi SDL3 && echo "  (warning: still links libSDL3.so)" \
 	   || echo "  no libSDL3.so dependency."
 
 strict: $(SRC) stb_truetype.h stb_image.h sw_theme.h
-	$(CC) -O2 -Wall -Wextra -Wno-misleading-indentation -DAPPWHEEL_BUILD='"$(BUILD)"' \
+	$(CC) -O2 -Wall -Wextra -Wno-misleading-indentation -DSWAS_BUILD='"$(BUILD)"' \
 	  $(SDL_CFLAGS) $(SRC) -o $(BIN) $(SDL_LIBS) -lm
 
 run: all
@@ -62,9 +62,9 @@ install: all
 	@./$(BIN) --version
 
 config: all
-	@mkdir -p $(HOME)/.config/appwheel
-	./$(BIN) --dump-config > $(HOME)/.config/appwheel/config
-	@echo "wrote $(HOME)/.config/appwheel/config"
+	@mkdir -p $(HOME)/.config/swas
+	./$(BIN) --dump-config > $(HOME)/.config/swas/config
+	@echo "wrote $(HOME)/.config/swas/config"
 
 clean:
 	rm -f $(BIN)
diff --git a/README.md b/README.md
index 4275d17..a4f4dc5 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-# appwheel
+# swas
 
-A radial app launcher, drawn with SDL3. Apps sit in wide slots across the top
+Sway App Selector: a radial app launcher, drawn with SDL3. Apps sit in wide slots across the top
 arc; point at one and click, or type to filter. Works on Wayland and X11.
 
-![appwheel](screenshot.png)
+![swas](screenshot.png)
 
 100% vibecode, but tested.
 
@@ -15,7 +15,7 @@ Debian trixie and newer:
 sudo apt install build-essential pkg-config libsdl3-dev
 make
 make install          # ~/.local/bin, or PREFIX=/usr/local
-make config           # optional: write a default config to ~/.config/appwheel/config
+make config           # optional: write a default config to ~/.config/swas/config
 ```
 
 `make static` bakes SDL3 into the binary, so it runs without `libSDL3.so`. It
@@ -29,8 +29,8 @@ Needs any TTF font. Icons need a `.desktop` file and an icon theme.
 ## Use
 
 ```
-bindsym $mod+space exec appwheel
-for_window [app_id="appwheel"] floating enable, border none
+bindsym $mod+space exec swas
+for_window [app_id="swas"] floating enable, border none
 ```
 
 | key | action |
@@ -46,27 +46,33 @@ for_window [app_id="appwheel"] floating enable, border none
 
 Apps are read from the `.desktop` files in the usual directories. The wheel
 shows the most recently opened ones first; every launch is written to
-`~/.cache/appwheel/history`.
+`~/.cache/swas/history`.
 
 ```sh
-appwheel --list                       # every id, name and resolved icon
-appwheel include=firefox,code,gimp    # a curated wheel, in that order
-appwheel --dmenu < items              # a dmenu-style picker on stdin/stdout
+swas --list                       # every id, name and resolved icon
+swas include=firefox,code,gimp    # a curated wheel, in that order
+swas --dmenu < items              # a dmenu-style picker on stdin/stdout
 ```
 
 ## Drop onto a workspace
 
 Drag an app out of the wheel and let go over a workspace: it starts *there*,
-while you stay where you are. As you drag, the wheel shrinks and slides into
-the top-left corner, out of the way of what you are aiming at, and it stays
-open afterwards, ready for the next one.
+while you stay where you are. As you drag, the wheel shrinks to about
+a hundred and thirty pixels across and stays where it is, out of the way of what you are
+aiming at. It is scaled, not redrawn — the same picture, just small — and it
+stays open afterwards, ready for the next one.
 
 Letting go over the wheel itself cancels — nothing opens, and the workspace
 underneath it is never picked up by mistake. A ring around the wheel says so
 while you hover there. `esc` and right click cancel too.
 
-`drop_corner=top-right` parks it on the other side, `none` leaves it in the
-middle.
+While it is small it sits on a disc of its own (`drop_bg`), so it keeps an
+edge against a busy overview instead of reading as a handful of loose marks.
+
+`drop_size` is that width in pixels, which is what you actually want to say
+rather than a fraction of a screen you have to work out; `drop_size=0` falls
+back to `drop_shrink` as a fraction. `drop_corner` moves it out of the middle
+— `top-left`, `top-right`, `bottom-left`, `bottom-right`, or `center`.
 
 Grey outlined tiles are numbers that have no workspace yet — drop on one and
 sway makes it.
@@ -77,13 +83,18 @@ sway makes it.
 underneath, showing every workspace with the windows already in it.
 
 ```
-bindsym $mod+space exec appwheel overview=1
+bindsym $mod+space exec swas overview=1
 
 no_focus [app_id="swov-backdrop"]
 for_window [app_id="swov-backdrop"] floating enable, border none
-for_window [app_id="appwheel"] floating enable, border none
+for_window [app_id="swas"] floating enable, border none
 ```
 
+The app id changed with the name, so any rule of yours saying `app_id="appwheel"`
+needs updating. The config and history move too — `~/.config/swas/config` and
+`~/.cache/swas/history` — but the old `appwheel` ones are still read when the
+new ones are absent, so nothing is lost by not moving them.
+
 `no_focus` is a command in its own right and takes the criteria as its
 argument — it is *not* something you put after `for_window`. Written the wrong
 way round it fails silently at load and the backdrop takes your keyboard.
@@ -95,7 +106,7 @@ If something looks wrong, run it from a terminal with `overview_debug=1`:
 every line between the two, and swov's own complaints, go to stderr.
 
 The backdrop maps on top of the wheel — on Wayland a window cannot lift itself
-back — so appwheel asks swov to restack it as soon as that window is up. If
+back — so swas asks swov to restack it as soon as that window is up. If
 you ever end up with a wheel that ignores the mouse, that is what went wrong;
 `esc` still closes it, and `overview=0` falls back to the plain tiles.
 
@@ -108,7 +119,7 @@ vertically. A bar shows the edge before you let go, the same one swov draws
 when you drag a window inside it. That way a workspace can be filled with a
 few apps in the arrangement you want without touching any of them afterwards.
 
-The app is placed before it opens, not moved after: appwheel hands swov the
+The app is placed before it opens, not moved after: swas hands swov the
 pid the moment it launches, and swov puts an `assign` rule in sway's way while
 the process is still starting. Nothing flashes onto the workspace you are on.
 
@@ -118,34 +129,35 @@ go and then pick one to switch to. The one catch is dropping on the workspace
 you are already on: the app opens behind the wheel, so you will not see it
 until you close it. `drop_close_here=1` closes the wheel in that case.
 
-appwheel starts it only after its own first frame is on screen, and swov fades
+swas starts it only after its own first frame is on screen, and swov fades
 in from nothing, so picking an app straight away shows no flicker at all — you
 never see it arrive. While you drag, the wheel shrinks and the workspace under
 the pointer takes the selection cursor. Let go and the app starts there.
 
-The overview is drawn soft while you are still choosing an app, and sharpens
-as soon as you start dragging — set `blur` in swov's own config.
+Nothing of the wheel's own is drawn over the overview while it is up — no
+second scrim on top of swov's — and the overview is drawn soft while you are
+still choosing an app, sharpening as soon as you start dragging — set `blur` in swov's own config.
 
-The two talk over a pipe, one line each way: appwheel sends the pointer as a
+The two talk over a pipe, one line each way: swas sends the pointer as a
 fraction of the screen, swov answers with the workspace under it. Closing the
 wheel closes the pipe, and the backdrop fades out and leaves.
 
-This needs swov on `PATH`: appwheel asks it for the
+This needs swov on `PATH`: swas asks it for the
 workspace list and hands it the launched process, which swov follows until its
 window appears and then moves. Without swov the feature is simply off. Set
 `drop_focus=1` to follow the app to its workspace instead of staying put.
 
 ## Config
 
-`${XDG_CONFIG_HOME:-~/.config}/appwheel/config`, `key=value`, `#` comments.
+`${XDG_CONFIG_HOME:-~/.config}/swas/config`, `key=value`, `#` comments.
 Every key is also a command line option:
 
 ```sh
-appwheel slots=8 arc=220 icons=0
-appwheel --ui_scale=1.3 --icon_px=56
+swas slots=8 arc=220 icons=0
+swas --ui_scale=1.3 --icon_px=56
 ```
 
-`appwheel --dump-config` prints the whole set with defaults. A `#` after
+`swas --dump-config` prints the whole set with defaults. A `#` after
 whitespace starts a comment, so the annotated lines that command prints can be
 kept as they are. The ones worth
 knowing:
@@ -168,19 +180,21 @@ knowing:
 | `overview_debug` | `1` = print the backdrop conversation to stderr |
 | `drop_close_here` | close after a drop on the current workspace; `0` = stay |
 | `drop_shrink`, `drop_ms`, `drop_px` | how the wheel gets out of the way |
-| `drop_corner` | where it parks while dragging: `top-left`, `top-right`, `none` |
+| `drop_size` | how wide the wheel is while dragging, in px; `0` = use `drop_shrink` |
+| `drop_bg` | the disc behind it while it is small; alpha `00` for none |
+| `drop_corner` | where it sits then: `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right` |
 | `drop_focus` | `1` = switch to the workspace the app landed on |
 | `swov` | the binary asked about workspaces |
 
 ### Shared config
 
-Colours and fonts for appwheel, swov and swbr can be set once in
+Colours and fonts for swas, swov and swbr can be set once in
 `${XDG_CONFIG_HOME:-~/.config}/sw/config`, using role names (`surface`,
 `accent`, `hl`, ...) that each program maps onto its own keys. `sw_theme.h`
 lists them all.
 
-Keys written before any section go to all three programs; a `[appwheel]`
-section goes to appwheel only and takes its own key names as well. The config
+Keys written before any section go to all three programs; a `[swas]`
+section goes to swas only and takes its own key names as well. The config
 above is read afterwards, so it always wins, and the command line wins over
 that.
 
diff --git a/appwheel-static-old_version b/appwheel-static-old_version
deleted file mode 100755
index 6394cfb..0000000
Binary files a/appwheel-static-old_version and /dev/null differ
diff --git a/appwheel.config.example b/appwheel.config.example
deleted file mode 100644
index b4b2d3b..0000000
--- a/appwheel.config.example
+++ /dev/null
@@ -1,66 +0,0 @@
-# appwheel config  —  ~/.config/appwheel/config
-# One key=value per line. '#' starts a comment. Blank lines are ignored.
-# Every key here also works on the command line (key=value or --key=value);
-# command-line values win over the file. See `appwheel --help` for the full list.
-# The values below are the built-in defaults, so this file changes nothing
-# until you edit it.
-
-# --- window ---
-width=900
-height=900
-fullscreen=1     # cover the screen as a borderless overlay (0 = 900x900 window)
-close_on_focus_loss=0   # 1 = quit when the window loses focus (dmenu-style)
-
-# --- ring layout & paging ---
-slots=11          # wide, easy-to-hit slots across the TOP arc
-arc=240           # degrees of the ring used for apps (rest = paging zone)
-radius=0.44       # wheel size, as a fraction of the shorter screen side
-y_offset=0.10     # nudge the wheel down (apps sit up top, so this centers it)
-page_ms=110       # base ms per paged step at the SLOW end. Bigger = calmer
-                  # start. Paging eases in: slow where you enter the bottom
-                  # zone, fast toward straight-down.
-
-# --- rendering ---
-ssaa=2            # full-scene supersampling 1..4 (smooths edges). alias: aa
-animate=1         # subtle settle animation when the search results change
-anim_ms=90        # its duration (0 or animate=0 to turn it off)
-icons=1           # show .desktop icons if found (PNG/SVG/JPG/BMP)
-icon_px=46        # icon size (before ui_scale)
-
-# --- text ---
-ui_scale=1.0      # master text size. 1.3 = bigger, 0.85 = smaller.
-                  # aliases: font_scale, text_scale
-label_px=24       # app labels on the wheel   (all four are multiplied by
-title_px=25       # selected app name (center)  ui_scale, so tweak one or all)
-search_px=20      # the text you type (search box)
-count_px=20       # the "3 / 42" counter
-# By default appwheel uses your desktop's configured font (via fontconfig).
-# Set a .ttf path or a family name to override, e.g. font=JetBrains Mono
-# font=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
-font_px=50        # glyph atlas height; the sharpness ceiling for big text
-
-# --- launching / ordering ---
-# appwheel logs every app you launch to the history file below and shows the
-# most-recently-opened ones first. This is the default (sort=recent).
-sort=recent       # recent = most-recently-opened first (DEFAULT) | alpha = A-Z
-launcher=sh       # sh = run Exec= ; gtk-launch = launch by desktop id
-terminal=xterm    # used for Terminal=true entries when launcher=sh
-# history=~/.cache/appwheel/history   # the opened-apps log (auto-created)
-
-# which apps show / in what order (an id is the .desktop filename without
-# the extension; run `appwheel --list` to see them):
-# dirs=~/.local/share/applications:/usr/share/applications
-# include=firefox,code,gimp     # show ONLY these ids, in this exact order
-# exclude=htop,xterm            # hide these (matches id OR Name)
-
-# --- colors: #rrggbb or #rrggbbaa ---
-# bg alpha < ff => transparent window background (needs a compositor)
-bg=0d111700
-ring=1e2733f2
-ring2=26313ff2
-hl=cb9b00ff        # highlighted slot
-text=e8e8e8ff      # normal slot text
-hltext=141414ff    # text on the highlighted slot
-center=0d1117e6    # hub disc (keep some alpha so search text stays legible)
-accent=89afc4ff    # typed query text + active paging chevrons
-dim=5a6b7aff       # hints / counters / idle chevrons
diff --git a/config.example b/config.example
index 0280aa1..83fc570 100644
--- a/config.example
+++ b/config.example
@@ -1,7 +1,7 @@
-# appwheel config  —  ~/.config/appwheel/config
+# swas config  —  ~/.config/swas/config
 # One key=value per line. '#' starts a comment. Blank lines are ignored.
 # Every key here also works on the command line (key=value or --key=value);
-# command-line values win over the file. See `appwheel --help` for the full list.
+# command-line values win over the file. See `swas --help` for the full list.
 # The values below are the built-in defaults, so this file changes nothing
 # until you edit it.
 
@@ -34,7 +34,7 @@ label_px=24       # app labels on the wheel   (all four are multiplied by
 title_px=25       # selected app name (center)  ui_scale, so tweak one or all)
 search_px=20      # the text you type (search box)
 count_px=20       # the "3 / 42" counter
-# By default appwheel uses your desktop's configured font (via fontconfig).
+# By default swas uses your desktop's configured font (via fontconfig).
 # Set a .ttf path or a family name to override, e.g. font=JetBrains Mono
 # font=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
 font_px=50        # glyph atlas height; the sharpness ceiling for big text
@@ -45,10 +45,14 @@ font_px=50        # glyph atlas height; the sharpness ceiling for big text
 # list and moves the window once it appears.
 drop=1            # 0 = off, the wheel then only launches
 drop_shrink=0.55  # how small the wheel goes while you drag
-drop_corner=top-left   # where it parks while you drag: top-left, top-right
-                  # or none to keep it in the middle. Letting go over the
-                  # wheel there cancels, so it never fights the workspace
-                  # underneath it
+drop_size=132     # how wide the wheel is while you drag, in pixels. It is
+                  # scaled, not redrawn, so it looks the same, just small.
+                  # 0 = use drop_shrink as a fraction of the screen instead
+drop_bg=0d1117d9  # a disc behind the wheel while it is small, so it does not
+                  # get lost over the overview. Alpha 00 for none
+drop_corner=center  # where it sits while dragging: center, top-left,
+                  # top-right, bottom-left, bottom-right. Letting go over the
+                  # wheel cancels wherever it is
 drop_ms=130       # how long that takes
 drop_px=10        # movement before a press turns into a drag
 drop_focus=0      # 1 = also switch to that workspace
@@ -64,15 +68,15 @@ overview_debug=0  # 1 = print the conversation with the backdrop to stderr
 # swov=swov       # the binary to ask (a path works too)
 
 # --- launching / ordering ---
-# appwheel logs every app you launch to the history file below and shows the
+# swas logs every app you launch to the history file below and shows the
 # most-recently-opened ones first. This is the default (sort=recent).
 sort=recent       # recent = most-recently-opened first (DEFAULT) | alpha = A-Z
 launcher=sh       # sh = run Exec= ; gtk-launch = launch by desktop id
 terminal=xterm    # used for Terminal=true entries when launcher=sh
-# history=~/.cache/appwheel/history   # the opened-apps log (auto-created)
+# history=~/.cache/swas/history   # the opened-apps log (auto-created)
 
 # which apps show / in what order (an id is the .desktop filename without
-# the extension; run `appwheel --list` to see them):
+# the extension; run `swas --list` to see them):
 # dirs=~/.local/share/applications:/usr/share/applications
 # include=firefox,code,gimp     # show ONLY these ids, in this exact order
 # exclude=htop,xterm            # hide these (matches id OR Name)
diff --git a/sw_theme.h b/sw_theme.h
index 63d22c6..0a512fc 100644
--- a/sw_theme.h
+++ b/sw_theme.h
@@ -1,10 +1,10 @@
-/* sw_theme.h — one look for swov, appwheel and swbr.
+/* sw_theme.h — one look for swov, swas and swbr.
  *
  *     ${XDG_CONFIG_HOME:-~/.config}/sw/config
  *
  * key=value, '#' comments, same as every other config here. Keys written
  * before any [section] go to all three programs; keys inside [swov],
- * [appwheel] or [swbr] go to that one only.
+ * [swas] or [swbr] go to that one only.
  *
  * Outside a section only *role* names are understood (surface, accent, hl,
  * ...). Each program translates them to its own keys, and roles it has no use
@@ -34,11 +34,11 @@
  * separated by commas: swbr paints its focused workspace button with `hl`.
  */
 typedef struct {
-    const char *role, *swov, *appwheel, *swbr;
+    const char *role, *swov, *swas, *swbr;
 } SwRole;
 
 static const SwRole SW_ROLES[] = {
-    /* role          swov            appwheel   swbr                           */
+    /* role          swov            swas       swbr                           */
     { "bg",          "bg",           "bg",      NULL                           },
     { "surface",     "tile",         "ring",    "bg"                           },
     { "surface_alt", "tile_sel",     "ring2",   NULL                           },
@@ -97,7 +97,7 @@ static int sw_ci_eq(const char *a, const char *b)
 static const char *sw_role_for(const SwRole *r, const char *app)
 {
     if (sw_ci_eq(app, "swov"))     return r->swov;
-    if (sw_ci_eq(app, "appwheel")) return r->appwheel;
+    if (sw_ci_eq(app, "swas") || sw_ci_eq(app, "appwheel")) return r->swas;
     if (sw_ci_eq(app, "swbr"))     return r->swbr;
     return NULL;
 }
diff --git a/appwheel.c b/swas.c
similarity index 91%
rename from appwheel.c
rename to swas.c
index 9042ea0..fb9fb1d 100644
--- a/appwheel.c
+++ b/swas.c
@@ -1,5 +1,5 @@
 /*
- * appwheel — a GTA-V-style radial (weapon-wheel) app launcher for Wayland & X11.
+ * swas — Sway App Selector: a radial (weapon-wheel) app launcher, Wayland & X11.
  *
  * Dependencies:
  *   - SDL3            (the only library you link)
@@ -9,7 +9,7 @@
  * The vendored *.h files just sit next to this source; nothing to install/link.
  *
  * Build:
- *   cc appwheel.c -o appwheel $(pkg-config --cflags --libs sdl3) -lm
+ *   cc swas.c -o swas $(pkg-config --cflags --libs sdl3) -lm
  *
  * See --help for every option (all config keys also work on the command line).
  */
@@ -39,11 +39,11 @@
 
 #include "sw_theme.h"
 
-#define APP_ID "appwheel"          /* wayland app_id / X11 WM_CLASS */
+#define APP_ID "swas"          /* wayland app_id / X11 WM_CLASS */
 
-#define APPWHEEL_VERSION "1.1"
-#ifndef APPWHEEL_BUILD             /* set by the Makefile: md5 of this file */
-#define APPWHEEL_BUILD "unknown"
+#define SWAS_VERSION "1.2"
+#ifndef SWAS_BUILD             /* set by the Makefile: md5 of this file */
+#define SWAS_BUILD "unknown"
 #endif
 
 /* SVG icons via nanosvg (vendored single-header). Third-party headers, so we
@@ -142,12 +142,30 @@ typedef struct {
     int   drop_ms, drop_px, drop_focus;
     int   drop_close_here;            /* dropped on the workspace we are on:
                                          close, or the app opens behind us   */
-    char  drop_corner[16];            /* where the wheel goes while dragging:
-                                         top-left, top-right, or none        */
+    char  drop_corner[16];            /* where the wheel sits while dragging:
+                                         center, top-left, top-right,
+                                         bottom-left, bottom-right, none     */
+    int   drop_size;                  /* its width in px then; 0 = use
+                                         drop_shrink as a fraction instead   */
     char  swov[PATH_MAX];             /* the binary that knows about sway */
     Col bg,ring,ring2,hl,text,hltext,center,accent,dim;
+    Col drop_bg;                      /* the disc behind the shrunken wheel */
 } Config;
 
+/* ~/.config/swas/..., falling back to the old ~/.config/appwheel/... so an
+   existing config and history keep working after the rename */
+static void xdg_path(char*out,size_t n,const char*envvar,const char*dotdir,
+                     const char*leaf){
+    const char*base=getenv(envvar); const char*home=getenv("HOME");
+    char legacy[PATH_MAX];
+    if(base&&*base){ snprintf(out,n,"%s/swas/%s",base,leaf);
+                     snprintf(legacy,sizeof legacy,"%s/appwheel/%s",base,leaf); }
+    else if(home){   snprintf(out,n,"%s/%s/swas/%s",home,dotdir,leaf);
+                     snprintf(legacy,sizeof legacy,"%s/%s/appwheel/%s",home,dotdir,leaf); }
+    else { out[0]='\0'; return; }
+    if(access(out,F_OK)!=0&&access(legacy,F_OK)==0) snprintf(out,n,"%s",legacy);
+}
+
 static void config_defaults(Config*c){
     memset(c,0,sizeof *c);
     c->width=900; c->height=900; c->fullscreen=1; c->close_on_focus_loss=0;
@@ -159,14 +177,13 @@ static void config_defaults(Config*c){
     c->animate=1; c->anim_ms=90; c->recent_first=1;
     c->drop=1; c->drop_shrink=0.55f; c->drop_ms=130; c->drop_px=10; c->drop_focus=0;
     c->overview=0; c->overview_debug=0; c->drop_close_here=0;
-    strcpy(c->drop_corner,"top-left");
+    strcpy(c->drop_corner,"center"); c->drop_size=66;
     strcpy(c->swov,"swov");
     strcpy(c->sort,"recent"); strcpy(c->launcher,"sh");
     const char*term=getenv("TERMINAL");
     snprintf(c->terminal,sizeof c->terminal,"%s",term?term:"xterm");
-    const char*home=getenv("HOME"),*xc=getenv("XDG_CACHE_HOME");
-    if(xc&&*xc) snprintf(c->history,sizeof c->history,"%s/appwheel/history",xc);
-    else        snprintf(c->history,sizeof c->history,"%s/.cache/appwheel/history",home?home:".");
+
+    xdg_path(c->history,sizeof c->history,"XDG_CACHE_HOME",".cache","history");
     c->bg    =(Col){0x0d,0x11,0x17,0x00};   /* transparent by default */
     c->ring  =(Col){0x1e,0x27,0x33,0xf2};
     c->ring2 =(Col){0x26,0x31,0x3f,0xf2};
@@ -174,6 +191,7 @@ static void config_defaults(Config*c){
     c->text  =(Col){0xe8,0xe8,0xe8,0xff};
     c->hltext=(Col){0x14,0x14,0x14,0xff};
     c->center=(Col){0x0d,0x11,0x17,0xe6};
+    c->drop_bg=(Col){0x0d,0x11,0x17,0xd9};
     c->accent=(Col){0x89,0xaf,0xc4,0xff};
     c->dim   =(Col){0x5a,0x6b,0x7a,0xff};
 }
@@ -203,7 +221,9 @@ static void config_set(Config*c,const char*k,const char*v){
     else if(!strcmp(k,"overview"))c->overview=atoi(v);
     else if(!strcmp(k,"overview_debug"))c->overview_debug=atoi(v);
     else if(!strcmp(k,"drop_close_here"))c->drop_close_here=atoi(v);
-    else if(!strcmp(k,"drop_corner"))snprintf(c->drop_corner,sizeof c->drop_corner,"%s",v);
+    else if(!strcmp(k,"drop_corner")||!strcmp(k,"drop_pos"))
+        snprintf(c->drop_corner,sizeof c->drop_corner,"%s",v);
+    else if(!strcmp(k,"drop_size"))c->drop_size=atoi(v);
     else if(!strcmp(k,"drop_shrink"))c->drop_shrink=(float)atof(v);
     else if(!strcmp(k,"drop_ms"))c->drop_ms=atoi(v);
     else if(!strcmp(k,"drop_px"))c->drop_px=atoi(v);
@@ -224,11 +244,12 @@ static void config_set(Config*c,const char*k,const char*v){
     else if(!strcmp(k,"text"))parse_color(v,&c->text);
     else if(!strcmp(k,"hltext"))parse_color(v,&c->hltext);
     else if(!strcmp(k,"center"))parse_color(v,&c->center);
+    else if(!strcmp(k,"drop_bg"))parse_color(v,&c->drop_bg);
     else if(!strcmp(k,"accent"))parse_color(v,&c->accent);
     else if(!strcmp(k,"dim"))parse_color(v,&c->dim);
     else fprintf(stderr,"wheel: unknown key '%s'\n",k);
 }
-/* the shared ~/.config/sw/config, translated into appwheel's own keys */
+/* the shared ~/.config/sw/config, translated into swas's own keys */
 static void config_set_shared(void*ud,const char*k,const char*v){ config_set((Config*)ud,k,v); }
 
 /* `key=value   # what it does` — the trailing comment is not part of the
@@ -809,9 +830,9 @@ static void ov_send(const char*fmt,...){
     int n=vsnprintf(line,sizeof line-1,fmt,ap); va_end(ap);
     if(n<0) return;
     line[n]='\n'; line[n+1]='\0';
-    if(OV_LOG) fprintf(stderr,"appwheel: -> %.*s\n",n,line);
+    if(OV_LOG) fprintf(stderr,"swas: -> %.*s\n",n,line);
     if(write(OV_IN,line,(size_t)n+1)<0){
-        if(OV_LOG) fprintf(stderr,"appwheel: backdrop pipe closed\n");
+        if(OV_LOG) fprintf(stderr,"swas: backdrop pipe closed\n");
         close(OV_IN); OV_IN=-1;
     }
 }
@@ -830,7 +851,7 @@ static void ov_spawn(Config*c){
         close(to[0]); close(to[1]); close(from[0]); close(from[1]);
         execlp(c->swov,c->swov,c->overview_debug?"--backdrop-debug":"--backdrop",
                (char*)NULL);
-        fprintf(stderr,"appwheel: cannot run '%s' (%s) — no overview\n",
+        fprintf(stderr,"swas: cannot run '%s' (%s) — no overview\n",
                 c->swov,strerror(errno));
         _exit(127);
     }
@@ -852,7 +873,7 @@ static void ov_poll(SDL_Window*win){
         char*start=buf,*nl;
         while((nl=strchr(start,'\n'))!=NULL){
             *nl='\0';
-            if(OV_LOG) fprintf(stderr,"appwheel: <- %s\n",start);
+            if(OV_LOG) fprintf(stderr,"swas: <- %s\n",start);
             if(!strcmp(start,"ready")){
                 OV_READY=1;
                 SDL_RaiseWindow(win);          /* enough on X11 */
@@ -946,7 +967,7 @@ static pid_t launch(App*a,Config*c){
     if(pipe(pfd)!=0){ pfd[0]=pfd[1]=-1; }
 
     pid_t pid=fork();
-    if(pid<0){ fprintf(stderr,"appwheel: fork failed\n");
+    if(pid<0){ fprintf(stderr,"swas: fork failed\n");
                if(pfd[0]>=0){ close(pfd[0]); close(pfd[1]); } return -1; }
     if(pid==0){
         if(pfd[0]>=0) close(pfd[0]);
@@ -1054,10 +1075,10 @@ static int on_icon(float mx,float my,float cx,float cy,float rl,float hitr){
 /* ------------------------------------------------------------------ */
 static void dump_config(void){
     fputs(
-"# appwheel config  —  ~/.config/appwheel/config\n"
+"# swas config  —  ~/.config/swas/config\n"
 "# One key=value per line. '#' starts a comment. Blank lines are ignored.\n"
 "# Every key here also works on the command line (key=value or --key=value);\n"
-"# command-line values win over the file. See `appwheel --help` for the full list.\n"
+"# command-line values win over the file. See `swas --help` for the full list.\n"
 "# The values below are the built-in defaults, so this file changes nothing\n"
 "# until you edit it.\n"
 "\n"
@@ -1091,7 +1112,7 @@ static void dump_config(void){
 "title_px=25       # selected app name (center)  ui_scale, so tweak one or all)\n"
 "search_px=20      # the text you type (search box)\n"
 "count_px=20       # the \"3 / 42\" counter\n"
-"# By default appwheel uses your desktop's configured font (via fontconfig).\n"
+"# By default swas uses your desktop's configured font (via fontconfig).\n"
 "# Set a .ttf path or a family name to override, e.g. font=JetBrains Mono\n"
 "# font=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf\n"
 "font_px=50        # glyph atlas height; the sharpness ceiling for big text\n"
@@ -1101,9 +1122,15 @@ static void dump_config(void){
 "# and the wheel stays open. Needs swov on PATH, which is asked for the\n"
 "# workspace list and does the moving.\n"
 "drop=1           # 0 = off, the wheel then only launches\n"
-"drop_shrink=0.55 # how small the wheel goes while you drag\n"
-"drop_corner=top-left  # top-left, top-right or none. Letting go over the\n"
-"                 # wheel there cancels instead of opening anything\n"
+"drop_size=132    # how wide the wheel is while you drag, in pixels. It is\n"
+"                 # scaled, not redrawn, so it looks the same, just small.\n"
+"                 # 0 = use drop_shrink as a fraction of the screen instead\n"
+"drop_shrink=0.55 # that fraction, when drop_size is 0\n"
+"drop_corner=center  # where it sits then: center, top-left, top-right,\n"
+"                 # bottom-left, bottom-right. Letting go over the wheel\n"
+"                 # cancels wherever it is\n"
+"drop_bg=0d1117d9 # a disc behind the wheel while it is small, so it does\n"
+"                 # not get lost over the overview. Alpha 0 for none\n"
 "drop_ms=130      # how long that takes\n"
 "drop_px=10       # movement before a press turns into a drag\n"
 "drop_focus=0     # 1 = also switch to that workspace\n"
@@ -1112,15 +1139,15 @@ static void dump_config(void){
 "# swov=swov      # the binary to ask (a path works too)\n"
 "\n"
 "# --- launching / ordering ---\n"
-"# appwheel logs every app you launch to the history file below and shows the\n"
+"# swas logs every app you launch to the history file below and shows the\n"
 "# most-recently-opened ones first. This is the default (sort=recent).\n"
 "sort=recent       # recent = most-recently-opened first (DEFAULT) | alpha = A-Z\n"
 "launcher=sh       # sh = run Exec= ; gtk-launch = launch by desktop id\n"
 "terminal=xterm    # used for Terminal=true entries when launcher=sh\n"
-"# history=~/.cache/appwheel/history   # the opened-apps log (auto-created)\n"
+"# history=~/.cache/swas/history   # the opened-apps log (auto-created)\n"
 "\n"
 "# which apps show / in what order (an id is the .desktop filename without\n"
-"# the extension; run `appwheel --list` to see them):\n"
+"# the extension; run `swas --list` to see them):\n"
 "# dirs=~/.local/share/applications:/usr/share/applications\n"
 "# include=firefox,code,gimp     # show ONLY these ids, in this exact order\n"
 "# exclude=htop,xterm            # hide these (matches id OR Name)\n"
@@ -1141,20 +1168,20 @@ static void dump_config(void){
 
 static void usage(const char*a0){
     printf(
-"appwheel " APPWHEEL_VERSION " (build " APPWHEEL_BUILD ") — a radial app launcher\n"
+"swas " SWAS_VERSION " (build " SWAS_BUILD ") — Sway App Selector, a radial launcher\n"
 "\n"
 "USAGE\n"
 "  %s [options] [key=value ...]\n"
 "\n"
 "  Every config key below is also a command-line argument. Both forms work:\n"
-"      appwheel slots=8 arc=220 icons=0\n"
-"      appwheel --slots=8 --arc=220 --icons=0\n"
+"      swas slots=8 arc=220 icons=0\n"
+"      swas --slots=8 --arc=220 --icons=0\n"
 "  CLI values override the config file.\n"
 "\n"
 "OPTIONS\n"
 "  -c, --config PATH   config file (default: $XDG_CONFIG_HOME/wheel/config)\n"
 "      --dump-config   print a commented default config (redirect to save it):\n"
-"                        appwheel --dump-config > ~/.config/appwheel/config\n"
+"                        swas --dump-config > ~/.config/swas/config\n"
 "      --list          print discovered apps (with resolved icon) and exit\n"
 "      --no-recent     rank matches purely by relevance, ignoring recent-app bias\n"
 "  -d, --dmenu         read newline-separated items from stdin, print the chosen\n"
@@ -1189,9 +1216,12 @@ static void usage(const char*a0){
 "  and the wheel stays open. Dropping it back on the wheel does nothing.\n"
 "  Needs swov on PATH — it supplies the workspace list and moves the window.\n"
 "  drop=1              0 = off\n"
-"  drop_shrink=0.55    how small the wheel goes while dragging\n"
-"  drop_corner=top-left  where it parks while dragging: top-left, top-right\n"
-"                      or none. Letting go over the wheel there cancels\n"
+"  drop_size=132       how wide the wheel is while dragging, in pixels;\n"
+"                      0 falls back to drop_shrink as a fraction\n"
+"  drop_corner=center  where it sits then: center, top-left, top-right,\n"
+"                      bottom-left, bottom-right. Letting go over the wheel\n"
+"                      cancels wherever it is\n"
+"  drop_bg=0d1117d9    a disc behind it while it is small\n"
 "  drop_ms=130 drop_px=10\n"
 "  drop_focus=0        1 = also switch to that workspace\n"
 "  swov=swov           the binary to ask\n"
@@ -1205,7 +1235,7 @@ static void usage(const char*a0){
 "  An app's \"id\" is just its .desktop filename without the extension:\n"
 "      /usr/share/applications/firefox.desktop      -> id \"firefox\"\n"
 "      ~/.local/share/applications/spotify.desktop  -> id \"spotify\"\n"
-"  Run  appwheel --list  to print every id next to its visible Name.\n"
+"  Run  swas --list  to print every id next to its visible Name.\n"
 "\n"
 "  sort=recent                    recent (most-recently-opened first, the\n"
 "                                 DEFAULT) | alpha (A-Z). Every launch is\n"
@@ -1219,10 +1249,10 @@ static void usage(const char*a0){
 "  history=PATH                   recency file (default ~/.cache/wheel/history)\n"
 "\n"
 "EXAMPLES\n"
-"  appwheel --list                          # discover ids\n"
-"  appwheel include=firefox,code,gimp       # a curated wheel, in that order\n"
-"  appwheel exclude=htop sort=alpha ssaa=3  # hide htop, A-Z, extra-smooth\n"
-"  appwheel ui_scale=1.3 icon_px=56         # bigger text and icons\n"
+"  swas --list                          # discover ids\n"
+"  swas include=firefox,code,gimp       # a curated wheel, in that order\n"
+"  swas exclude=htop sort=alpha ssaa=3  # hide htop, A-Z, extra-smooth\n"
+"  swas ui_scale=1.3 icon_px=56         # bigger text and icons\n"
 "\n"
 "COLORS  (#rrggbb or #rrggbbaa)\n"
 "  bg ring ring2 hl text hltext center accent dim\n"
@@ -1263,9 +1293,8 @@ static void load_apps(AppList*apps, Config*cfg, int dmenu){
 int main(int argc,char**argv){
     Config cfg; config_defaults(&cfg);
     char cfgpath[PATH_MAX];
-    const char*xc=getenv("XDG_CONFIG_HOME"),*home=getenv("HOME");
-    if(xc&&*xc) snprintf(cfgpath,sizeof cfgpath,"%s/appwheel/config",xc);
-    else snprintf(cfgpath,sizeof cfgpath,"%s/.config/appwheel/config",home?home:".");
+    
+    xdg_path(cfgpath,sizeof cfgpath,"XDG_CONFIG_HOME",".config","config");
 
     int want_list=0, dmenu=0;
     for(int i=1;i<argc;i++){
@@ -1273,13 +1302,13 @@ int main(int argc,char**argv){
             snprintf(cfgpath,sizeof cfgpath,"%s",argv[++i]);
         else if(!strcmp(argv[i],"-h")||!strcmp(argv[i],"--help")){ usage(argv[0]); return 0; }
         else if(!strcmp(argv[i],"-v")||!strcmp(argv[i],"--version")){
-            printf("appwheel %s (build %s)\n",APPWHEEL_VERSION,APPWHEEL_BUILD); return 0; }
+            printf("swas %s (build %s)\n",SWAS_VERSION,SWAS_BUILD); return 0; }
         else if(!strcmp(argv[i],"--dump-config")){ dump_config(); return 0; }
         else if(!strcmp(argv[i],"--list")) want_list=1;
         else if(!strcmp(argv[i],"--dmenu")||!strcmp(argv[i],"-d")) dmenu=1;
     }
     { char tmp[PATH_MAX]; expand_tilde(cfgpath,tmp,sizeof tmp); snprintf(cfgpath,sizeof cfgpath,"%s",tmp); }
-    sw_shared_apply("appwheel",config_set_shared,&cfg);   /* shared first */
+    sw_shared_apply("swas",config_set_shared,&cfg);   /* shared first */
     config_load(&cfg,cfgpath);                            /* our own wins  */
     for(int i=1;i<argc;i++){
         if(!strcmp(argv[i],"-c")||!strcmp(argv[i],"--config")){ i++; continue; }
@@ -1304,9 +1333,9 @@ int main(int argc,char**argv){
         return 0;
     }
 
-    /* Identify as appwheel so the compositor shows the same name everywhere,
+    /* Identify as swas so the compositor shows the same name everywhere,
        Wayland app_id / X11 WM_CLASS so float/center rules match. Before init. */
-    SDL_SetAppMetadata(APP_ID,APPWHEEL_VERSION,"org.appwheel.appwheel");
+    SDL_SetAppMetadata(APP_ID,SWAS_VERSION,"org.swas.selector");
     SDL_SetHint(SDL_HINT_APP_ID,APP_ID);
 
     if(!SDL_Init(SDL_INIT_VIDEO)){ fprintf(stderr,"SDL_Init: %s\n",SDL_GetError()); return 1; }
@@ -1341,7 +1370,7 @@ int main(int argc,char**argv){
 
     load_apps(&apps,&cfg,dmenu);                    /* slow part; keystrokes queue meanwhile */
 
-    if(apps.n==0){ fprintf(stderr,"appwheel: no %s\n", dmenu?"input on stdin":".desktop applications found");
+    if(apps.n==0){ fprintf(stderr,"swas: no %s\n", dmenu?"input on stdin":".desktop applications found");
                    SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit(); return 1; }
 
     Font font; memset(&font,0,sizeof font);
@@ -1354,7 +1383,7 @@ int main(int argc,char**argv){
     if(!*fontpath) try_font_paths(fontpath,sizeof fontpath);         /* last-resort known paths */
     int atlas_px=(int)(cfg.font_px*cfg.ui_scale); if(atlas_px<10)atlas_px=10; if(atlas_px>200)atlas_px=200;
     if(*fontpath) font_load(&font,ren,fontpath,atlas_px);
-    if(!font.ok) fprintf(stderr,"appwheel: no usable TTF font found; using built-in font\n");
+    if(!font.ok) fprintf(stderr,"swas: no usable TTF font found; using built-in font\n");
 
     int *filt=malloc(apps.n*sizeof*filt); int fn=0; char query[256]={0};
     int off=0, selslot=0;                 /* fixed highlight = off+selslot     */
@@ -1403,8 +1432,19 @@ int main(int argc,char**argv){
         int w,h; SDL_GetWindowSize(win,&w,&h);
         int ss=cfg.ssaa;
 
-        {   /* ease the wheel down to drop_shrink and into its corner, and back */
-            float want = dragging ? cfg.drop_shrink : 1.0f;
+        {   /* ease the wheel down to its dragging size and place, and back.
+               drop_size is a width in pixels, which is what you actually want
+               to say — "about a hundred across" — rather than a fraction of a
+               screen you have to work out. */
+            float full = (float)(w<h?w:h);
+            float want = 1.0f;
+            if(dragging){
+                want = cfg.drop_size>0 && cfg.radius>0.0f && full>0.0f
+                     ? (float)cfg.drop_size/(2.0f*cfg.radius*full)
+                     : cfg.drop_shrink;
+                if(want<0.04f) want=0.04f;
+                if(want>1.0f)  want=1.0f;
+            }
             float step = cfg.drop_ms>0 ? 16.0f/(float)cfg.drop_ms : 1.0f;
             if(wheel_scale<want){ wheel_scale+=step; if(wheel_scale>want)wheel_scale=want; }
             else if(wheel_scale>want){ wheel_scale-=step; if(wheel_scale<want)wheel_scale=want; }
@@ -1418,15 +1458,17 @@ int main(int argc,char**argv){
         float R=mind*cfg.radius, ri=R*0.46f, rc=ri*0.95f, rl=(R+ri)/2.0f;
         float cx=w/2.0f, cy=h/2.0f + cfg.y_offset*mind;
 
-        /* Out of the way: parked in a corner the wheel stops covering the
-           workspaces you are aiming at, and becomes the place to drop an app
-           you have changed your mind about. */
-        int corner_left = !strcmp(cfg.drop_corner,"top-left");
-        int corner_on   = corner_left || !strcmp(cfg.drop_corner,"top-right");
-        if(corner_on && corner_t>0.0f){
+        /* Out of the way. Small enough in the middle it stops covering what
+           you are aiming at; a corner moves it further still. Either way it
+           stays the place to drop an app you have changed your mind about. */
+        int c_left  = strstr(cfg.drop_corner,"left")   != NULL;
+        int c_right = strstr(cfg.drop_corner,"right")  != NULL;
+        int c_top   = strstr(cfg.drop_corner,"top")    != NULL;
+        int c_bot   = strstr(cfg.drop_corner,"bottom") != NULL;
+        if((c_left||c_right||c_top||c_bot) && corner_t>0.0f){
             float pad=R*0.12f+14.0f*cfg.ui_scale;
-            float tx=corner_left ? R+pad : (float)w-R-pad;
-            float ty=R+pad;
+            float tx = c_left ? R+pad : c_right ? (float)w-R-pad : cx;
+            float ty = c_top  ? R+pad : c_bot   ? (float)h-R-pad : cy;
             float e=corner_t*corner_t*(3.0f-2.0f*corner_t);   /* smoothstep */
             cx += (tx-cx)*e;
             cy += (ty-cy)*e;
@@ -1679,16 +1721,34 @@ int main(int argc,char**argv){
             else ss=1;
         }
 
-        SDL_SetRenderDrawColor(ren,cfg.bg.r,cfg.bg.g,cfg.bg.b,cfg.bg.a);
+        /* With swov behind us it draws its own scrim; a second one over the
+           top only makes the thing you are aiming at harder to see. */
+        Col clearc = OV_READY ? (Col){0,0,0,0} : cfg.bg;
+        SDL_SetRenderDrawColor(ren,clearc.r,clearc.g,clearc.b,clearc.a);
         SDL_RenderClear(ren);
 
         float slotw=step;
-        float label_px=cfg.label_px*ui;
+        /* everything inside the wheel is measured against this, so shrinking
+           the wheel shrinks its contents by the same amount and it reads as
+           the same picture, just smaller. The workspace tiles and the app on
+           the pointer keep the real ui scale. */
+        float uiw=ui*wheel_scale;
+        float label_px=cfg.label_px*uiw;
         /* app-data crossfade: on a results change, the names/icons/highlight text
            fade back in while the ring sectors (background) stay put — smooths fast
            typing without delaying anything. */
         float af = (cfg.animate && cfg.anim_ms>0)
                    ? clampf(0.30f + 0.70f*(float)(SDL_GetTicks()-anim0)/(float)cfg.anim_ms, 0.0f, 1.0f) : 1.0f;
+
+        /* Small, over a busy overview, the wheel had nothing to sit on and
+           read as a handful of loose marks. A disc behind it gives it an edge
+           again — only while it is small, fading in with the shrink. */
+        if(corner_t>0.0f && cfg.drop_bg.a){
+            Col d=cfg.drop_bg;
+            d.a=(Uint8)(d.a*clampf(corner_t,0.0f,1.0f));
+            fill_circle(ren,cx,cy,R*1.10f,d);
+        }
+
         for(int i=0;i<vis;i++){
             int item=filt[off+i];
             float a = astart+(i+0.5f)*step;
@@ -1710,8 +1770,8 @@ int main(int argc,char**argv){
 
             SDL_Texture*ic=app_icon(ren,&apps.v[item],&cfg);
             if(ic){
-                float isz=cfg.icon_px*ui; if(isz>chord)isz=chord;
-                float gap=7.0f*ui;                       /* breathing room */
+                float isz=cfg.icon_px*uiw; if(isz>chord)isz=chord;
+                float gap=7.0f*uiw;                       /* breathing room */
                 float blockH=isz+gap+label_px;
                 float topy=ly-blockH/2;
                 SDL_FRect dst={lx-isz/2, topy, isz, isz};
@@ -1733,13 +1793,13 @@ int main(int argc,char**argv){
             { int on=(page_dir<0); float sp=on?page_speed:0;
               Col c=on?cfg.accent:cfg.dim; c.a=on?255:210;
               int cnt=1+(on?(int)lroundf(sp*2):0);
-              float s=(19.0f+ (on?13.0f*sp:0))*ui;
+              float s=(19.0f+ (on?13.0f*sp:0))*uiw;
               draw_chevrons(ren,lxp,lyp,-1,s,cnt,c); }
             /* right */
             { int on=(page_dir>0); float sp=on?page_speed:0;
               Col c=on?cfg.accent:cfg.dim; c.a=on?255:210;
               int cnt=1+(on?(int)lroundf(sp*2):0);
-              float s=(19.0f+ (on?13.0f*sp:0))*ui;
+              float s=(19.0f+ (on?13.0f*sp:0))*uiw;
               draw_chevrons(ren,rxp,ryp,+1,s,cnt,c); }
         }
 
@@ -1750,20 +1810,20 @@ int main(int argc,char**argv){
         if(query[0]) snprintf(shown,sizeof shown,"%s%s",query,caret?"|":" ");
         else         snprintf(shown,sizeof shown,"type to search");
         Col qc=query[0]?cfg.accent:cfg.dim;
-        text_centered(ren,&font,cx,cy-rc*0.42f,cfg.search_px*ui,qc,shown);
+        text_centered(ren,&font,cx,cy-rc*0.42f,cfg.search_px*uiw,qc,shown);
 
         if(fn){
             int sel_item=filt[sel]; last_sel=sel_item;
             float caf = (sel_item==snap_sel)?1.0f:af;      /* same app in the hub -> no fade */
-            char nm[200]; fit_label(&font,cfg.title_px*ui,apps.v[sel_item].name,rc*1.7f,nm,sizeof nm);
+            char nm[200]; fit_label(&font,cfg.title_px*uiw,apps.v[sel_item].name,rc*1.7f,nm,sizeof nm);
             Col nmc=cfg.text; nmc.a=(Uint8)(nmc.a*caf);
-            text_centered(ren,&font,cx,cy,cfg.title_px*ui,nmc,nm);
+            text_centered(ren,&font,cx,cy,cfg.title_px*uiw,nmc,nm);
             char cnt[64]; snprintf(cnt,sizeof cnt,"%d / %d",sel+1,fn);
             Col cc=cfg.dim; cc.a=(Uint8)(cc.a*caf);
-            text_centered(ren,&font,cx,cy+rc*0.40f,cfg.count_px*ui,cc,cnt);
+            text_centered(ren,&font,cx,cy+rc*0.40f,cfg.count_px*uiw,cc,cnt);
         } else {
             last_sel=-1;
-            text_centered(ren,&font,cx,cy,cfg.title_px*ui,cfg.dim,"no matches");
+            text_centered(ren,&font,cx,cy,cfg.title_px*uiw,cfg.dim,"no matches");
         }
 
         /* --- the workspaces, and the app hanging off the pointer --- */