From 14e9dad4a722bd48de61327455767adb7f0f60f3 Mon Sep 17 00:00:00 2001 From: kkeybbs Date: Sat, 21 Jun 2025 09:21:04 +0800 Subject: [PATCH 1/3] add support to hidden minimize and maximize button on macos and windows #143 --- app/os.go | 6 ++++++ app/os_macos.go | 15 +++++++++++++-- app/os_windows.go | 10 ++++++++++ app/window.go | 18 ++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/os.go b/app/os.go index 79adaafdc..528de0857 100644 --- a/app/os.go +++ b/app/os.go @@ -45,6 +45,12 @@ type Config struct { CustomRenderer bool // Decorated reports whether window decorations are provided automatically. Decorated bool + + // MinimizeButtonHidden hide the window's minimize button (only works for windows and macOS) + MinimizeButtonHidden bool + // MaximizeButtonHidden hide the window's maximize button (only works for windows and macOS) + MaximizeButtonHidden bool + // Focused reports whether has the keyboard focus. Focused bool // decoHeight is the height of the fallback decoration for platforms such diff --git a/app/os_macos.go b/app/os_macos.go index 3a01ef251..63c329779 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -495,8 +495,11 @@ func (w *window) Configure(options []Option) { C.setWindowTitleVisibility(window, titleVis) C.setWindowStyleMask(window, mask) C.setWindowStandardButtonHidden(window, C.NSWindowCloseButton, barTrans) - C.setWindowStandardButtonHidden(window, C.NSWindowMiniaturizeButton, barTrans) - C.setWindowStandardButtonHidden(window, C.NSWindowZoomButton, barTrans) + // no decorated or hide minimize and maximize buttons + w.config.MinimizeButtonHidden = cnf.MinimizeButtonHidden + w.config.MaximizeButtonHidden = cnf.MaximizeButtonHidden + C.setWindowStandardButtonHidden(window, C.NSWindowMiniaturizeButton, toInt(!cnf.Decorated || cnf.MinimizeButtonHidden)) + C.setWindowStandardButtonHidden(window, C.NSWindowZoomButton, toInt(!cnf.Decorated || cnf.MaximizeButtonHidden)) // When toggling the titlebar, the layer doesn't update its frame // until the next resize. Force it. C.resetLayerFrame(w.view) @@ -1161,6 +1164,14 @@ func convertMods(mods C.NSUInteger) key.Modifiers { return kmods } +// toInt golang bool to C.int +func toInt(v bool) C.int { + if v { + return C.int(C.YES) + } + return C.int(C.NO) +} + func (AppKitViewEvent) implementsViewEvent() {} func (AppKitViewEvent) ImplementsEvent() {} func (a AppKitViewEvent) Valid() bool { diff --git a/app/os_windows.go b/app/os_windows.go index f601d910f..e76f696aa 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -758,6 +758,16 @@ func (w *window) Configure(options []Option) { swpStyle |= windows.SWP_NOMOVE | windows.SWP_NOSIZE showMode = windows.SW_SHOWMAXIMIZED } + if w.config.MinimizeButtonHidden { + style &^= windows.WS_MINIMIZEBOX + } else { + style |= windows.WS_MINIMIZEBOX + } + if w.config.MaximizeButtonHidden { + style &^= windows.WS_MAXIMIZEBOX + } else { + style |= windows.WS_MAXIMIZEBOX + } // Disable maximize button if MaxSize is set. if cnf.MaxSize != (image.Point{X: 0, Y: 0}) { diff --git a/app/window.go b/app/window.go index 3953600d4..9cd9a4e7c 100644 --- a/app/window.go +++ b/app/window.go @@ -969,6 +969,24 @@ func Decorated(enabled bool) Option { } } +// MinimizeButtonHidden hides the minimize button of the window. +// +// MinimizeButtonHidden is supported on Windows and macOS. +func MinimizeButtonHidden(hidden bool) Option { + return func(_ unit.Metric, cnf *Config) { + cnf.MinimizeButtonHidden = hidden + } +} + +// MaximizeButtonHidden hides the maximize button of the window. +// +// MaximizeButtonHidden is supported on Windows and macOS. +func MaximizeButtonHidden(hidden bool) Option { + return func(_ unit.Metric, cnf *Config) { + cnf.MaximizeButtonHidden = hidden + } +} + // flushEvent is sent to detect when the user program // has completed processing of all prior events. Its an // [io/event.Event] but only for internal use. From babf85123b1bfda01f965efe7ba7e4410622b023 Mon Sep 17 00:00:00 2001 From: eastjiao Date: Tue, 24 Jun 2025 13:13:57 +0800 Subject: [PATCH 2/3] no hidding maximize button for app.MaxSize on Windows #143 --- app/os_windows.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/os_windows.go b/app/os_windows.go index e76f696aa..5ecc55b5d 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -710,6 +710,8 @@ func (w *window) Configure(options []Option) { w.config.Decorated = cnf.Decorated w.config.MinSize = cnf.MinSize w.config.MaxSize = cnf.MaxSize + w.config.MinimizeButtonHidden = cnf.MinimizeButtonHidden + w.config.MaximizeButtonHidden = cnf.MaximizeButtonHidden windows.SetWindowText(w.hwnd, cnf.Title) style := windows.GetWindowLong(w.hwnd, windows.GWL_STYLE) @@ -771,7 +773,9 @@ func (w *window) Configure(options []Option) { // Disable maximize button if MaxSize is set. if cnf.MaxSize != (image.Point{X: 0, Y: 0}) { - style &^= windows.WS_MAXIMIZEBOX + // On Windows, clicking maximize button will maximize the window to its' max size, so we don't hide the button. + // style &^= windows.WS_MAXIMIZEBOX + // Disable window resizing if MinSize and MaxSize are equal. if cnf.MinSize == cnf.MaxSize { style &^= windows.WS_THICKFRAME From 83a642f1e9517bde044414212d3c5c4c195090af Mon Sep 17 00:00:00 2001 From: kkeybbs Date: Mon, 30 Jun 2025 21:20:06 +0800 Subject: [PATCH 3/3] #143 clicking maximize button will maximize the window to its' max size, so we don't hide the button --- app/os_windows.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/os_windows.go b/app/os_windows.go index 5ecc55b5d..6f629b8a6 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -772,14 +772,8 @@ func (w *window) Configure(options []Option) { } // Disable maximize button if MaxSize is set. - if cnf.MaxSize != (image.Point{X: 0, Y: 0}) { - // On Windows, clicking maximize button will maximize the window to its' max size, so we don't hide the button. - // style &^= windows.WS_MAXIMIZEBOX - - // Disable window resizing if MinSize and MaxSize are equal. - if cnf.MinSize == cnf.MaxSize { - style &^= windows.WS_THICKFRAME - } + if cnf.MaxSize != (image.Point{X: 0, Y: 0}) && cnf.MinSize == cnf.MaxSize { + style &^= windows.WS_THICKFRAME } // Note: these invocation all trigger the windows callback method which may process a pending system.ActionCenter