Skip to content

Commit

Permalink
wrap pollEvent() to guarantee all loops handle modifiers (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
NQNStudios authored Nov 23, 2024
1 parent e39c930 commit b441401
Show file tree
Hide file tree
Showing 14 changed files with 45 additions and 27 deletions.
6 changes: 2 additions & 4 deletions src/dialogxml/dialogs/dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ void cDialog::run(std::function<void(cDialog&)> onopen){
handle_events();

win.setVisible(false);
while(parentWin->pollEvent(currentEvent));
while(pollEvent(parentWin, currentEvent));
set_cursor(former_curs);
topWindow = formerTop;
makeFrontWindow(*parentWin);
Expand Down Expand Up @@ -584,7 +584,7 @@ void cDialog::handle_events() {
cTextField& text_field = dynamic_cast<cTextField&>(getControl(currentFocus));
text_field.replay_selection(pop_next_action());
}else{
while(win.pollEvent(currentEvent)){
while(pollEvent(win, currentEvent)){
handle_one_event(currentEvent, fps_limiter);
}
}
Expand Down Expand Up @@ -618,8 +618,6 @@ void cDialog::handle_one_event(const sf::Event& currentEvent, cFramerateLimiter&
std::string itemHit = "";
location where;

if(kb.handleModifier(currentEvent)) return;

switch(currentEvent.type) {
case sf::Event::KeyPressed:
switch(currentEvent.key.code){
Expand Down
3 changes: 2 additions & 1 deletion src/dialogxml/widgets/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "tools/cursors.hpp"
#include "replay.hpp"
#include <boost/lexical_cast.hpp>
#include "winutil.hpp"

void cControl::setText(std::string l){
lbl = l;
Expand Down Expand Up @@ -228,7 +229,7 @@ bool cControl::handleClick(location, cFramerateLimiter& fps_limiter){
depressed = true;
while(!done){
redraw();
while(inWindow->pollEvent(e)){
while(pollEvent(inWindow, e)){
if(e.type == sf::Event::MouseButtonReleased){
done = true;
location clickPos(e.mouseButton.x, e.mouseButton.y);
Expand Down
2 changes: 1 addition & 1 deletion src/dialogxml/widgets/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ bool cTextField::handleClick(location clickLoc, cFramerateLimiter& fps_limiter)
int initial_ip = insertionPoint, initial_sp = selectionPoint;
while(!done) {
redraw();
while(inWindow->pollEvent(e)){
while(pollEvent(inWindow, e)){
if(e.type == sf::Event::MouseButtonReleased){
done = true;
} else if(e.type == sf::Event::MouseMoved){
Expand Down
3 changes: 2 additions & 1 deletion src/dialogxml/widgets/scrollbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "tools/cursors.hpp"
#include "replay.hpp"
#include <boost/lexical_cast.hpp>
#include "winutil.hpp"

std::string cScrollbar::scroll_textures[NUM_STYLES] = {
"dlogscrollwh",
Expand Down Expand Up @@ -319,7 +320,7 @@ bool cScrollbar::handleClick(location where, cFramerateLimiter& fps_limiter) {
int diff = clickPos - thumbPos;
while(!done){
redraw();
while(inWindow->pollEvent(e)){
while(pollEvent(inWindow, e)){
location mouseLoc = sf::Mouse::getPosition(*inWindow);
mouseLoc = inWindow->mapPixelToCoords(mouseLoc);
int mousePos = vert ? mouseLoc.y : mouseLoc.x;
Expand Down
6 changes: 3 additions & 3 deletions src/game/boe.actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ void handle_rest(bool& need_redraw, bool& need_reprint) {
i = 200;
add_string_to_buf(" Monsters nearby.");
}
while(mainPtr.pollEvent(dummy_evt));
while(pollEvent(mainPtr, dummy_evt));
redraw_screen(REFRESH_NONE);
i++;
}
Expand Down Expand Up @@ -1068,7 +1068,7 @@ static void handle_town_wait(bool& need_redraw, bool& need_reprint) {
i = 200;
add_string_to_buf(" Monster sighted!");
}
while(mainPtr.pollEvent(dummy_evt));
while(pollEvent(mainPtr, dummy_evt));
redraw_screen(REFRESH_NONE);
}
put_pc_screen();
Expand Down Expand Up @@ -3648,7 +3648,7 @@ bool check_for_interrupt(){
pop_next_action();
interrupt = true;
}
else if(mainPtr.pollEvent(evt) && evt.type == sf::Event::KeyPressed) {
else if(pollEvent(mainPtr, evt) && evt.type == sf::Event::KeyPressed) {
// TODO: I wonder if there are other events we should handle here? Resize maybe?
#ifdef __APPLE__
if(evt.key.code == kb::Period && evt.key.system)
Expand Down
7 changes: 2 additions & 5 deletions src/game/boe.main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,12 +827,12 @@ void handle_events() {
fake_event_queue.pop_front();
handle_one_event(next_event, fps_limiter);
}
while(mainPtr.pollEvent(currentEvent)) handle_one_event(currentEvent, fps_limiter);
while(pollEvent(mainPtr, currentEvent)) handle_one_event(currentEvent, fps_limiter);

// It would be nice to have minimap inside the main game window (we have lots of screen space in fullscreen mode).
// Alternatively, minimap could live on its own thread.
// But for now we just handle events from both windows on this thread.
while(map_visible && mini_map.pollEvent(currentEvent)) handle_one_minimap_event(currentEvent);
while(map_visible && pollEvent(mini_map, currentEvent)) handle_one_minimap_event(currentEvent);
}

if(changed_display_mode) {
Expand Down Expand Up @@ -893,9 +893,6 @@ void handle_one_event(const sf::Event& event, cFramerateLimiter& fps_limiter) {
// What does this do and should it be here?
clear_sound_memory();

// If it's just a modifier key, update the state
if(kb.handleModifier(event)) return;

// Check if any of the event listeners want this event.
for(auto & listener : event_listeners) {
if(listener.second->handle_event(event)) return;
Expand Down
3 changes: 2 additions & 1 deletion src/game/boe.specials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "boe.menus.hpp"
#include "replay.hpp"
#include <boost/lexical_cast.hpp>
#include "winutil.hpp"

extern sf::RenderWindow mainPtr;
extern eGameMode overall_mode;
Expand Down Expand Up @@ -2017,7 +2018,7 @@ void run_special(eSpecCtx which_mode, eSpecCtxType which_type, spec_num_t start_
if(replaying && has_next_action("step_through_continue")){
pop_next_action();
break;
}else if(mainPtr.pollEvent(evt) && (evt.type == sf::Event::KeyPressed || evt.type == sf::Event::MouseButtonPressed)){
}else if(pollEvent(mainPtr, evt) && (evt.type == sf::Event::KeyPressed || evt.type == sf::Event::MouseButtonPressed)){
if(recording){
record_action("step_through_continue", "");
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/boe.startup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool handle_startup_press(location the_point) {

static void handle_splash_events(cFramerateLimiter& fps_limiter) {
sf::Event event;
while(mainPtr.pollEvent(event)) {
while(pollEvent(mainPtr, event)) {
if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved)
set_cursor(sword_curs);
}
Expand Down
3 changes: 2 additions & 1 deletion src/game/boe.ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "fileio/resmgr/res_image.hpp"
#include "mathutil.hpp"
#include "sounds.hpp"
#include "winutil.hpp"

namespace UI {
cToolbar toolbar;
Expand Down Expand Up @@ -62,7 +63,7 @@ eToolbarButton cToolbar::button_hit(sf::RenderWindow& win, location click, cFram
active = i;
while(!done){
redraw_screen(REFRESH_NONE);
while(win.pollEvent(e)) {
while(pollEvent(win, e)) {
if(e.type == sf::Event::MouseButtonReleased){
done = true;
location clickPos(e.mouseButton.x, e.mouseButton.y);
Expand Down
5 changes: 1 addition & 4 deletions src/pcedit/pc.main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void handle_events() {
menuChoiceId=-1;
}
#endif
while(mainPtr.pollEvent(currentEvent)) handle_one_event(currentEvent);
while(pollEvent(mainPtr, currentEvent)) handle_one_event(currentEvent);

redraw_everything();

Expand All @@ -225,9 +225,6 @@ void handle_events() {

void handle_one_event (const sf::Event& event) {

// If it's just a modifier key, update the state
if(kb.handleModifier(event)) return;

// Check if the menubar wants to handle this event.
if(menuBarProcessEvent(event)) return;

Expand Down
3 changes: 2 additions & 1 deletion src/scenedit/scen.graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "mathutil.hpp"
#include "tools/drawable_manager.hpp"
#include "tools/cursors.hpp"
#include "tools/winutil.hpp"

#include "dialogxml/dialogs/dialog.hpp"

Expand Down Expand Up @@ -366,7 +367,7 @@ void run_startup_g() {
sf::Clock timer;
while(sound_going(95) || timer.getElapsedTime() < delay) {
draw_splash(pict_to_draw, mainPtr, dest_rect);
if(!mainPtr.pollEvent(event)) continue;
if(!pollEvent(mainPtr, event)) continue;
if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved)
set_cursor(watch_curs);
if(event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed)
Expand Down
5 changes: 1 addition & 4 deletions src/scenedit/scen.main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void handle_events() {
menuChoiceId=-1;
}
#endif
while(mainPtr.pollEvent(currentEvent)) handle_one_event(currentEvent);
while(pollEvent(mainPtr, currentEvent)) handle_one_event(currentEvent);

// Why do we have to set this to false after handling every event?
ae_loading = false;
Expand All @@ -287,9 +287,6 @@ void handle_events() {

void handle_one_event(const sf::Event& event) {

// If it's just a modifier key, update the state
if(kb.handleModifier(event)) return;

// Check if any of the event listeners want this event.
for (auto& listener : event_listeners) {
if(listener.second->handle_event(event)) return;
Expand Down
20 changes: 20 additions & 0 deletions src/tools/winutil.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "winutil.hpp"

#include "keymods.hpp"

// The default scale should be the largest that the user's screen can fit all three
// BoE application windows (because they should probably default to match each other).
double fallback_scale() {
Expand Down Expand Up @@ -28,4 +30,22 @@ double fallback_scale() {
}

return scale;
}

// We use many nested event loops in this codebase. Each one of them
// calls pollEvent() and they each need to remember to call handleModifier()
// or else modifier keys will claim to be held forever.
// The best solution for this is to wrap pollEvent() so that it calls
// handleModifier for us every time.
bool pollEvent(sf::Window& win, sf::Event& event){
if(win.pollEvent(event)) {
if(kb.handleModifier(event)) return false;
return true;
}

return false;
}

bool pollEvent(sf::Window* win, sf::Event& event){
return pollEvent(*win, event);
}
4 changes: 4 additions & 0 deletions src/tools/winutil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ char keyToChar(sf::Keyboard::Key key, bool isShift);
void makeFrontWindow(sf::Window& win);
void setWindowFloating(sf::Window& win, bool floating);

// Necessary wrapper for sf::Window.pollEvent()
bool pollEvent(sf::Window& win, sf::Event& event);
bool pollEvent(sf::Window* win, sf::Event& event);

void init_fileio();
void launchURL(std::string url);

Expand Down

0 comments on commit b441401

Please sign in to comment.