mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-05 00:36:57 +00:00
GUI: Add guard to prevent recursive call of handleMouseWheel in dialogs
This fixes bug #14404. The rercusive call was introduced with commit325260f
that changed the implementation of Widget::handleMouseWheel to call handleMouseWheel on the widget boss. If the widget boss is a dialog, its implementation is to call handleMouseWheel on the widget under the cursor. And we can end up with an infinite loop. As indicated in bug #13106, which was fixed by commit325260f
, a similar infinite loop when using the mouse wheel to scroll tabs in the options dialog was caused by the commit and quickly fixed. But the fix was only for that particular case. Here the fix should be more global.
This commit is contained in:
parent
b4b27be65b
commit
059781c89c
@ -40,7 +40,7 @@ namespace GUI {
|
||||
Dialog::Dialog(int x, int y, int w, int h, bool scale)
|
||||
: GuiObject(x, y, w, h, scale),
|
||||
_mouseWidget(nullptr), _focusedWidget(nullptr), _dragWidget(nullptr), _tickleWidget(nullptr), _visible(false),
|
||||
_backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) {
|
||||
_backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault), _handlingMouseWheel(false) {
|
||||
// Some dialogs like LauncherDialog use internally a fixed size, even though
|
||||
// their widgets rely on the layout to be initialized correctly by the theme.
|
||||
// Thus we need to catch screen changes here too. If we do not do that, it
|
||||
@ -55,7 +55,7 @@ Dialog::Dialog(int x, int y, int w, int h, bool scale)
|
||||
Dialog::Dialog(const Common::String &name)
|
||||
: GuiObject(name),
|
||||
_mouseWidget(nullptr), _focusedWidget(nullptr), _dragWidget(nullptr), _tickleWidget(nullptr), _visible(false),
|
||||
_backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) {
|
||||
_backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault), _handlingMouseWheel(false) {
|
||||
|
||||
// It may happen that we have 3x scaler in launcher (960xY) and then 640x480
|
||||
// game will be forced to 1x. At this stage GUI will not be aware of
|
||||
@ -236,17 +236,24 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||
}
|
||||
|
||||
void Dialog::handleMouseWheel(int x, int y, int direction) {
|
||||
Widget *w;
|
||||
// Guard against recursive call.
|
||||
// This can happen as we call handleMouseWheel() on the widget under the mouse,
|
||||
// and the default implementation of Widget::handleMouseWheel() is to call it
|
||||
// for the widget boss, which can be this dialog.
|
||||
if (_handlingMouseWheel)
|
||||
return;
|
||||
_handlingMouseWheel = true;
|
||||
|
||||
// This may look a bit backwards, but I think it makes more sense for
|
||||
// the mouse wheel to primarily affect the widget the mouse is at than
|
||||
// the widget that happens to be focused.
|
||||
|
||||
w = findWidget(x, y);
|
||||
Widget *w = findWidget(x, y);
|
||||
if (!w)
|
||||
w = _focusedWidget;
|
||||
if (w)
|
||||
w->handleMouseWheel(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), direction);
|
||||
|
||||
_handlingMouseWheel = false;
|
||||
}
|
||||
|
||||
void Dialog::handleKeyDown(Common::KeyState state) {
|
||||
|
@ -66,6 +66,7 @@ protected:
|
||||
|
||||
private:
|
||||
int _result;
|
||||
bool _handlingMouseWheel;
|
||||
|
||||
public:
|
||||
Dialog(int x, int y, int w, int h, bool scale = false);
|
||||
|
Loading…
Reference in New Issue
Block a user