mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
app/internal/window: [Windows] properly handle WM_QUIT
First, don't filter on HWND in GetMessage and PeekMessage, lest thread-specific messages may get lost. See https://devblogs.microsoft.com/oldnewthing/20050209-00/?p=36493 Second, replace the dead status with the detection of WM_QUIT; it's what it's there for. May update gio#168 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -44,7 +44,6 @@ type window struct {
|
|||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
stage system.Stage
|
stage system.Stage
|
||||||
dead bool
|
|
||||||
pointerBtns pointer.Buttons
|
pointerBtns pointer.Buttons
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -86,7 +85,10 @@ func Main() {
|
|||||||
func NewWindow(window Callbacks, opts *Options) error {
|
func NewWindow(window Callbacks, opts *Options) error {
|
||||||
cerr := make(chan error)
|
cerr := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
// Call win32 API from a single OS thread.
|
// GetMessage and PeekMessage can filter on a window HWND, but
|
||||||
|
// then thread-specific messages such as WM_QUIT are ignored.
|
||||||
|
// Instead lock the thread so window messages arrive through
|
||||||
|
// unfiltered GetMessage calls.
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
w, err := createNativeWindow(opts)
|
w, err := createNativeWindow(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -263,7 +265,7 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
|
|||||||
case windows.WM_MOUSEWHEEL:
|
case windows.WM_MOUSEWHEEL:
|
||||||
w.scrollEvent(wParam, lParam)
|
w.scrollEvent(wParam, lParam)
|
||||||
case windows.WM_DESTROY:
|
case windows.WM_DESTROY:
|
||||||
w.dead = true
|
windows.PostQuitMessage(0)
|
||||||
case windows.WM_PAINT:
|
case windows.WM_PAINT:
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
case windows.WM_SIZE:
|
case windows.WM_SIZE:
|
||||||
@@ -363,18 +365,21 @@ func (w *window) scrollEvent(wParam, lParam uintptr) {
|
|||||||
// Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20060126-00/?p=32513/
|
// Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20060126-00/?p=32513/
|
||||||
func (w *window) loop() error {
|
func (w *window) loop() error {
|
||||||
msg := new(windows.Msg)
|
msg := new(windows.Msg)
|
||||||
for !w.dead {
|
loop:
|
||||||
|
for {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
anim := w.animating
|
anim := w.animating
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
if anim && !windows.PeekMessage(msg, w.hwnd, 0, 0, windows.PM_NOREMOVE) {
|
if anim && !windows.PeekMessage(msg, 0, 0, 0, windows.PM_NOREMOVE) {
|
||||||
w.draw(false)
|
w.draw(false)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
windows.GetMessage(msg, w.hwnd, 0, 0)
|
switch ret := windows.GetMessage(msg, 0, 0, 0); ret {
|
||||||
if msg.Message == windows.WM_QUIT {
|
case -1:
|
||||||
windows.PostQuitMessage(msg.WParam)
|
return errors.New("GetMessage failed")
|
||||||
break
|
case 0:
|
||||||
|
// WM_QUIT received.
|
||||||
|
break loop
|
||||||
}
|
}
|
||||||
windows.TranslateMessage(msg)
|
windows.TranslateMessage(msg)
|
||||||
windows.DispatchMessage(msg)
|
windows.DispatchMessage(msg)
|
||||||
|
|||||||
Reference in New Issue
Block a user