-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Window manager for properly refreshing and resizing multiple layers of windows #37894
Conversation
This should close #8514 once and for all? |
It could, but the related menus should be first migrated to use this system. I'll migrate the menus mentioned there if it turns out to be doable in this PR. |
fa1024e
to
12ad380
Compare
src/sdltiles.cpp
Outdated
// Main menu redraw | ||
reinitialize_framebuffer(); | ||
// TODO: redraw all game menus if they are open | ||
ui_manager::redraw_all(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please test it in fullscreen dx9 mode. I remember in fullscreen mode when the game window was maximized after alt-tabbing, an event appeared - SDL_WINDOWEVENT_FOCUS_GAINED
but not SDL_WINDOWEVENT_EXPOSED
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested in fullscreen with direct3d and it was refreshing properly. I didn't see a dx9 mode though, so I'm not sure if that's what you mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
304f5b4
to
faf6881
Compare
@Night-Pryanik the menus mentioned in that issue are more complex than I expected so I'll leave them to a later PR. |
Also, can someone test if this is working on ncurses? |
@Qrox Do you need anything specific for testing on curses? Just open the game play around with menus, make a new character, edit settings, make a new world, etc.? |
@anothersimulacrum Thanks! There are two things I would like to test on curses:
On tiles I also expect the window to be refreshed when the window content is invalidated by system, such as when recovering from a sleep, but I assume on curses this is done by the terminal software and requires no action from the game. |
Have you applied the changes in #38235? That's where the actual migration takes place. |
No, that would probably help. |
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
For properly refreshing and resizing multiple layers of windows
// add_msg( m_info, "tile map fw %d fh %d", fw, fh); | ||
} else if( map_font && capture_win == g->w_terrain ) { | ||
window_dimensions dim; | ||
if( use_tiles && win == g->w_terrain ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently sometimes g
could be empty when there are errors (see #39258), so we need to check for non-emptiness prior to comparing win
with members of g
, e.g.:
window_dimensions dim;
dim.scaled_font_size.x = fontwidth;
dim.scaled_font_size.y = fontheight;
if( g ) {
if( use_tiles && win == g->w_terrain ) {
// tiles might have different dimensions than standard font
dim.scaled_font_size.x = tilecontext->get_tile_width();
dim.scaled_font_size.y = tilecontext->get_tile_height();
} else if( map_font && win == g->w_terrain ) {
// map font (if any) might differ from standard font
dim.scaled_font_size.x = map_font->fontwidth;
dim.scaled_font_size.y = map_font->fontheight;
} else if( overmap_font && win == g->w_overmap ) {
dim.scaled_font_size.x = overmap_font->fontwidth;
dim.scaled_font_size.y = overmap_font->fontheight;
}
}
Summary
SUMMARY: Infrastructure "Window manager for properly refreshing and resizing multiple layers of windows"
Purpose of change
Currently many game menus can be called from multiple places, such as the keybindings menu which can be opened from nearly every game menu. However, when closing some of these menus, keybindings menu included, only the previous menu is redrawn, leaving black space on the screen. Additionally, when resizing the game window, most of the menus aren't correctly resized and re-positioned.
Describe the solution
A new window manager that stores
ui_adaptor
objects, which UI code can use to encapsulate their initialization and redrawing code as callbacks. When closing a menu or resizing the game window, UIs are invalidated accordingly and redrawn, so all layers of windows are correctly displayed.This PR only contains the code for the ui manager. Menus need to be migrated individually to be properly refreshed and resized. For example, #38235 migrates the main menu and several related menus using ui_manager.
Describe alternatives you've considered
If the UI code was to be designed from scratch I would use an object-oriented event-based system, but since most of the game's UI code was written to be sequentially executed, this is a solution I found least intrusive.
Testing
Compiled with #38235, triggered a popup in the main game UI, and opened its keybindings menu. Closed the keybindings menu and observed that there was not black space left behind. Resized the game window and observed that the popup was correctly placed in the center of the screen.