ui.backend.gtk, use a separate widget for drawing opengl. Fixes #1487

Apparently you can't use opengl calls in a configure event signaled from
the window. If you do, on ubuntu 14.04 with unity, each and every frame
will be drawn. Since they are drawn slower than the event are emitted,
it continues to redraw after the resize is done, 'replaying' the resize
motion.
opengl calls from a configure event on the single child of the
window are ok.
Also, now that the window is not used to draw opengl, it doesn't produce
expose events, instead the drawable child must be used.

This also makes moving the window much smoother.
char-rename
Jon Harper 2017-01-13 17:08:46 +01:00 committed by John Benediktsson
parent 134be588cf
commit 14f51e2dd5
2 changed files with 27 additions and 18 deletions

View File

@ -24,7 +24,7 @@ HELP: on-configure
{ "user-data" alien } { "user-data" alien }
{ "?" boolean } { "?" boolean }
} }
{ $description "Handles a configure event (" { $link GdkEventConfigure } " sent from the windowing system. If the world has been sent the on-map event from gtk then it is relayouted, otherwise nothing happens." } ; { $description "Handles a configure event (" { $link GdkEventConfigure } ") sent from the windowing system. If the world has been sent the on-map event from gtk then it is updated, otherwise nothing happens. Resizing the window causes the world to be relayouted, but moving the window does not." } ;
ARTICLE: "ui.backend.gtk" "Gtk-based UI backend" ARTICLE: "ui.backend.gtk" "Gtk-based UI backend"
"GDK Event handlers:" "GDK Event handlers:"

View File

@ -15,9 +15,9 @@ IN: ui.backend.gtk
SINGLETON: gtk-ui-backend SINGLETON: gtk-ui-backend
TUPLE: window-handle window im-context fullscreen? ; TUPLE: window-handle window drawable im-context fullscreen? ;
: <window-handle> ( window im-context -- window-handle ) : <window-handle> ( window drawable im-context -- window-handle )
f window-handle boa ; f window-handle boa ;
: connect-signal-with-data ( object signal-name callback data -- ) : connect-signal-with-data ( object signal-name callback data -- )
@ -219,14 +219,14 @@ icon-data [ default-icon-data ] initialize
! Window state events ! Window state events
: on-expose ( win event user-data -- ? ) : on-expose ( win event user-data -- ? )
2drop window relayout t ; 2drop gtk_widget_get_toplevel window relayout t ;
: on-configure ( win event user-data -- ? ) : on-configure ( window event user-data -- ? )
drop swap window dup active?>> [ drop swap dup gtk_widget_get_toplevel [ = ] keep window dup active?>> [
swap GdkEventConfigure memory>struct swap [ swap GdkEventConfigure memory>struct ] dip
[ event-loc >>window-loc ] [ event-dim >>dim ] bi [ event-loc >>window-loc drop ]
relayout-1 [ event-dim >>dim relayout-1 ] if
] [ 2drop ] if f ; ] [ 3drop ] if f ;
: on-map ( win event user-data -- ? ) : on-map ( win event user-data -- ? )
2drop window t >>active? drop t ; 2drop window t >>active? drop t ;
@ -234,11 +234,16 @@ icon-data [ default-icon-data ] initialize
: on-delete ( win event user-data -- ? ) : on-delete ( win event user-data -- ? )
2drop window ungraft t ; 2drop window ungraft t ;
: connect-configure-signal ( winhandle -- )
[ window>> ] [ drawable>> ] bi "configure-event"
[ on-configure yield ] GtkWidget:configure-event
[ connect-signal ] 2curry bi@ ;
: connect-expose-sigal ( drawable -- )
"expose-event" [ on-expose yield ]
GtkWidget:expose-event connect-signal ;
:: connect-win-state-signals ( win -- ) :: connect-win-state-signals ( win -- )
win "expose-event" [ on-expose yield ]
GtkWidget:expose-event connect-signal
win "configure-event" [ on-configure yield ]
GtkWidget:configure-event connect-signal
win "delete-event" [ on-delete yield ] win "delete-event" [ on-delete yield ]
GtkWidget:delete-event connect-signal GtkWidget:delete-event connect-signal
win "map-event" [ on-map yield ] win "map-event" [ on-map yield ]
@ -395,19 +400,19 @@ M: gtk-ui-backend (pixel-format-attribute)
with-out-parameters ; with-out-parameters ;
M: window-handle select-gl-context ( handle -- ) M: window-handle select-gl-context ( handle -- )
window>> drawable>>
[ gtk_widget_get_gl_window ] [ gtk_widget_get_gl_context ] bi [ gtk_widget_get_gl_window ] [ gtk_widget_get_gl_context ] bi
gdk_gl_drawable_make_current drop ; gdk_gl_drawable_make_current drop ;
M: window-handle flush-gl-context ( handle -- ) M: window-handle flush-gl-context ( handle -- )
window>> gtk_widget_get_gl_window drawable>> gtk_widget_get_gl_window
gdk_gl_drawable_swap_buffers ; gdk_gl_drawable_swap_buffers ;
! Window ! Window
: configure-gl ( world -- ) : configure-gl ( world -- )
[ [
[ handle>> window>> ] [ handle>> ] bi* [ handle>> drawable>> ] [ handle>> ] bi*
f t GDK_GL_RGBA_TYPE gtk_widget_set_gl_capability drop f t GDK_GL_RGBA_TYPE gtk_widget_set_gl_capability drop
] with-world-pixel-format ; ] with-world-pixel-format ;
@ -420,9 +425,11 @@ M: window-handle flush-gl-context ( handle -- )
M:: gtk-ui-backend (open-window) ( world -- ) M:: gtk-ui-backend (open-window) ( world -- )
GTK_WINDOW_TOPLEVEL gtk_window_new :> win GTK_WINDOW_TOPLEVEL gtk_window_new :> win
gtk_drawing_area_new :> drawable
win drawable gtk_container_add
gtk_im_multicontext_new :> im gtk_im_multicontext_new :> im
win im <window-handle> world handle<< win drawable im <window-handle> world handle<<
world win register-window world win register-window
@ -443,6 +450,8 @@ M:: gtk-ui-backend (open-window) ( world -- )
win im configure-im win im configure-im
win connect-user-input-signals win connect-user-input-signals
win connect-win-state-signals win connect-win-state-signals
world handle>> connect-configure-signal
drawable connect-expose-sigal
win world window-controls>> configure-window-controls win world window-controls>> configure-window-controls
win gtk_widget_show_all ; win gtk_widget_show_all ;