From cd51650f1a9e996cddc1d1616ed40a363aeab587 Mon Sep 17 00:00:00 2001 From: Pantazis Vouzaxakis Date: Wed, 7 Aug 2024 00:17:41 +0200 Subject: [PATCH 1/3] Add support for client bounds without NonClient Area on Windows --- Sources/windows/main.cc | 32 +++++++++++++++++++++++++------- index.d.ts | 10 ++++++++++ index.test-d.ts | 6 ++++-- readme.md | 5 +++++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/Sources/windows/main.cc b/Sources/windows/main.cc index 1611cba..57862fa 100644 --- a/Sources/windows/main.cc +++ b/Sources/windows/main.cc @@ -181,10 +181,13 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf return env.Null(); } - RECT lpRect; - BOOL rectResult = GetWindowRect(hwnd, &lpRect); + RECT lpWinRect; + BOOL rectWinResult = GetWindowRect(hwnd, &lpWinRect); - if (rectResult == 0) { + RECT lpClientRect; + BOOL rectClientResult = GetClientRect(hwnd, &lpClientRect); + + if (rectWinResult == 0 || rectClientResult == 0 ) { return env.Null(); } @@ -194,12 +197,26 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf owner.Set(Napi::String::New(env, "path"), ownerInfo.path); owner.Set(Napi::String::New(env, "name"), ownerInfo.name); + // bounds window Napi::Object bounds = Napi::Object::New(env); - bounds.Set(Napi::String::New(env, "x"), lpRect.left); - bounds.Set(Napi::String::New(env, "y"), lpRect.top); - bounds.Set(Napi::String::New(env, "width"), lpRect.right - lpRect.left); - bounds.Set(Napi::String::New(env, "height"), lpRect.bottom - lpRect.top); + bounds.Set(Napi::String::New(env, "x"), lpWinRect.left); + bounds.Set(Napi::String::New(env, "y"), lpWinRect.top); + bounds.Set(Napi::String::New(env, "width"), lpWinRect.right - lpWinRect.left); + bounds.Set(Napi::String::New(env, "height"), lpWinRect.bottom - lpWinRect.top); + + // bounds client + POINT rectTopLeft = {lpClientRect.left, lpClientRect.top}; + ClientToScreen(hwnd, &rectTopLeft); + POINT rectBottomRight = {lpClientRect.right, lpClientRect.bottom}; + ClientToScreen(hwnd, &rectBottomRight); + + Napi::Object boundsClient = Napi::Object::New(env); + + boundsClient.Set(Napi::String::New(env, "x"), rectTopLeft.x); + boundsClient.Set(Napi::String::New(env, "y"), rectTopLeft.y); + boundsClient.Set(Napi::String::New(env, "width"), rectBottomRight.x - rectTopLeft.x); + boundsClient.Set(Napi::String::New(env, "height"), rectBottomRight.y - rectTopLeft.y); Napi::Object activeWinObj = Napi::Object::New(env); @@ -208,6 +225,7 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf activeWinObj.Set(Napi::String::New(env, "title"), getWindowTitle(hwnd)); activeWinObj.Set(Napi::String::New(env, "owner"), owner); activeWinObj.Set(Napi::String::New(env, "bounds"), bounds); + activeWinObj.Set(Napi::String::New(env, "boundsClient"), boundsClient); activeWinObj.Set(Napi::String::New(env, "memoryUsage"), memoryCounter.WorkingSetSize); return activeWinObj; diff --git a/index.d.ts b/index.d.ts index 8acef88..2182cf7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -95,6 +95,16 @@ export type LinuxResult = { export type WindowsResult = { platform: 'windows'; + + /** + Client position and size. + */ + boundsClient: { + x: number; + y: number; + width: number; + height: number; + }; } & BaseResult; export type Result = MacOSResult | LinuxResult | WindowsResult; diff --git a/index.test-d.ts b/index.test-d.ts index 1021d7e..50faeda 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -39,9 +39,11 @@ if (result) { expectType(result.url); } else if (result.platform === 'linux') { expectType(result); - expectError(result.owner.bundleId); } else { expectType(result); - expectError(result.owner.bundleId); + expectType(result.boundsClient.x); + expectType(result.boundsClient.y); + expectType(result.boundsClient.width); + expectType(result.boundsClient.height); } } diff --git a/readme.md b/readme.md index 475b17c..b1f7f72 100644 --- a/readme.md +++ b/readme.md @@ -80,6 +80,11 @@ Returns a `Promise` with the result, or `Promise` if there is - `y` *(number)* - `width` *(number)* - `height` *(number)* +- `boundsClient` *(Object)* - Client position and size without Nonclient Area *(Windows only)* + - `x` *(number)* + - `y` *(number)* + - `width` *(number)* + - `height` *(number)* - `owner` *(Object)* - App that owns the window - `name` *(string)* - Name of the app - `processId` *(number)* - Process identifier From c16e6f3e1298823fe3858e610ca2fe84c443e0b0 Mon Sep 17 00:00:00 2001 From: Pantazis Vouzaxakis Date: Wed, 7 Aug 2024 21:58:12 +0200 Subject: [PATCH 2/3] Rename clientBound to contentBounds and update description --- Sources/windows/main.cc | 16 ++++++++-------- index.d.ts | 6 +++--- index.test-d.ts | 8 ++++---- readme.md | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Sources/windows/main.cc b/Sources/windows/main.cc index 57862fa..2f4f469 100644 --- a/Sources/windows/main.cc +++ b/Sources/windows/main.cc @@ -197,7 +197,7 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf owner.Set(Napi::String::New(env, "path"), ownerInfo.path); owner.Set(Napi::String::New(env, "name"), ownerInfo.name); - // bounds window + // bounds window Napi::Object bounds = Napi::Object::New(env); bounds.Set(Napi::String::New(env, "x"), lpWinRect.left); @@ -205,18 +205,18 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf bounds.Set(Napi::String::New(env, "width"), lpWinRect.right - lpWinRect.left); bounds.Set(Napi::String::New(env, "height"), lpWinRect.bottom - lpWinRect.top); - // bounds client + // bounds content POINT rectTopLeft = {lpClientRect.left, lpClientRect.top}; ClientToScreen(hwnd, &rectTopLeft); POINT rectBottomRight = {lpClientRect.right, lpClientRect.bottom}; ClientToScreen(hwnd, &rectBottomRight); - Napi::Object boundsClient = Napi::Object::New(env); + Napi::Object contentBounds = Napi::Object::New(env); - boundsClient.Set(Napi::String::New(env, "x"), rectTopLeft.x); - boundsClient.Set(Napi::String::New(env, "y"), rectTopLeft.y); - boundsClient.Set(Napi::String::New(env, "width"), rectBottomRight.x - rectTopLeft.x); - boundsClient.Set(Napi::String::New(env, "height"), rectBottomRight.y - rectTopLeft.y); + contentBounds.Set(Napi::String::New(env, "x"), rectTopLeft.x); + contentBounds.Set(Napi::String::New(env, "y"), rectTopLeft.y); + contentBounds.Set(Napi::String::New(env, "width"), rectBottomRight.x - rectTopLeft.x); + contentBounds.Set(Napi::String::New(env, "height"), rectBottomRight.y - rectTopLeft.y); Napi::Object activeWinObj = Napi::Object::New(env); @@ -225,7 +225,7 @@ Napi::Value getWindowInformation(const HWND &hwnd, const Napi::CallbackInfo &inf activeWinObj.Set(Napi::String::New(env, "title"), getWindowTitle(hwnd)); activeWinObj.Set(Napi::String::New(env, "owner"), owner); activeWinObj.Set(Napi::String::New(env, "bounds"), bounds); - activeWinObj.Set(Napi::String::New(env, "boundsClient"), boundsClient); + activeWinObj.Set(Napi::String::New(env, "contentBounds"), contentBounds); activeWinObj.Set(Napi::String::New(env, "memoryUsage"), memoryCounter.WorkingSetSize); return activeWinObj; diff --git a/index.d.ts b/index.d.ts index 2182cf7..78338d0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -97,9 +97,9 @@ export type WindowsResult = { platform: 'windows'; /** - Client position and size. - */ - boundsClient: { + Content position and size without Nonclient Area + */ + contentBounds: { x: number; y: number; width: number; diff --git a/index.test-d.ts b/index.test-d.ts index 50faeda..7ba88dc 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -41,9 +41,9 @@ if (result) { expectType(result); } else { expectType(result); - expectType(result.boundsClient.x); - expectType(result.boundsClient.y); - expectType(result.boundsClient.width); - expectType(result.boundsClient.height); + expectType(result.contentBounds.x); + expectType(result.contentBounds.y); + expectType(result.contentBounds.width); + expectType(result.contentBounds.height); } } diff --git a/readme.md b/readme.md index b1f7f72..c8c2a8e 100644 --- a/readme.md +++ b/readme.md @@ -80,7 +80,7 @@ Returns a `Promise` with the result, or `Promise` if there is - `y` *(number)* - `width` *(number)* - `height` *(number)* -- `boundsClient` *(Object)* - Client position and size without Nonclient Area *(Windows only)* +- `contentBounds` *(Object)* - Client position and size without Nonclient Area *(Windows only)* - `x` *(number)* - `y` *(number)* - `width` *(number)* From 600c6b83441084c6403951bca0a56dfbf0c1dcf1 Mon Sep 17 00:00:00 2001 From: Pantazis Vouzaxakis Date: Fri, 9 Aug 2024 22:22:13 +0200 Subject: [PATCH 3/3] Adjust contentBounds description on readme and doc --- index.d.ts | 2 +- readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 78338d0..3ceebd6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -97,7 +97,7 @@ export type WindowsResult = { platform: 'windows'; /** - Content position and size without Nonclient Area + Window content position and size, which excludes the title bar, menu bar, and frame. */ contentBounds: { x: number; diff --git a/readme.md b/readme.md index c8c2a8e..d67c774 100644 --- a/readme.md +++ b/readme.md @@ -80,7 +80,7 @@ Returns a `Promise` with the result, or `Promise` if there is - `y` *(number)* - `width` *(number)* - `height` *(number)* -- `contentBounds` *(Object)* - Client position and size without Nonclient Area *(Windows only)* +- `contentBounds` *(Object)* - Window content position and size, which excludes the title bar, menu bar, and frame *(Windows only)* - `x` *(number)* - `y` *(number)* - `width` *(number)*