Skip to content

Commit c3ff8c1

Browse files
committed
Add window centering functionality to all platforms
Introduces a new Center() method to the Window class and exposes it via the C API. Implements platform-specific logic to center the window on the screen for Windows, macOS, Linux, and iOS. On Android and OpenHarmony, centering is not supported and is stubbed with warnings or no-ops.
1 parent 8be0cdb commit c3ff8c1

File tree

9 files changed

+116
-0
lines changed

9 files changed

+116
-0
lines changed

src/capi/window_c.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,14 @@ native_point_t native_window_get_position(native_window_t window) {
381381
return result;
382382
}
383383

384+
FFI_PLUGIN_EXPORT
385+
void native_window_center(native_window_t window) {
386+
if (!window)
387+
return;
388+
auto* win = static_cast<nativeapi::Window*>(window);
389+
win->Center();
390+
}
391+
384392
// Window properties
385393
FFI_PLUGIN_EXPORT
386394
void native_window_set_resizable(native_window_t window, bool resizable) {

src/capi/window_c.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ void native_window_set_position(native_window_t window, double x, double y);
163163
FFI_PLUGIN_EXPORT
164164
native_point_t native_window_get_position(native_window_t window);
165165

166+
FFI_PLUGIN_EXPORT
167+
void native_window_center(native_window_t window);
168+
166169
// Window properties
167170
FFI_PLUGIN_EXPORT
168171
void native_window_set_resizable(native_window_t window, bool resizable);

src/platform/android/window_android.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ Point Window::GetPosition() const {
278278
return Point{0, 0};
279279
}
280280

281+
void Window::Center() {
282+
// On Android, window positioning is not supported
283+
// Activities are automatically managed by the system
284+
ALOGW("Center not supported on Android - Activities are managed by the system");
285+
}
286+
281287
void Window::SetTitle(std::string title) {
282288
ALOGW("SetTitle not supported on Android (use Activity title)");
283289
}

src/platform/ios/window_ios.mm

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,27 @@
288288
return Point{static_cast<double>(origin.x), static_cast<double>(origin.y)};
289289
}
290290

291+
void Window::Center() {
292+
if (!pimpl_->ui_window_)
293+
return;
294+
295+
// Get the screen bounds
296+
UIScreen* screen = pimpl_->ui_window_.screen ?: [UIScreen mainScreen];
297+
CGRect screenBounds = screen.bounds;
298+
299+
// Get the current window size
300+
CGRect windowFrame = pimpl_->ui_window_.frame;
301+
302+
// Calculate center position
303+
CGFloat centerX = (screenBounds.size.width - windowFrame.size.width) / 2.0;
304+
CGFloat centerY = (screenBounds.size.height - windowFrame.size.height) / 2.0;
305+
306+
// Set the centered frame
307+
windowFrame.origin.x = centerX;
308+
windowFrame.origin.y = centerY;
309+
pimpl_->ui_window_.frame = windowFrame;
310+
}
311+
291312
void Window::SetTitle(std::string title) {
292313
// iOS windows don't have titles (use view controller title)
293314
if (pimpl_->ui_window_) {

src/platform/linux/window_linux.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,35 @@ Point Window::GetPosition() const {
314314
return point;
315315
}
316316

317+
void Window::Center() {
318+
if (!pimpl_->gdk_window_)
319+
return;
320+
321+
// Get the window size
322+
gint window_width, window_height;
323+
gdk_window_get_geometry(pimpl_->gdk_window_, nullptr, nullptr, &window_width, &window_height);
324+
325+
// Get the screen size
326+
GdkDisplay* display = gdk_window_get_display(pimpl_->gdk_window_);
327+
GdkMonitor* monitor = gdk_display_get_primary_monitor(display);
328+
if (!monitor) {
329+
// Fallback to first monitor if no primary monitor is found
330+
monitor = gdk_display_get_monitor(display, 0);
331+
}
332+
333+
if (monitor) {
334+
GdkRectangle geometry;
335+
gdk_monitor_get_geometry(monitor, &geometry);
336+
337+
// Calculate center position
338+
gint center_x = geometry.x + (geometry.width - window_width) / 2;
339+
gint center_y = geometry.y + (geometry.height - window_height) / 2;
340+
341+
// Move the window to center
342+
gdk_window_move(pimpl_->gdk_window_, center_x, center_y);
343+
}
344+
}
345+
317346
void Window::SetTitle(std::string title) {
318347
// GDK windows don't have titles directly - this would be set on the GTK
319348
// widget For now, provide stub implementation

src/platform/macos/window_macos.mm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@
283283
return point;
284284
}
285285

286+
void Window::Center() {
287+
if (!pimpl_->ns_window_)
288+
return;
289+
290+
// Use NSWindow's center method which automatically centers on the main screen
291+
[pimpl_->ns_window_ center];
292+
}
293+
286294
void Window::SetTitle(std::string title) {
287295
[pimpl_->ns_window_ setTitle:[NSString stringWithUTF8String:title.c_str()]];
288296
}

src/platform/ohos/window_ohos.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,14 @@ Point Window::GetPosition() const {
260260
return Point{0, 0};
261261
}
262262

263+
void Window::Center() {
264+
// On OpenHarmony, window positioning is not supported
265+
// Abilities are automatically managed by the system
266+
if (pimpl_->native_window_) {
267+
// Center not supported on OpenHarmony - Abilities are managed by the system
268+
}
269+
}
270+
263271
void Window::SetTitle(std::string title) {
264272
// SetTitle not supported on OpenHarmony (use Ability title)
265273
}

src/platform/windows/window_windows.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,30 @@ Point Window::GetPosition() const {
436436
return point;
437437
}
438438

439+
void Window::Center() {
440+
if (!pimpl_->hwnd_)
441+
return;
442+
443+
// Get the current window size
444+
RECT windowRect;
445+
GetWindowRect(pimpl_->hwnd_, &windowRect);
446+
int windowWidth = windowRect.right - windowRect.left;
447+
int windowHeight = windowRect.bottom - windowRect.top;
448+
449+
// Get the monitor that the window is currently on
450+
HMONITOR monitor = MonitorFromWindow(pimpl_->hwnd_, MONITOR_DEFAULTTONEAREST);
451+
MONITORINFO mi = {sizeof(mi)};
452+
GetMonitorInfo(monitor, &mi);
453+
454+
// Calculate the center position on the monitor's work area
455+
int centerX = mi.rcWork.left + (mi.rcWork.right - mi.rcWork.left - windowWidth) / 2;
456+
int centerY = mi.rcWork.top + (mi.rcWork.bottom - mi.rcWork.top - windowHeight) / 2;
457+
458+
// Set the window position to center
459+
SetWindowPos(pimpl_->hwnd_, nullptr, centerX, centerY, 0, 0,
460+
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
461+
}
462+
439463
void Window::SetTitle(std::string title) {
440464
if (pimpl_->hwnd_) {
441465
std::wstring wtitle = StringToWString(title);

src/window.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,15 @@ class Window : public NativeObjectProvider {
462462
*/
463463
Point GetPosition() const;
464464

465+
/**
466+
* @brief Centers the window on the screen.
467+
*
468+
* Moves the window to the center of the primary display. The window
469+
* will be positioned so that its center point aligns with the center
470+
* of the screen.
471+
*/
472+
void Center();
473+
465474
/**
466475
* @brief Sets the text displayed in the window's title bar.
467476
*

0 commit comments

Comments
 (0)