summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-11-28 08:17:10 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-11-28 08:17:10 +0200
commit95a6963112f430dfae63ee6b801b36985482a541 (patch)
tree0c1265a9b93468d1bde8c3c3deba462ea9fc2c82
parent3b0e44cc32f4d45e37912d52fc2f2cd98f12da75 (diff)
Workaround for SDL window resize issue
Rearrange and draw window contents with an event watcher during window resizing because SDL is blocking the main thread. Tested on macOS so far, may need a build option. In reference to SDL bug: https://bugzilla.libsdl.org/show_bug.cgi?id=2077
-rw-r--r--src/app.c10
-rw-r--r--src/ui/window.c20
-rw-r--r--src/ui/window.h1
3 files changed, 25 insertions, 6 deletions
diff --git a/src/app.c b/src/app.c
index 57fa3318..419c5619 100644
--- a/src/app.c
+++ b/src/app.c
@@ -566,10 +566,20 @@ static void runTickers_App_(iApp *d) {
566 } 566 }
567} 567}
568 568
569static int resizeWatcher_(void *user, SDL_Event *event) {
570 iApp *d = user;
571 if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
572 const SDL_WindowEvent *winev = &event->window;
573 drawWhileResizing_Window(d->window, winev->data1, winev->data2);
574 }
575 return 0;
576}
577
569static int run_App_(iApp *d) { 578static int run_App_(iApp *d) {
570 arrange_Widget(findWidget_App("root")); 579 arrange_Widget(findWidget_App("root"));
571 d->running = iTrue; 580 d->running = iTrue;
572 SDL_EventState(SDL_DROPFILE, SDL_ENABLE); /* open files via drag'n'drop */ 581 SDL_EventState(SDL_DROPFILE, SDL_ENABLE); /* open files via drag'n'drop */
582 SDL_AddEventWatch(resizeWatcher_, d);
573 while (d->running) { 583 while (d->running) {
574 processEvents_App(waitForNewEvents_AppEventMode); 584 processEvents_App(waitForNewEvents_AppEventMode);
575 runTickers_App_(d); 585 runTickers_App_(d);
diff --git a/src/ui/window.c b/src/ui/window.c
index cdb122be..dd9181ad 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -514,17 +514,25 @@ static void setupUserInterface_Window(iWindow *d) {
514 } 514 }
515} 515}
516 516
517static void updateRootSize_Window_(iWindow *d) { 517static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) {
518 iInt2 *size = &d->root->rect.size; 518 iInt2 *size = &d->root->rect.size;
519 const iInt2 oldSize = *size; 519 const iInt2 oldSize = *size;
520 SDL_GetRendererOutputSize(d->render, &size->x, &size->y); 520 SDL_GetRendererOutputSize(d->render, &size->x, &size->y);
521 if (!isEqual_I2(oldSize, *size)) { 521 if (notifyAlways || !isEqual_I2(oldSize, *size)) {
522 arrange_Widget(d->root); 522 arrange_Widget(d->root);
523 postCommandf_App("window.resized width:%d height:%d", size->x, size->y); 523 postCommandf_App("window.resized width:%d height:%d", size->x, size->y);
524 postRefresh_App(); 524 postRefresh_App();
525 } 525 }
526} 526}
527 527
528void drawWhileResizing_Window(iWindow *d, int w, int h) {
529 /* This is called while a window resize is in progress, so we can be pretty confident
530 the size has actually changed. */
531 d->root->rect.size = mulf_I2(init_I2(w, h), d->pixelRatio);
532 arrange_Widget(d->root);
533 draw_Window(d);
534}
535
528static float pixelRatio_Window_(const iWindow *d) { 536static float pixelRatio_Window_(const iWindow *d) {
529#if defined (iPlatformMsys) 537#if defined (iPlatformMsys)
530 iUnused(d); 538 iUnused(d);
@@ -631,7 +639,7 @@ void init_Window(iWindow *d, iRect rect) {
631 init_Text(d->render); 639 init_Text(d->render);
632 setupUserInterface_Window(d); 640 setupUserInterface_Window(d);
633 postCommand_App("bindings.changed"); /* update from bindings */ 641 postCommand_App("bindings.changed"); /* update from bindings */
634 updateRootSize_Window_(d); 642 updateRootSize_Window_(d, iFalse);
635} 643}
636 644
637void deinit_Window(iWindow *d) { 645void deinit_Window(iWindow *d) {
@@ -692,11 +700,11 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) {
692 return iTrue; 700 return iTrue;
693 } 701 }
694 case SDL_WINDOWEVENT_RESIZED: 702 case SDL_WINDOWEVENT_RESIZED:
695 case SDL_WINDOWEVENT_SIZE_CHANGED: 703// case SDL_WINDOWEVENT_SIZE_CHANGED:
696 if (!isMaximized_Window_(d) && !d->isDrawFrozen) { 704 if (!isMaximized_Window_(d) && !d->isDrawFrozen) {
697 d->lastRect.size = init_I2(ev->data1, ev->data2); 705 d->lastRect.size = init_I2(ev->data1, ev->data2);
698 } 706 }
699 updateRootSize_Window_(d); 707 updateRootSize_Window_(d, iTrue /* we were already redrawing during the resize */);
700 return iTrue; 708 return iTrue;
701 case SDL_WINDOWEVENT_LEAVE: 709 case SDL_WINDOWEVENT_LEAVE:
702 unhover_Widget(); 710 unhover_Widget();
@@ -836,7 +844,7 @@ void draw_Window(iWindow *d) {
836 844
837void resize_Window(iWindow *d, int w, int h) { 845void resize_Window(iWindow *d, int w, int h) {
838 SDL_SetWindowSize(d->win, w, h); 846 SDL_SetWindowSize(d->win, w, h);
839 updateRootSize_Window_(d); 847 updateRootSize_Window_(d, iFalse);
840} 848}
841 849
842void setTitle_Window(iWindow *d, const iString *title) { 850void setTitle_Window(iWindow *d, const iString *title) {
diff --git a/src/ui/window.h b/src/ui/window.h
index 18df0cf9..2b68d7aa 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -51,6 +51,7 @@ struct Impl_Window {
51 51
52iBool processEvent_Window (iWindow *, const SDL_Event *); 52iBool processEvent_Window (iWindow *, const SDL_Event *);
53void draw_Window (iWindow *); 53void draw_Window (iWindow *);
54void drawWhileResizing_Window(iWindow *d, int w, int h); /* workaround for SDL bug */
54void resize_Window (iWindow *, int w, int h); 55void resize_Window (iWindow *, int w, int h);
55void setTitle_Window (iWindow *, const iString *title); 56void setTitle_Window (iWindow *, const iString *title);
56void setUiScale_Window (iWindow *, float uiScale); 57void setUiScale_Window (iWindow *, float uiScale);