Skip to content

Add the WM_CLASS property to the BizHawk window#4782

Open
Leopardly wants to merge 6 commits into
TASEmulators:masterfrom
Leopardly:linux-wm-class
Open

Add the WM_CLASS property to the BizHawk window#4782
Leopardly wants to merge 6 commits into
TASEmulators:masterfrom
Leopardly:linux-wm-class

Conversation

@Leopardly

@Leopardly Leopardly commented Jun 24, 2026

Copy link
Copy Markdown

dev build for branch | Leopardly:linux-wm-class

Adds a set of calls to XLIB to set a WM_CLASS on Linux for BizHawk; runs once but has to be run in the main loop as the application needs to be fully loaded and rendering (If there is a better place to put this, please do let me know!). Also added support for defining the WM_CLASS to use via a CLI argument.

There were 2 issues essentially:

  • Using custom .desktop s to launch Bizhawk with the roms and Lua scripts I want (for things like Kaizo) - the system has no way to correlate the running Bizhawk instance with what was launched so it falls back to using the embedded icon, rather than the icon of the .desktop file.
  • Attempting to set rules with KDE's built in "Window Rules" gives you a warning that no WM_CLASS is set, meaning things like "Remove window borders" rules etc have to rely on less reliable pickups like window title.

I'll admit the first case (which is basically my justification for the CLI arg) is niche and I'm not against dropping it entirely; it just makes having say "Run X in Bizhawk" as a shortcut much easier to uniquely integrate rather than running instances all looking the same.

CI suites ran; I think that's all I needed to do?

Check if completed:

@YoshiRulz YoshiRulz added App: EmuHawk Relating to EmuHawk frontend re: Multiplatform Relating to porting to Linux (or macOS, etc.), or porting to other host architectures labels Jun 25, 2026

@YoshiRulz YoshiRulz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a bunch of lint problems too, but you can ignore those until we finalise the design.

Comment thread src/BizHawk.Client.EmuHawk/MainForm.cs Outdated
Comment thread src/BizHawk.Client.EmuHawk/MainForm.cs Outdated
Comment thread src/BizHawk.Common/OSTailoredCode.cs Outdated
Comment thread src/BizHawk.Common/OSTailoredCode.cs Outdated
public static void SetWMClass(IntPtr x11Display, string className)
{
//Setup the ClassHint
var wmSet = new XlibImports.XClassHint{res_name = Marshal.StringToCoTaskMemAnsi("BizHawk"), res_class = Marshal.StringToCoTaskMemAnsi(className)};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why the same string needs to be passed twice?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WM_CLASS property is made up of two parts (name and class) - both need to be provided - they can be different/unique however it is somewhat common to see application name used in both fields (as I have here as the default behaviour).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incidentally, I saw this in Mono's issue tracker: https://gitlab.winehq.org/mono/mono/-/work_items/32

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I can't say I'd seen that happening (although I'm just on whatever mono is in Cachy's repos) - Picking through Keepass's implementation it looks like their is a neater way to be picking up the Window frame to assign WM_CLASS to - so I may take a look at that next week (away all weekend)


private static readonly Option<string?> OptionWMClass = new ("--wmclass")
{
Description = "set a custom WM_CLASS for this Bizhawk initiation, Linux only.",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a CLI flag? When should a user be changing it? If it's for vendoring, we already have VersionInfo.CustomBuildString.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial reasoning for looking into adding WM_CLASS was to help improve BizHawk's integration with the DE (I use KDE). By defining a WM_CLASS we can hint StartupWMClass for example in .desktop files.
In allowing WM_CLASS to be set in a CLI arg it is then feasible to distinguish between different installs of Bizhawk (for example, a Kaizo Ironmon setup and a regular Bizhawk install)

This comment was marked as resolved.

This comment was marked as resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I should really get around to making a textbox to set the window title thing. Then you could pull from that, and your .desktop files could pass --config. Or maybe it could use the rom name and you wouldn't need any extra flags?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App: EmuHawk Relating to EmuHawk frontend re: Multiplatform Relating to porting to Linux (or macOS, etc.), or porting to other host architectures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants