GTK: thread-safe refresh. doesn't freeze randomly anymore.

This commit is contained in:
StapleButter
2017-09-19 16:53:02 +02:00
parent 4db1a51fa4
commit edd33187b6
4 changed files with 24 additions and 5 deletions

View File

@ -1,6 +1,8 @@
// 4 september 2015 // 4 september 2015
#include "uipriv_unix.h" #include "uipriv_unix.h"
extern GThread* gtkthread;
// notes: // notes:
// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) // - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
#define areaWidgetType (areaWidget_get_type()) #define areaWidgetType (areaWidget_get_type())
@ -387,7 +389,7 @@ static int areaKeyEvent(uiArea *a, int up, GdkEventKey *e)
ke.Key = 0; ke.Key = 0;
ke.ExtKey = 0; ke.ExtKey = 0;
ke.Modifier = 0; ke.Modifier = 0;
printf("keypress: %08X\n", e->hardware_keycode-8);
state = translateModifiers(e->state, e->window); state = translateModifiers(e->state, e->window);
ke.Modifiers = toModifiers(state); ke.Modifiers = toModifiers(state);
@ -501,9 +503,20 @@ void uiAreaSetSize(uiArea *a, int width, int height)
gtk_widget_queue_resize(a->areaWidget); gtk_widget_queue_resize(a->areaWidget);
} }
gboolean _threadsaferefresh(gpointer data)
{
uiArea* a = (uiArea*)data;
gtk_widget_queue_draw(a->areaWidget);
return FALSE;
}
void uiAreaQueueRedrawAll(uiArea *a) void uiAreaQueueRedrawAll(uiArea *a)
{ {
gtk_widget_queue_draw(a->areaWidget); // TODO: figure out how we could generalize the "thread-safe function call" mechanism
if (g_thread_self() != gtkthread)
g_idle_add(_threadsaferefresh, a);
else
gtk_widget_queue_draw(a->areaWidget);
} }
void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height)

View File

@ -3,6 +3,9 @@
uiInitOptions options; uiInitOptions options;
// kind of a hack
GThread* gtkthread;
const char *uiInit(uiInitOptions *o) const char *uiInit(uiInitOptions *o)
{ {
GError *err = NULL; GError *err = NULL;
@ -16,6 +19,9 @@ const char *uiInit(uiInitOptions *o)
} }
initAlloc(); initAlloc();
loadFutures(); loadFutures();
gtkthread = g_thread_self();
return NULL; return NULL;
} }

View File

@ -265,7 +265,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
// show everything in the vbox, but not the GtkWindow itself // show everything in the vbox, but not the GtkWindow itself
gtk_widget_show_all(w->vboxWidget); gtk_widget_show_all(w->vboxWidget);
printf("wbox %p\n", w->childHolderWidget);
// and connect our events // and connect our events
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w); g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
g_signal_connect(w->childHolderWidget, "size-allocate", G_CALLBACK(onSizeAllocate), w); g_signal_connect(w->childHolderWidget, "size-allocate", G_CALLBACK(onSizeAllocate), w);

View File

@ -133,7 +133,7 @@ int EmuThreadFunc(void* burp)
char melontitle[100]; char melontitle[100];
sprintf(melontitle, "%d/%.0f FPS | melonDS " MELONDS_VERSION, fps, fpstarget); sprintf(melontitle, "%d/%.0f FPS | melonDS " MELONDS_VERSION, fps, fpstarget);
uiWindowSetTitle(MainWindow, melontitle); //uiWindowSetTitle(MainWindow, melontitle);
} }
} }
else else
@ -321,7 +321,7 @@ int main(int argc, char** argv)
EmuThread = SDL_CreateThread(EmuThreadFunc, "melonDS magic", NULL); EmuThread = SDL_CreateThread(EmuThreadFunc, "melonDS magic", NULL);
uiControlShow(uiControl(MainWindow)); uiControlShow(uiControl(MainWindow));
uiControlSetFocus(uiControl(MainDrawArea)); // TODO: this needs to be done when the window regains focus //uiControlSetFocus(uiControl(MainDrawArea)); // TODO: this needs to be done when the window regains focus
uiMain(); uiMain();
EmuRunning = 0; EmuRunning = 0;