From 9835cd5996424ecdf9499fa46f9e7d5574f08e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A5re=20Vatne?= Date: Wed, 10 Nov 2021 13:56:08 +0100 Subject: [PATCH] app: add Window.Maximize and Center, add Windows implementation Signed-off-by: Jan Kare Vatne --- app/internal/windows/windows.go | 1 + app/os.go | 5 +++++ app/os_android.go | 6 +++++ app/os_ios.go | 6 +++++ app/os_js.go | 6 +++++ app/os_macos.go | 6 +++++ app/os_wayland.go | 6 +++++ app/os_windows.go | 40 +++++++++++++++++++++++++++++++++ app/os_x11.go | 6 +++++ app/window.go | 16 +++++++++++++ 10 files changed, 98 insertions(+) diff --git a/app/internal/windows/windows.go b/app/internal/windows/windows.go index e8dced0b..e695139c 100644 --- a/app/internal/windows/windows.go +++ b/app/internal/windows/windows.go @@ -200,6 +200,7 @@ const ( WS_CLIPCHILDREN = 0x00010000 WS_CLIPSIBLINGS = 0x04000000 + WS_MAXIMIZE = 0x01000000 WS_VISIBLE = 0x10000000 WS_OVERLAPPED = 0x00000000 WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | diff --git a/app/os.go b/app/os.go index 338797e3..160267ff 100644 --- a/app/os.go +++ b/app/os.go @@ -149,6 +149,11 @@ type driver interface { Close() // Wakeup wakes up the event loop and sends a WakeupEvent. Wakeup() + + // Maximize will make the window as large as possible, but keep the frame decorations. + Maximize() + // Center will place the window at monitor center. + Center() } type windowRendezvous struct { diff --git a/app/os_android.go b/app/os_android.go index dc410380..d3354621 100644 --- a/app/os_android.go +++ b/app/os_android.go @@ -922,6 +922,12 @@ func setNavigationColor(env *C.JNIEnv, view C.jobject, color color.NRGBA) { // Close the window. Not implemented for Android. func (w *window) Close() {} +// Maximize maximizes the window. Not implemented for Android. +func (w *window) Maximize() {} + +// Center the window. Not implemented for Android. +func (w *window) Center() {} + // runOnMain runs a function on the Java main thread. func runOnMain(f func(env *C.JNIEnv)) { go func() { diff --git a/app/os_ios.go b/app/os_ios.go index 54a81468..2939b3b0 100644 --- a/app/os_ios.go +++ b/app/os_ios.go @@ -331,6 +331,12 @@ func (w *window) SetInputHint(_ key.InputHint) {} // Close the window. Not implemented for iOS. func (w *window) Close() {} +// Maximize the window. Not implemented for iOS. +func (w *window) Maximize() {} + +// Center the window. Not implemented for iOS. +func (w *window) Center() {} + func newWindow(win *callbacks, options []Option) error { mainWindow.in <- windowAndConfig{win, options} return <-mainWindow.errs diff --git a/app/os_js.go b/app/os_js.go index 4950e501..5b1388cf 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -566,6 +566,12 @@ func (w *window) SetInputHint(mode key.InputHint) { // Close the window. Not implemented for js. func (w *window) Close() {} +// Maximize the window. Not implemented for js. +func (w *window) Maximize() {} + +// Center the window. Not implemented for js. +func (w *window) Center() {} + func (w *window) resize() { w.scale = float32(w.window.Get("devicePixelRatio").Float()) diff --git a/app/os_macos.go b/app/os_macos.go index 1ee4df7e..de4e0b34 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -291,6 +291,12 @@ func (w *window) Close() { C.closeWindow(w.window) } +// Maximize the window. Not implemented for macos. +func (w *window) Maximize() {} + +// Center the window. Not implemented for macos. +func (w *window) Center() {} + func (w *window) setStage(stage system.Stage) { if stage == w.stage { return diff --git a/app/os_wayland.go b/app/os_wayland.go index 8f03f6a3..84d76945 100644 --- a/app/os_wayland.go +++ b/app/os_wayland.go @@ -1481,6 +1481,12 @@ func (w *window) SetInputHint(_ key.InputHint) {} // Close the window. Not implemented for Wayland. func (w *window) Close() {} +// Maximize the window. Not implemented for Wayland. +func (w *window) Maximize() {} + +// Center the window. Not implemented for Wayland. +func (w *window) Center() {} + func (w *window) NewContext() (context, error) { var firstErr error if f := newWaylandVulkanContext; f != nil { diff --git a/app/os_windows.go b/app/os_windows.go index f8d22565..ed3ad447 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -539,6 +539,46 @@ func (w *window) Configure(options []Option) { } } +// Maximize the window. It will have no effect when in fullscreen mode. +func (w *window) Maximize() { + if w.config.Mode == Fullscreen { + return + } + style := windows.GetWindowLong(w.hwnd) + windows.SetWindowLong(w.hwnd, windows.GWL_STYLE, style|windows.WS_OVERLAPPEDWINDOW|windows.WS_MAXIMIZE) + mi := windows.GetMonitorInfo(w.hwnd) + windows.SetWindowPos(w.hwnd, 0, + mi.Monitor.Left, mi.Monitor.Top, + mi.Monitor.Right-mi.Monitor.Left, + mi.Monitor.Bottom-mi.Monitor.Top, + windows.SWP_NOOWNERZORDER|windows.SWP_FRAMECHANGED, + ) +} + +// Center will place window at monitor center. +func (w *window) Center() { + // Make sure that the window is sizeable + style := windows.GetWindowLong(w.hwnd) & (^uintptr(windows.WS_MAXIMIZE)) + windows.SetWindowLong(w.hwnd, windows.GWL_STYLE, style|windows.WS_OVERLAPPEDWINDOW) + + // Find with/height including the window decorations. + wr := windows.Rect{ + Right: int32(w.config.Size.X), + Bottom: int32(w.config.Size.Y), + } + dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW) + dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE) + windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle) + width := wr.Right - wr.Left + height := wr.Bottom - wr.Top + + // Move to center of current monitor + mi := windows.GetMonitorInfo(w.hwnd).Monitor + x := mi.Left + (mi.Right-mi.Left-width)/2 + y := mi.Top + (mi.Bottom-mi.Top-height)/2 + windows.MoveWindow(w.hwnd, x, y, width, height, true) +} + func (w *window) SetWindowMode(mode WindowMode) { // https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353 switch mode { diff --git a/app/os_x11.go b/app/os_x11.go index 1a9115ca..6687c674 100644 --- a/app/os_x11.go +++ b/app/os_x11.go @@ -295,6 +295,12 @@ func (w *x11Window) Close() { C.XSendEvent(w.x, w.xw, C.False, C.NoEventMask, &xev) } +// Maximize the window. Not implemented for x11. +func (w *x11Window) Maximize() {} + +// Center the window. Not implemented for x11. +func (w *x11Window) Center() {} + var x11OneByte = make([]byte, 1) func (w *x11Window) Wakeup() { diff --git a/app/window.go b/app/window.go index 9540d650..58e24dc2 100644 --- a/app/window.go +++ b/app/window.go @@ -311,6 +311,22 @@ func (w *Window) Close() { }) } +// Maximize the window. +// Note: only implemented on Windows. +func (w *Window) Maximize() { + w.driverDefer(func(d driver) { + d.Maximize() + }) +} + +// Center the window. +// Note: only implemented on Windows. +func (w *Window) Center() { + w.driverDefer(func(d driver) { + d.Center() + }) +} + // Run f in the same thread as the native window event loop, and wait for f to // return or the window to close. Run is guaranteed not to deadlock if it is // invoked during the handling of a ViewEvent, system.FrameEvent,