Web-facing or private intranet?
Window management is up to the Browser and the OS. HTML & ECMAscript have nothing to say about it.
If this is for a public-facing website, then just don't bother -- as they say, "Don't break the web."
But I really wanna!
If this is for some tightly managed (say Intranet) application of some kind then you'll need to resort to writing Addons/Extensions. It's certaintly easier if you can restrict yourself to a single browser & platform.
EDIT: Example for Firefox on Win32...
This solution works as a custom addon for Firefox which uses jsctypes
internally to load a Win32 DLL. The window_focus()
JavaScript function is exposed which does what you want.
There are 3 parts to this solution:
- The privileged JavaScript code to load/bind the Win32 APIs
- The CPP header file for our external DLL
- The CPP source file for our external DLL
I built a simple GUI DLL project in MSVC++ with the later two files & compiled wmctrl.dll
, depending on msvcr100.dll
, and used Dependency Walker to find the "plain C" symbols exported by the DLL for use by js-ctypes. E.g: ?wmctrl_find_window@@YAKPAD@Z
is the "plain C" symbol for the C++ api function called wmctrl_find_window
.
As a caveat, this code relies on temporarily being able to change the title of the window that needs to be focused so that Win32 APIs can examine all windows on your desktop to find the correct Firefox window.
You need to have access to privileged Mozilla platform APIs, i.e: JavaScript inside a Firefox Addon.
In your privileged JavaScript code:
// get API constants (might already be available)
const {Cc,Ci,Cu} = require("chrome");
// import js-ctypes
var file=null, lib=null, ctypes = {};
Cu.import("resource://gre/modules/ctypes.jsm", ctypes);
var ctypes = ctypes.ctypes;
// build platform specific library path
var filename = ctypes.libraryName("wmctrl"); // automatically adds '.dll'
var comp = "@mozilla.org/file/directory_service;1";
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
file.append("browser_code"); // or whereever you put your DLL
file.append(filename);
// get the JavaScript library interface (load the library)
var lib = ctypes.open(file.path);
// wmctrl_find_window: returing unsigned 32bit (long) "window handle"
// takes string "window title".
var find_window = lib.declare(
"?wmctrl_find_window@@YAKPAD@Z", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.uint32_t, /* return type: uint32 */
ctypes.char.ptr); /* parameter: string */
// wmctrl_window_focus: takes unsigned 32bit (long) "window handle".
var window_focus = lib.declare(
"?wmctrl_window_focus@@YAXK@Z", /* plain "C" DLL symbol */
ctypes.stdcall_abi, ctypes.void_t, /* return type: void */
ctypes.uint32_t); /* parameter: uint32 */
wmctrldll.h
#ifdef WMCTRLDLL_EXPORTS
#define WMCTRLDLL_API __declspec(dllexport)
#else
#define WMCTRLDLL_API __declspec(dllimport)
#endif
WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid);
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
wmctrldll.cpp
typedef struct {
HWND hWnd;
char title[255];
} myWinSpec;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
char String[255];
myWinSpec* to_find = (myWinSpec*) lParam;
// not a window
if (!hWnd) return TRUE;
// not visible
if (!IsWindowVisible(hWnd)) return TRUE;
// no window title
if (!GetWindowTextA(hWnd, (LPSTR)String, 255)) return TRUE;
// no title match
if (strcmp(String, to_find->title) != 0) return TRUE;
to_find->hWnd = hWnd;
return FALSE;
}
WMCTRLDLL_API void wmctrl_window_focus(unsigned long wid) {
SetForegroundWindow((HWND) wid);
}
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title) {
myWinSpec to_find;
sprintf_s(to_find.title, sizeof(to_find.title), "%s", find_title);
to_find.hWnd = 0;
EnumWindows(EnumWindowsProc, (LPARAM)&to_find);
return (unsigned long) to_find.hWnd;
}