Skip to content

add focus & resize window functions #164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 14, 2023
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@ export function getWindows(): number[];
export function getActiveWindow(): number;
export function getWindowRect(handle: number): Rect;
export function getWindowTitle(handle: number): string;
export function focusWindow(handle: number): void;
export function resizeWindow(handle: number, width: number, height: number): void;

export const screen: Screen;
2 changes: 2 additions & 0 deletions permissionCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ try {
"getActiveWindow",
"getWindowRect",
"getWindowTitle",
"focusWindow",
"resizeWindow"
];
const screenCaptureAccess = [
"getWindowTitle",
Expand Down
29 changes: 29 additions & 0 deletions src/linux/window_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,32 @@ MMRect getWindowRect(const WindowHandle windowHandle) {
}
return windowRect;
}

bool focusWindow(const WindowHandle windowHandle) {
Display* display = XGetMainDisplay();
if (display != NULL && windowHandle >= 0) {
// Try to set the window to the foreground
XSetInputFocus(display, windowHandle, RevertToParent, CurrentTime);
XRaiseWindow(display, windowHandle);
XFlush(display);

return true;
}
return false;
}

bool resizeWindow(const WindowHandle windowHandle, int width, int height) {
Display* display = XGetMainDisplay();
if (display != NULL && windowHandle >= 0) {
XWindowChanges changes;
changes.width = width;
changes.height = height;

// Resize the window
XConfigureWindow(display, windowHandle, CWWidth | CWHeight, &changes);
XFlush(display);

return true;
}
return false;
}
25 changes: 25 additions & 0 deletions src/macos/window_manager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,28 @@ MMRect getWindowRect(const WindowHandle windowHandle) {
}
return "";
}

BOOL focusWindow(NSWindow *window) {
if (window) {
// Restore the window if it's minimized
if ([window isMiniaturized]) {
[window deminiaturize:nil];
}

// Try to set the window to the foreground
[window makeKeyAndOrderFront:nil];

return YES;
}
return NO;
}

BOOL resizeWindow(NSWindow *window, int width, int height) {
if (window) {
NSRect frame = [window frame];
frame.size = NSMakeSize(width, height);
[window setFrame:frame display:YES animate:NO];
return YES;
}
return NO;
}
25 changes: 25 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,29 @@ Napi::String _getWindowTitle(const Napi::CallbackInfo &info) {
return Napi::String::New(env, getWindowTitle(windowHandle));
}

Napi::Boolean _focusWindow(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();

WindowHandle windowHandle = info[0].As<Napi::Number>().Int64Value();

bool result = focusWindow(windowHandle);

return Napi::Boolean::New(env, result);
}

Napi::Boolean _resizeWindow(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();

WindowHandle windowHandle = info[0].As<Napi::Number>().Int64Value();
int width = info[1].As<Napi::Number>().Int32Value();
int height = info[2].As<Napi::Number>().Int32Value();

bool result = resizeWindow(windowHandle, width, height);

return Napi::Boolean::New(env, result);
}


Napi::Object _captureScreen(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();

Expand Down Expand Up @@ -725,6 +748,8 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "getActiveWindow"), Napi::Function::New(env, _getActiveWindow));
exports.Set(Napi::String::New(env, "getWindowRect"), Napi::Function::New(env, _getWindowRect));
exports.Set(Napi::String::New(env, "getWindowTitle"), Napi::Function::New(env, _getWindowTitle));
exports.Set(Napi::String::New(env, "focusWindow"), Napi::Function::New(env, _focusWindow));
exports.Set(Napi::String::New(env, "resizeWindow"), Napi::Function::New(env, _resizeWindow));
exports.Set(Napi::String::New(env, "captureScreen"), Napi::Function::New(env, _captureScreen));
exports.Set(Napi::String::New(env, "getXDisplayName"), Napi::Function::New(env, _getXDisplayName));
exports.Set(Napi::String::New(env, "setXDisplayName"), Napi::Function::New(env, _setXDisplayName));
Expand Down
27 changes: 27 additions & 0 deletions src/win32/window_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,30 @@ std::string getWindowTitle(const WindowHandle windowHandle) {
}
return "";
}

bool focusWindow(const WindowHandle windowHandle) {
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
if (IsWindow(hWnd)) {
// Restore the window if it's minimized
if (IsIconic(hWnd)) {
ShowWindow(hWnd, SW_RESTORE);
}

// Try to set the window to the foreground
return SetForegroundWindow(hWnd);
}
return false;
}

bool resizeWindow(const WindowHandle windowHandle, int width, int height) {
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
if (IsWindow(hWnd)) {
RECT rect;
if (GetWindowRect(hWnd, &rect)) {
int x = rect.left;
int y = rect.top;
return MoveWindow(hWnd, x, y, width, height, TRUE);
}
}
return false;
}
19 changes: 19 additions & 0 deletions src/window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ std::string getWindowTitle(const WindowHandle windowHandle);
* That is, a window's top left position given as `x` and `y` coordinate, as well as it's window size given as `width` and `height`
* The respective window handle may be aquired via `getWindows` or `getActiveWindow`
*/
/**
* `focusWindow` focuses on the window specified by its window handle.
* It brings the specified window to the foreground and gives it input focus.
* The respective window handle may be acquired via `getWindows` or `getActiveWindow`.
* @param windowHandle The window handle of the window to be focused.
* @return Returns a boolean indicating whether the window focus operation was successful.
*/
bool focusWindow(const WindowHandle windowHandle);

/**
* `resizeWindow` resizes the window specified by its window handle to the given width and height.
* The respective window handle may be acquired via `getWindows` or `getActiveWindow`.
* @param windowHandle The window handle of the window to be resized.
* @param width The new width of the window.
* @param height The new height of the window.
* @return Returns a boolean indicating whether the window resize operation was successful.
*/
bool resizeWindow(const WindowHandle windowHandle, int width, int height);

MMRect getWindowRect(const WindowHandle windowHandle);

#endif