Fixed the infinite loop on Tab control dialog message bug(s) on the Windows backend.
This commit is contained in:
parent
2c8bb7bc6d
commit
acbe70b4e5
|
@ -14,6 +14,7 @@ import "C"
|
|||
type container struct {
|
||||
containerbase
|
||||
hwnd C.HWND
|
||||
nchildren int
|
||||
}
|
||||
|
||||
type sizing struct {
|
||||
|
@ -45,12 +46,12 @@ func newContainer(control Control) *container {
|
|||
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in container (%p) differ", hwnd, c.hwnd))
|
||||
}
|
||||
c.child = control
|
||||
c.child.setParent(&controlParent{c.hwnd})
|
||||
c.child.setParent(&controlParent{c})
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *container) setParent(p *controlParent) {
|
||||
C.controlSetParent(c.hwnd, p.hwnd)
|
||||
func (c *container) setParent(hwnd C.HWND) {
|
||||
C.controlSetParent(c.hwnd, hwnd)
|
||||
}
|
||||
|
||||
// this is needed because Windows won't move/resize a child window for us
|
||||
|
|
|
@ -11,11 +11,12 @@ type controlPrivate interface {
|
|||
}
|
||||
|
||||
type controlParent struct {
|
||||
hwnd C.HWND
|
||||
c *container
|
||||
}
|
||||
|
||||
func basesetParent(c controlPrivate, p *controlParent) {
|
||||
C.controlSetParent(c.hwnd(), p.hwnd)
|
||||
C.controlSetParent(c.hwnd(), p.c.hwnd)
|
||||
p.c.nchildren++
|
||||
}
|
||||
|
||||
// don't specify basepreferredSize; it is custom on ALL controls
|
||||
|
|
|
@ -57,7 +57,8 @@ func (l *label) settextlen(len C.LONG) {
|
|||
}
|
||||
|
||||
func (l *label) setParent(p *controlParent) {
|
||||
basesetParent(l, p)
|
||||
C.controlSetParent(l.hwnd(), p.c.hwnd)
|
||||
// don't increment p.c.nchildren here because Labels aren't tab stops
|
||||
}
|
||||
|
||||
func (l *label) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
|
||||
|
|
|
@ -25,6 +25,8 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
return 0;
|
||||
}
|
||||
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
||||
case msgTabCurrentTabHasChildren:
|
||||
return (LRESULT) tabTabHasChildren((void *) data, SendMessageW(hwnd, TCM_GETCURSEL, 0, 0));
|
||||
case WM_NCDESTROY:
|
||||
if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, id) == FALSE)
|
||||
xpanic("error removing Tab subclass (which was for its own event handler)", GetLastError());
|
||||
|
|
|
@ -34,7 +34,7 @@ func newTab() Tab {
|
|||
|
||||
func (t *tab) Append(name string, control Control) {
|
||||
c := newContainer(control)
|
||||
c.setParent(&controlParent{t._hwnd})
|
||||
c.setParent(t._hwnd)
|
||||
t.tabs = append(t.tabs, c)
|
||||
// initially hide tab 1..n controls; if we don't, they'll appear over other tabs, resulting in weird behavior
|
||||
if len(t.tabs) != 1 {
|
||||
|
@ -55,6 +55,15 @@ func tabChanged(data unsafe.Pointer, new C.LRESULT) {
|
|||
t.tabs[int(new)].show()
|
||||
}
|
||||
|
||||
//export tabTabHasChildren
|
||||
func tabTabHasChildren(data unsafe.Pointer, which C.LRESULT) C.BOOL {
|
||||
t := (*tab)(data)
|
||||
if t.tabs[int(which)].nchildren > 0 {
|
||||
return C.TRUE
|
||||
}
|
||||
return C.FALSE
|
||||
}
|
||||
|
||||
func (t *tab) hwnd() C.HWND {
|
||||
return t._hwnd
|
||||
}
|
||||
|
|
|
@ -41,17 +41,19 @@ void uimsgloop(void)
|
|||
if (wcscmp(classchk, areaWindowClass) == 0)
|
||||
dodlgmessage = FALSE;
|
||||
else if (wcscmp(classchk, WC_TABCONTROL) == 0)
|
||||
istab = TRUE;
|
||||
// THIS BIT IS IMPORTANT
|
||||
// if the current tab has no children, then there will be no children left in the dialog to tab to, and IsDialogMessageW() will loop forever
|
||||
istab = (BOOL) SendMessageW(focus, msgTabCurrentTabHasChildren, 0, 0);
|
||||
}
|
||||
if (istab)
|
||||
tabEnterChildren(focus);
|
||||
// TODO this goes into an infinite loop on a blank tab
|
||||
if (dodlgmessage)
|
||||
if (dodlgmessage) {
|
||||
if (istab)
|
||||
tabEnterChildren(focus);
|
||||
idm = IsDialogMessageW(active, &msg);
|
||||
if (istab)
|
||||
tabLeaveChildren(focus);
|
||||
if (idm != 0)
|
||||
continue;
|
||||
if (istab)
|
||||
tabLeaveChildren(focus);
|
||||
if (idm != 0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
|
|
|
@ -29,6 +29,7 @@ enum {
|
|||
msgNOTIFY, // WM_NOTIFY proxy
|
||||
msgAreaSizeChanged,
|
||||
msgAreaRepaintAll,
|
||||
msgTabCurrentTabHasChildren,
|
||||
};
|
||||
|
||||
// uitask_windows.c
|
||||
|
|
|
@ -44,7 +44,7 @@ func newWindow(title string, width int, height int, control Control) *window {
|
|||
if hresult != C.S_OK {
|
||||
panic(fmt.Errorf("error setting tab background texture on Window; HRESULT: 0x%X", hresult))
|
||||
}
|
||||
w.container.setParent(&controlParent{w.hwnd})
|
||||
w.container.setParent(w.hwnd)
|
||||
return w
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue