Fix window focus bugs for Windows
This commit is contained in:
@@ -764,9 +764,6 @@ void cDialog::handle_one_event(const sf::Event& currentEvent, cFramerateLimiter&
|
|||||||
for(int i = dialog_stack.size() - 1; i >= 0; --i){
|
for(int i = dialog_stack.size() - 1; i >= 0; --i){
|
||||||
makeFrontWindow(*(dialog_stack[i]));
|
makeFrontWindow(*(dialog_stack[i]));
|
||||||
}
|
}
|
||||||
// that generates more LostFocus and GainedFocus event(s)
|
|
||||||
sf::Event evt;
|
|
||||||
while(pollEvent(win, evt));
|
|
||||||
}
|
}
|
||||||
BOOST_FALLTHROUGH;
|
BOOST_FALLTHROUGH;
|
||||||
case sf::Event::MouseMoved:{
|
case sf::Event::MouseMoved:{
|
||||||
|
@@ -692,7 +692,7 @@ void init_mini_map() {
|
|||||||
mini_map().setVisible(false);
|
mini_map().setVisible(false);
|
||||||
map_visible=false;
|
map_visible=false;
|
||||||
setWindowFloating(mini_map(), true);
|
setWindowFloating(mini_map(), true);
|
||||||
makeFrontWindow(mainPtr());
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
|
|
||||||
// Create and initialize map gworld
|
// Create and initialize map gworld
|
||||||
if(!map_gworld().create(384, 384)) {
|
if(!map_gworld().create(384, 384)) {
|
||||||
|
@@ -233,13 +233,10 @@ void dialog_lost_focus(sf::RenderWindow& win) {
|
|||||||
|
|
||||||
void dialog_gained_focus(sf::RenderWindow& win) {
|
void dialog_gained_focus(sf::RenderWindow& win) {
|
||||||
setWindowFloating(mini_map(), true);
|
setWindowFloating(mini_map(), true);
|
||||||
makeFrontWindow(mainPtr());
|
|
||||||
if(map_visible){
|
if(map_visible){
|
||||||
makeFrontWindow(mini_map());
|
makeFrontWindow(mini_map());
|
||||||
}
|
}
|
||||||
// that generates more LostFocus and GainedFocus event(s)
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
sf::Event evt;
|
|
||||||
while(pollEvent(win, evt));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comment this line out for exact exception callstacks:
|
// Comment this line out for exact exception callstacks:
|
||||||
@@ -1294,8 +1291,8 @@ void handle_events() {
|
|||||||
setWindowFloating(mini_map(), true);
|
setWindowFloating(mini_map(), true);
|
||||||
if(map_visible){
|
if(map_visible){
|
||||||
makeFrontWindow(mini_map());
|
makeFrontWindow(mini_map());
|
||||||
makeFrontWindow(mainPtr());
|
|
||||||
}
|
}
|
||||||
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
}
|
}
|
||||||
|
|
||||||
main_window_lost_focus = main_window_gained_focus =
|
main_window_lost_focus = main_window_gained_focus =
|
||||||
@@ -1375,7 +1372,7 @@ void handle_one_event(const sf::Event& event, cFramerateLimiter& fps_limiter) {
|
|||||||
case sf::Event::GainedFocus:
|
case sf::Event::GainedFocus:
|
||||||
check_window_moved(mainPtr(), last_window_x, last_window_y, "MainWindow");
|
check_window_moved(mainPtr(), last_window_x, last_window_y, "MainWindow");
|
||||||
main_window_gained_focus = true;
|
main_window_gained_focus = true;
|
||||||
makeFrontWindow(mainPtr());
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
change_cursor();
|
change_cursor();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1415,7 +1412,7 @@ void handle_one_minimap_event(const sf::Event& event) {
|
|||||||
}else if(event.type == sf::Event::GainedFocus){
|
}else if(event.type == sf::Event::GainedFocus){
|
||||||
map_window_gained_focus = true;
|
map_window_gained_focus = true;
|
||||||
check_window_moved(mini_map(), last_map_x, last_map_y, "MapWindow");
|
check_window_moved(mini_map(), last_map_x, last_map_y, "MapWindow");
|
||||||
makeFrontWindow(mainPtr());
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
}else if(event.type == sf::Event::LostFocus){
|
}else if(event.type == sf::Event::LostFocus){
|
||||||
map_window_lost_focus = true;
|
map_window_lost_focus = true;
|
||||||
}else if(event.type == sf::Event::MouseMoved){
|
}else if(event.type == sf::Event::MouseMoved){
|
||||||
|
@@ -1575,7 +1575,7 @@ void display_map() {
|
|||||||
mini_map().setVisible(true);
|
mini_map().setVisible(true);
|
||||||
map_visible = true;
|
map_visible = true;
|
||||||
draw_map(true);
|
draw_map(true);
|
||||||
makeFrontWindow(mainPtr());
|
makeFrontWindow(mainPtr(), mini_map());
|
||||||
|
|
||||||
set_cursor(sword_curs);
|
set_cursor(sword_curs);
|
||||||
}
|
}
|
||||||
|
@@ -89,4 +89,26 @@ bool check_window_moved(sf::RenderWindow& win, int& winLastX, int& winLastY, std
|
|||||||
winLastX = winPosition.x;
|
winLastX = winPosition.x;
|
||||||
winLastY = winPosition.y;
|
winLastY = winPosition.y;
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void makeFrontWindow(sf::Window& win) {
|
||||||
|
static sf::Event evt;
|
||||||
|
_makeFrontWindow(win);
|
||||||
|
// Discard GainedFocus events generated by our own meddling:
|
||||||
|
while(pollEvent(win, evt));
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeFrontWindow(sf::Window& win, sf::Window& prev) {
|
||||||
|
static sf::Event evt;
|
||||||
|
_makeFrontWindow(win);
|
||||||
|
// Discard GainedFocus and LostFocus events generated by our own meddling:
|
||||||
|
while(pollEvent(win, evt));
|
||||||
|
while(pollEvent(prev, evt));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowFloating(sf::Window& win, bool floating) {
|
||||||
|
static sf::Event evt;
|
||||||
|
_setWindowFloating(win, floating);
|
||||||
|
// Discard GainedFocus and LostFocus events generated by our own meddling:
|
||||||
|
while(pollEvent(win, evt));
|
||||||
|
}
|
||||||
|
@@ -23,8 +23,14 @@ sf::RenderWindow& mainPtr();
|
|||||||
|
|
||||||
char keyToChar(sf::Keyboard::Key key, bool isShift);
|
char keyToChar(sf::Keyboard::Key key, bool isShift);
|
||||||
|
|
||||||
|
// public-facing overloads which discard events generated by the operation:
|
||||||
void makeFrontWindow(sf::Window& win);
|
void makeFrontWindow(sf::Window& win);
|
||||||
|
void makeFrontWindow(sf::Window& win, sf::Window& prev);
|
||||||
void setWindowFloating(sf::Window& win, bool floating);
|
void setWindowFloating(sf::Window& win, bool floating);
|
||||||
|
// OS-specific implementations:
|
||||||
|
void _makeFrontWindow(sf::Window& win);
|
||||||
|
void _setWindowFloating(sf::Window& win, bool floating);
|
||||||
|
|
||||||
|
|
||||||
// Necessary wrapper for sf::Window.pollEvent()
|
// Necessary wrapper for sf::Window.pollEvent()
|
||||||
bool pollEvent(sf::Window& win, sf::Event& event);
|
bool pollEvent(sf::Window& win, sf::Event& event);
|
||||||
|
@@ -91,10 +91,10 @@ std::string get_os_version() {
|
|||||||
return version.str();
|
return version.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeFrontWindow(sf::Window& win) {
|
void _makeFrontWindow(sf::Window& win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFloating(sf::Window& win, bool floating) {
|
void _setWindowFloating(sf::Window& win, bool floating) {
|
||||||
// Code adapted from <http://stackoverflow.com/a/16235920>
|
// Code adapted from <http://stackoverflow.com/a/16235920>
|
||||||
auto display = XOpenDisplay(NULL);
|
auto display = XOpenDisplay(NULL);
|
||||||
Atom wmStateAbove = XInternAtom(display, "_NET_WM_STATE_ABOVE", true);
|
Atom wmStateAbove = XInternAtom(display, "_NET_WM_STATE_ABOVE", true);
|
||||||
|
@@ -83,7 +83,7 @@ std::string get_os_version() {
|
|||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeFrontWindow(sf::Window& win) {
|
void _makeFrontWindow(sf::Window& win) {
|
||||||
sf::WindowHandle handle = win.getSystemHandle();
|
sf::WindowHandle handle = win.getSystemHandle();
|
||||||
id nsHandle = id(handle);
|
id nsHandle = id(handle);
|
||||||
if([nsHandle isKindOfClass: [NSWindow class]]) {
|
if([nsHandle isKindOfClass: [NSWindow class]]) {
|
||||||
@@ -92,7 +92,7 @@ void makeFrontWindow(sf::Window& win) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFloating(sf::Window& win, bool floating) {
|
void _setWindowFloating(sf::Window& win, bool floating) {
|
||||||
sf::WindowHandle handle = win.getSystemHandle();
|
sf::WindowHandle handle = win.getSystemHandle();
|
||||||
id nsHandle = id(handle);
|
id nsHandle = id(handle);
|
||||||
if([nsHandle isKindOfClass: [NSWindow class]]) {
|
if([nsHandle isKindOfClass: [NSWindow class]]) {
|
||||||
|
@@ -144,15 +144,15 @@ std::string get_os_version() {
|
|||||||
return version.str();
|
return version.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeFrontWindow(sf::Window& win) {
|
void _makeFrontWindow(sf::Window& win) {
|
||||||
HWND win_handle = win.getSystemHandle();
|
HWND win_handle = win.getSystemHandle();
|
||||||
BringWindowToTop(win_handle);
|
BringWindowToTop(win_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFloating(sf::Window& win, bool floating) {
|
void _setWindowFloating(sf::Window& win, bool floating) {
|
||||||
HWND win_handle = win.getSystemHandle();
|
HWND win_handle = win.getSystemHandle();
|
||||||
UINT flags = SWP_NOMOVE | SWP_NOSIZE;
|
UINT flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE;
|
||||||
HWND newPos = floating ? HWND_TOPMOST : HWND_TOP;
|
HWND newPos = floating ? HWND_TOPMOST : HWND_BOTTOM;
|
||||||
// The flags param specifies that these 0's are ignored.
|
// The flags param specifies that these 0's are ignored.
|
||||||
SetWindowPos(win_handle, newPos, 0, 0, 0, 0, flags);
|
SetWindowPos(win_handle, newPos, 0, 0, 0, 0, flags);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user