How can I give my Native Messaging host a real window handle so its dialogs can take focus on Windows?

171 views
Skip to first unread message

Ryan Guilbault

unread,
Jul 23, 2025, 7:28:08 PM7/23/25
to Chromium Extensions

Hi all,

I’m building a Chrome native‑messaging host on Windows that sometimes needs to pop up a MessageBox (or similar dialog, e.g. for scanner UI or reporting errors). Right now, when it tries to call SetForegroundWindow, Windows refuses and just flashes the taskbar button, because Chrome still owns the foreground.

I dug into Chromium’s code and found this:

```
// Pass handle of the native view window to the native messaging host.
// This way the host will be able to create properly focused UI windows.
#if BUILDFLAG(IS_WIN)
 command_line.AppendArg(
 base::StringPrintf("--parent-window=%" PRIdPTR, window_handle));
#endif
```

However, my host is launched from a service‑worker background page, so --parent-window=0 every time.

I have tried locating how to change this behavior and tried flipping the NativeHostsExecutablesLaunchDirectly flag (which also controls start_hidden), but I am failing to find anything useful that will pass a valid HWND.

The current workaround I’ve seen is to briefly open a 1x1 popup so Chrome will pass its window handle:

```
chrome.windows.create({
  url: "toast.html",
  type: "popup",
  width:1,
  height:1,
  focused:true }, win => {
    const port = chrome.runtime.connectNative("com.mycompany.myhost");
    port.postMessage(data); setTimeout(() => chrome.windows.remove(win.id), 100); });

That hack may work (I have not tried it yet), but it feels brittle:

  1. Is there a supported API for forcing Chrome to hand me its window handle, even from a background script?

  2. Am I missing another flag or context under which --parent-window is set?

  3. Are there “official” patterns (beyond toast popups or UIAccess manifests) that extension authors use to let native‑host dialogs take focus without extra user clicks?

Any pointers or "tried-and-true" recipes you’ve used would be hugely appreciated!

Thanks

woxxom

unread,
Jul 24, 2025, 12:48:50 AM7/24/25
to Chromium Extensions, Ryan Guilbault
>  my host is launched from a service‑worker background page, so --parent-window=0 every time

Assuming you have some browser windows open it sounds like a bug in Chrome, because I would expect HWND to use the so-called "current window", which is either the window of the caller (this is what's happening now) or the last focused browser window of the same user.

woxxom

unread,
Jul 24, 2025, 12:58:42 AM7/24/25
to Chromium Extensions, woxxom, Ryan Guilbault
I guess the bug is caused by the fact that a service worker doesn't have an associated NativeView:

You should report the bug and explain that it's not a minor inconvenience because the workaround can be broken by another extension that immediately closes the window and it's disruptive as opening a new window may flicker in the taskbar or cause large reflows in an tiling desktop manager.

Inspirational kid ;237

unread,
Jul 24, 2025, 3:19:52 AM7/24/25
to Chromium Extensions, Ryan Guilbault
HI

Ryan Guilbault

unread,
Jul 24, 2025, 8:55:04 AM7/24/25
to woxxom, Chromium Extensions
yep, I had found that code as well:

#if BUILDFLAG(IS_WIN)
  window_handle = reinterpret_cast<intptr_t>(
      views::HWNDForNativeView(native_view));

and ran out of gas trying to track down how/where a native_view gets setup before I sent my message. 

I'm going to try the popup trick just to confirm that it would work and then I will see about submitting a bug report for this.

fwiw, I think this may have been a change (regression?) with mv3, since I had no issues in mv2 taking focus with my application before (I didn't need the --parent-window parameter).
 https://www.facebook.com/MeditechEHR  https://twitter.com/MEDITECH  https://www.youtube.com/@MEDITECHvideo  https://www.threads.net/@meditechehr  https://www.linkedin.com/company/meditech  https://instagram.com/meditechehr
Subscribe to receive emails from MEDITECH or to change email preferences.

Ryan Guilbault

unread,
Jul 24, 2025, 10:34:01 PM7/24/25
to woxxom, Chromium Extensions
I tested opening a chrome window and opening the connection to my native app from the callback and it made no difference re: --parent-window.

I went ahead and filed:


with a demo. I elected to file a new report vs. resurrecting:


which would be another way to accommodate my needs, but has a lot of baggage (and lack of movement for a couple years now).

Reply all
Reply to author
Forward
0 new messages