Movatterモバイル変換


[0]ホーム

URL:


Jwno

Jwno

Playing With WSLg Windows

Jwno »Devlog

Jwno And WSLg Windows

When it comes to window management, theWSLg windows are quite unique, because they live in both worlds. The cool kids from Microsoft is using a customWeston compositor to manage the Linux windows, passing the rendered content through a fancy localRDP connection. The Linux GUI we see on our Windows desktops are, in fact, “remote” windows created by Microsoft Remote Desktop Client (msrdc.exe).

It surely has a lot of moving parts, but works great in general. That is, when we manipulate our windows with a mouse. There arelong-standingissues in the WSLg repository tracking window movement/layout problems from the Windows side. TL; DR: If we call Win32 APIs, such asSetWindowPos, instead of using the mouse, on a WSLg window, the window on the Linux side would have weird behavior.

If you invoke Jwno’s:describe-window command (bound toWin+W D in the example config) on a WSLg window, you would find that Jwno doesn’t see it as a normal window, because it doesn’t even have aWindow Control Pattern:

You can try to force Jwno to manage a WSLg window using the:manage-window command (bound toWin+W M in the example config), and it wouldlook like that window got resized/moved successfully, but the actual Linux GUI would stay where it was, making the WSLg window shown on screen misaligned with the real UI.

I understand that it’s hard to sync states between two distinct graphical environments, but this issue renders Jwno completely useless against WSLg windows.

Well, maybe not completely. Jwno has such a funny design (cough not a complimentcough), we can still hack it, to have some fun!

Hacking It (in Lisp Style)

In Common Lisp (yeah it’s an all-of-a-sudden-detour, buckle up), functions are mostly referenced by theirnames. That means the actual bodies of the functions can be re-defined at runtime, and be available to their callers immediately. E.g. you can do this:

ECL (Embeddable Common-Lisp) 24.5.10 (git:UNKNOWN)[...banner text omitted...]> (defun callee () (format t "printing from CALLEE~%"))CALLEE> (defun caller () (callee))CALLER> (caller)printing from CALLEENIL> (defun callee () (format t "printing from NEW CALLEE~%")) ;; re-define CALLEECALLEE> (caller) ;; call CALLER again, the new definition for callee is available immediatelyprinting from NEW CALLEENIL

This is handy, since you can “patch” arunning program by simply re-defining existing functions. I did this in myStumpWM config on my Linux machines, to work around bugs and tweak WM behavior.

But, if we try the same trick in Janet:

Janet 1.37.1-83e8aab2 linux/aarch64/clang - '(doc)' for helprepl:1:> (defn callee [] (printf "printing from CALLEE"))<function callee>repl:2:> (defn caller [] (callee))<function caller>repl:3:> (caller)printing from CALLEEnilrepl:4:> (defn callee [] (printf "printing from NEW CALLEE"))<function callee>repl:5:> (caller)printing from CALLEEnil

Oops,caller still uses the old definition ofcallee. That’s because, unlike Common Lisp, Janet functions are mostly referenced and passed around by theirvalues, and they get “frozen” at their call sites at compile-time.

To make things more “dynamic”, Jwno exports most of its APIs as objects with their own methods. Objects in Janet are justmutable tables with prototypes, so we can override their methods by simply changing their table content.

Take the WSLg windows we talked about as an example (finally!), since normal transformation using Win32 APIs doesn’t work for them, we’ll provide ourown:transform method for these window objects.

What do we do to actually transform the WSLg windows then? When playing with them, I found that some of them respond correctly to X11-related commands on the Linux side, e.g.xdotool, andwsl.exe on the Windows side can pass our window geometries to those commands.

(I should mention that I’m certainly not thefirst one to come up with such a trick.)

So invoking this command is exactly what we’re going to do:

wsl.exe --exec xdotool search --name <window title> windowmove <x> <y> windowsize <width> <height>

And the control flow would make a roundtrip between the host system and the Linux VM:

But, I failed to find a similar command for the custom Weston compositor, or for Wayland in general,so the trick only works for X11 windows. I did a quick-and-dirty implementation as a separate Janet script, and here’s how it works on the good oldglxgears:

You can see it’s reeeaaally laggy, due to the host <-> VM roundtrip. And there’s a console window flash-opening every time the WSLg window is manipulated 😂.

The Actual Code

In case you want to try it out, the whole script ishere. Make sure you read the comments for usage tips and caveats. It’s a playfulhack after all, and too unstable to be included in Jwno’s core code.

Until next time! 🤘

Get Jwno

Buy Now$10.00 USD or more

Jwno

A tiling window manager for Windows 10/11, built with Janet and ❤️.

Add Tool To Collection

More posts

See all posts

Leave a comment

Log in with itch.io to leave a comment.

itch.io·View all by Agent Kilo·Report
JwnoBlog

[8]ページ先頭

©2009-2025 Movatter.jp