Skip to content

Add the WM_CLASS property to the BizHawk window#4782

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

Add the WM_CLASS property to the BizHawk window#4782
Leopardly wants to merge 5 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.

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.

StepRunLoop_Throttle();

//Code to set WM_CLASS only need be run once, but must be run after the application has rendered at least once
if(_runWMSetOnce && OSTailoredCode.CurrentOS==OSTailoredCode.DistinctOS.Linux)

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 few possible places for init code, mainly the constructor and the Load handler MainForm_Load.

if(_runWMSetOnce && OSTailoredCode.CurrentOS==OSTailoredCode.DistinctOS.Linux)
{
string wmclass = _argParser.wmClassName is not null ? _argParser.wmClassName : "BizHawk";
OSTailoredCode.SetWMClass(_x11Display,wmclass);

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.

I think this is meant to be a lazy-initialised variable:

if (_x11Display == IntPtr.Zero)
{
_x11Display = XlibImports.XOpenDisplay(null);

So you should do the same here.

return stdout.ReadLine()!;
}

public static void SetWMClass(IntPtr x11Display, string 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.

Move to XlibImports

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


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)

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