From 847690bb105ead7d68cb0af018fa96864ffe137d Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 18 Jul 2014 19:36:29 -0400 Subject: [PATCH] Fixed window resizing in GTK+ acting wonky AND several related TODOs to boot! --- redo/common_unix.go | 10 ++++++++++ redo/sizing_unix.go | 16 +++++++++++++--- redo/window_unix.go | 22 +++++++++++----------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/redo/common_unix.go b/redo/common_unix.go index 5bcb819..aab80bf 100644 --- a/redo/common_unix.go +++ b/redo/common_unix.go @@ -14,6 +14,10 @@ import ( // { // g_signal_connect(obj, sig, callback, data); // } +// void gSignalConnectAfter(gpointer obj, gchar *sig, GCallback callback, gpointer data) +// { +// g_signal_connect_after(obj, sig, callback, data); +// } import "C" func fromgstr(s *C.gchar) string { @@ -33,3 +37,9 @@ func g_signal_connect(object C.gpointer, name string, to C.GCallback, data C.gpo defer freegstr(cname) C.gSignalConnect(object, cname, to, data) } + +func g_signal_connect_after(object C.gpointer, name string, to C.GCallback, data C.gpointer) { + cname := togstr(name) + defer freegstr(cname) + C.gSignalConnectAfter(object, cname, to, data) +} diff --git a/redo/sizing_unix.go b/redo/sizing_unix.go index 83411dc..caa9c8c 100644 --- a/redo/sizing_unix.go +++ b/redo/sizing_unix.go @@ -66,9 +66,19 @@ func (w *widgetbase) commitResize(c *allocation, d *sizing) { } } */ - // TODO this uses w.parentw directly; change? - C.gtk_layout_move(w.parentw.layout, w.widget, C.gint(c.x), C.gint(c.y)) - C.gtk_widget_set_size_request(w.widget, C.gint(c.width), C.gint(c.height)) + + // as we resize on size-allocate, we have to also use size-allocate on our children + // this is fine anyway; in fact, this allows us to move without knowing what the container is! + // this is what GtkBox does anyway + // thanks to tristan in irc.gimp.net/#gtk+ + + var r C.GtkAllocation + + r.x = C.int(c.x) + r.y = C.int(c.y) + r.width = C.int(c.width) + r.height = C.int(c.height) + C.gtk_widget_size_allocate(w.widget, &r) } func (w *widgetbase) getAuxResizeInfo(d *sizing) { diff --git a/redo/window_unix.go b/redo/window_unix.go index 87f1edb..251865b 100644 --- a/redo/window_unix.go +++ b/redo/window_unix.go @@ -11,7 +11,7 @@ import ( // #include "gtk_unix.h" // extern gboolean windowClosing(GtkWidget *, GdkEvent *, gpointer); -// extern gboolean windowResizing(GtkWidget *, GdkEvent *, gpointer); +// extern void windowResizing(GtkWidget *, GdkRectangle *, gpointer); import "C" type window struct { @@ -53,9 +53,13 @@ func newWindow(title string, width int, height int) *Request { "delete-event", C.GCallback(C.windowClosing), C.gpointer(unsafe.Pointer(w))) - g_signal_connect( - C.gpointer(unsafe.Pointer(w.window)), - "configure-event", + // we connect to the layout's size-allocate, not to the window's configure-event + // this allows us to handle client-side decoration-based configurations (such as GTK+ on Wayland) properly + // also see commitResize() in sizing_unix.go for additional notes + // thanks to many people in irc.gimp.net/#gtk+ for help (including tristan for suggesting g_signal_connect_after()) + g_signal_connect_after( + C.gpointer(unsafe.Pointer(layoutw)), + "size-allocate", C.GCallback(C.windowResizing), C.gpointer(unsafe.Pointer(w))) // TODO size @@ -161,12 +165,8 @@ func windowClosing(wid *C.GtkWidget, e *C.GdkEvent, data C.gpointer) C.gboolean } //export windowResizing -func windowResizing(wid *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean { +func windowResizing(wid *C.GtkWidget, r *C.GdkRectangle, data C.gpointer) { w := (*window)(unsafe.Pointer(data)) - e := (*C.GdkEventConfigure)(unsafe.Pointer(event)) - w.doresize(int(e.width), int(e.height)) - // TODO this does not take CSD into account; my attempts at doing so so far have failed to work correctly in the face of rapid live resizing - // TODO triggered twice on each resize or maximize for some reason??? - fmt.Printf("new size %d x %d\n", e.width, e.height) - return C.GDK_EVENT_PROPAGATE // let's be safe + w.doresize(int(r.width), int(r.height)) + fmt.Printf("new size %d x %d\n", r.width, r.height) }