From d14ee7f3ddc76755495b42730124f8c1be66dd15 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 11 Jun 2014 10:01:55 -0400 Subject: [PATCH] Fixed the implementation of sysData.center() on Windows to be thread-safe; also added center() to the _xSysData interface. --- sysdata.go | 1 + sysdata_windows.go | 36 +++++++++++++++++++++++++++++++++--- zconstants_windows_386.go | 2 +- zconstants_windows_amd64.go | 2 +- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/sysdata.go b/sysdata.go index 9e6e384..dec0e27 100644 --- a/sysdata.go +++ b/sysdata.go @@ -41,6 +41,7 @@ var _xSysData interface { len() int setAreaSize(int, int) repaintAll() + center() } = &sysData{} // this line will error if there's an inconsistency // signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task. diff --git a/sysdata_windows.go b/sysdata_windows.go index 76c068c..99dbad8 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -515,6 +515,7 @@ func (s *sysData) setWindowSize(width int, height int) error { return fmt.Errorf("error getting upper-left of window for resize: %v", r.err) } // 0 because (0,0) is top-left so no winheight + // TODO this needs to be run on uitask! err := s.setRect(int(rect.left), int(rect.top), width, height, 0) if err != nil { return fmt.Errorf("error actually resizing window: %v", err) @@ -688,12 +689,41 @@ func (s *sysData) repaintAll() { func (s *sysData) center() { var ws _RECT - _getWindowRect.Call(uintptr(s.hwnd), uintptr(unsafe.Pointer(&ws))) - dw, _, _ := _getSystemMetrics.Call(_SM_CXFULLSCREEN) - dh, _, _ := _getSystemMetrics.Call(_SM_CYFULLSCREEN) + + ret := make(chan uiret) + defer close(ret) + uitask <- &uimsg{ + call: _getWindowRect, + p: []uintptr{ + uintptr(s.hwnd), + uintptr(unsafe.Pointer(&ws)), + }, + ret: ret, + } + r := <-ret + if r.ret == 0 { + panic(fmt.Errorf("error getting window rect for sysData.center(): %v", r.err)) + } + // TODO should this be using the monitor functions instead? http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx + // error returns from GetSystemMetrics() is meaningless because the return value, 0, is still valid + uitask <- &uimsg{ + call: _getSystemMetrics, + p: []uintptr{uintptr(_SM_CXFULLSCREEN)}, + ret: ret, + } + r = <-ret + dw := r.ret + uitask <- &uimsg{ + call: _getSystemMetrics, + p: []uintptr{uintptr(_SM_CYFULLSCREEN)}, + ret: ret, + } + r = <-ret + dh := r.ret ww := ws.right - ws.left wh := ws.bottom - ws.top wx := (int32(dw) / 2) - (ww / 2) wy := (int32(dh) / 2) - (wh / 2) + // TODO this needs to be run on uitask! s.setRect(int(wx), int(wy), int(ww), int(wh), 0) } diff --git a/zconstants_windows_386.go b/zconstants_windows_386.go index 1db9e22..f19d39a 100644 --- a/zconstants_windows_386.go +++ b/zconstants_windows_386.go @@ -80,8 +80,8 @@ const _SIF_POS = 4 const _SIF_RANGE = 1 const _SIF_TRACKPOS = 16 const _SM_CXDOUBLECLK = 36 -const _SM_CYDOUBLECLK = 37 const _SM_CXFULLSCREEN = 16 +const _SM_CYDOUBLECLK = 37 const _SM_CYFULLSCREEN = 17 const _SPI_GETNONCLIENTMETRICS = 41 const _SRCCOPY = 13369376 diff --git a/zconstants_windows_amd64.go b/zconstants_windows_amd64.go index a8bed71..ec55813 100644 --- a/zconstants_windows_amd64.go +++ b/zconstants_windows_amd64.go @@ -80,8 +80,8 @@ const _SIF_POS = 4 const _SIF_RANGE = 1 const _SIF_TRACKPOS = 16 const _SM_CXDOUBLECLK = 36 -const _SM_CYDOUBLECLK = 37 const _SM_CXFULLSCREEN = 16 +const _SM_CYDOUBLECLK = 37 const _SM_CYFULLSCREEN = 17 const _SPI_GETNONCLIENTMETRICS = 41 const _SRCCOPY = 13369376