Included new window structure flag w_closing_state and let window_close() set this flag - after drawing all windows, check them again and call window_do_close() which then actually closes the window(s) marked to. Solving all sorts of problems when windows close while being drawn (network error messageboxes, game_leave_menus(), etc.)
This commit is contained in:
parent
9a64614a04
commit
c7a65c9313
|
@ -4,6 +4,7 @@ D2X-Rebirth Changelog
|
|||
--------
|
||||
main/automap.c, main/gamecntl.c: Little fixes for recent kconfig/event overhaul: Automap inputs read by kconfig should be processed by input rather than idle and automap frame calculations should be done while drawing; Fixed drop_bomb_count which could roll over to 255 dropping bombs without end
|
||||
main/gauges: Corrected values for gr_ubox while drawing a window_view to not mess up at some widescreen resolutions
|
||||
arch/include/window.h, arch/sdl/event.c, arch/sdl/window.c: Included new window structure flag w_closing_state and let window_close() set this flag - after drawing all windows, check them again and call window_do_close() which then actually closes the window(s) marked to. Solving all sorts of problems when windows close while being drawn (network error messageboxes, game_leave_menus(), etc.)
|
||||
|
||||
20110202
|
||||
--------
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef struct window window;
|
|||
|
||||
extern window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_callback)(window *wind, d_event *event, void *data), void *data);
|
||||
extern int window_close(window *wind);
|
||||
extern int window_do_close(window *wind);
|
||||
extern int window_exists(window *wind);
|
||||
extern window *window_get_front(void);
|
||||
extern window *window_get_first(void);
|
||||
|
|
|
@ -152,16 +152,19 @@ void event_process(void)
|
|||
return;
|
||||
|
||||
event.type = EVENT_WINDOW_DRAW; // then draw all visible windows
|
||||
wind = window_get_first();
|
||||
while (wind != NULL)
|
||||
{
|
||||
window *next_wind = window_get_next(wind); // check this in now in case this window closes during EVENT_WINDOW_DRAW
|
||||
for (wind = window_get_first(); wind != NULL; wind = window_get_next(wind))
|
||||
if (window_is_visible(wind))
|
||||
window_send_event(wind, &event);
|
||||
wind = next_wind;
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
|
||||
wind = window_get_first();
|
||||
while (wind != NULL) // go through all windows and actually close them if they want to
|
||||
{
|
||||
window *next_wind = window_get_next(wind);
|
||||
window_do_close(wind);
|
||||
wind = next_wind;
|
||||
}
|
||||
}
|
||||
|
||||
void event_toggle_focus(int activate_focus)
|
||||
|
|
|
@ -18,6 +18,7 @@ struct window
|
|||
grs_canvas w_canv; // the window's canvas to draw to
|
||||
int (*w_callback)(window *wind, d_event *event, void *data); // the event handler
|
||||
int w_visible; // whether it's visible
|
||||
ubyte w_closing_state;
|
||||
void *data; // whatever the user wants (eg menu data for 'newmenu' menus)
|
||||
struct window *prev; // the previous window in the doubly linked list
|
||||
struct window *next; // the next window in the doubly linked list
|
||||
|
@ -41,6 +42,7 @@ window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_c
|
|||
gr_init_sub_canvas(&wind->w_canv, src, x, y, w, h);
|
||||
wind->w_callback = event_callback;
|
||||
wind->w_visible = 1; // default to visible
|
||||
wind->w_closing_state = 0;
|
||||
wind->data = data;
|
||||
|
||||
if (FirstWindow == NULL)
|
||||
|
@ -59,11 +61,20 @@ window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_c
|
|||
}
|
||||
|
||||
int window_close(window *wind)
|
||||
{
|
||||
wind->w_closing_state = 1; // mark this window to close
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int window_do_close(window *wind)
|
||||
{
|
||||
window *prev;
|
||||
d_event event;
|
||||
int (*w_callback)(window *wind, d_event *event, void *data) = wind->w_callback;
|
||||
|
||||
if (!wind->w_closing_state)
|
||||
return 0;
|
||||
if (wind == window_get_front())
|
||||
WINDOW_SEND_EVENT(wind, EVENT_WINDOW_DEACTIVATED); // Deactivate first
|
||||
|
||||
|
@ -74,7 +85,10 @@ int window_close(window *wind)
|
|||
{
|
||||
// User 'handled' the event, cancelling close
|
||||
if (wind == window_get_front())
|
||||
WINDOW_SEND_EVENT(wind, EVENT_WINDOW_ACTIVATED); // Reactivate. May cause flashing of some sort, too bad
|
||||
{
|
||||
WINDOW_SEND_EVENT(wind, EVENT_WINDOW_ACTIVATED);
|
||||
wind->w_closing_state = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -88,7 +102,7 @@ int window_close(window *wind)
|
|||
wind->prev->next = wind->next;
|
||||
|
||||
if ((prev = window_get_front()))
|
||||
WINDOW_SEND_EVENT(prev, EVENT_WINDOW_ACTIVATED); // Reactivate. May cause flashing of some sort, too bad
|
||||
WINDOW_SEND_EVENT(prev, EVENT_WINDOW_ACTIVATED);
|
||||
|
||||
d_free(wind);
|
||||
|
||||
|
|
Loading…
Reference in a new issue