Creating a window with options app.MinSize
and app.MaxSize
set to the same values will make the window behave oddly. The maximize button is still clickable and when clicked, the window randomly moves to the left-top corner of the screen while retaining the same size and its maximized state (the maximize icon will update to its counterpart icon until clicked again or the window is manually moved). Additionally, when hovering over the window's frame, the cursor displays the resize icon which, as far as I've tested, doesn't happen if a win32 window is properly set up to not allow resizing.
So my suggestion is to either make it so when app.MinSize
and app.MaxSize
are set to the same values, correctly mark the window as unresizable and unmaximizable; Or, add a new option to achieve this goal.
Below example code reproduces the issue:
package main
import (
"log"
"os"
"gioui.org/app"
"gioui.org/op"
"gioui.org/widget/material"
)
func main() {
go func() {
window := new(app.Window)
window.Option(
app.MinSize(800, 600),
app.MaxSize(800, 600),
)
err := run(window)
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
app.Main()
}
func run(window *app.Window) error {
theme := material.NewTheme()
var ops op.Ops
for {
switch e := window.Event().(type) {
case app.DestroyEvent:
return e.Err
case app.FrameEvent:
gtx := app.NewContext(&ops, e)
title := material.H1(theme, "Test 123")
title.Layout(gtx)
e.Frame(gtx.Ops)
}
}
}
I managed to find a temporary workaround to achieve the effect I want by modifying the HWND on a
Win32ViewEvent
. I feel like this is quite a hack though as it's modifying the window AFTER it's created and not intercepting the window creation itself, so it would still be much better to have that sorted out in the library. Here is the code in case it's of any help:package main import ( "log" "os" "gioui.org/app" "gioui.org/op" "gioui.org/widget/material" "golang.org/x/sys/windows" ) const ( GWL_STYLE = -16 WS_BORDER = 0x00800000 WS_CAPTION = 0x00C00000 WS_SYSMENU = 0x00080000 WS_MINIMIZEBOX = 0x00020000 WS_VISIBLE = 0x10000000 SWP_NOSIZE = 0x0001 SWP_NOMOVE = 0x0002 SWP_FRAMECHANGED = 0x0020 ) var ( user32 = windows.NewLazySystemDLL("user32.dll") procSetWindowLongPtr = user32.NewProc("SetWindowLongPtrW") procSetWindowPos = user32.NewProc("SetWindowPos") ) func setWindowLongPtr(hWnd uintptr, index int, newLong uintptr) { procSetWindowLongPtr.Call(hWnd, uintptr(index), newLong) } func setWindowPos(hWnd uintptr) { procSetWindowPos.Call(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED) } func main() { go func() { window := new(app.Window) window.Option( app.MinSize(400, 300), app.MaxSize(400, 300), ) err := run(window) if err != nil { log.Fatal(err) } os.Exit(0) }() app.Main() } func run(window *app.Window) error { theme := material.NewTheme() var ops op.Ops for { switch e := window.Event().(type) { case app.DestroyEvent: return e.Err case app.Win32ViewEvent: log.Println(e.HWND) window.Run(func() { setWindowLongPtr(e.HWND, GWL_STYLE, WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE) setWindowPos(e.HWND) }) case app.FrameEvent: gtx := app.NewContext(&ops, e) title := material.H1(theme, "Test 123") title.Layout(gtx) e.Frame(gtx.Ops) } } }
Related: https://github.com/gioui/gio/pull/143
It seems to me the maximize button should be hidden whenever MaxSize != {0,0}. Further, if MinSize == MaxSize the frame resizing should be disabled, as you suggest.
Would you like to attempt a patch? window.Configure is probably the right place to edit. It's ok if the change only works for Windows.
I agree, I'm going to try to submit a patch.
I submitted a patch here: https://lists.sr.ht/~eliasnaur/gio-patches/patches/57210
I'm not very experienced with git so I'm not sure if I did it right though.. Please let me know if there's anything wrong with it.
vasijob225 referenced this ticket in commit 95354d8.