diff options
author | Andrei Karas <akaras@inbox.ru> | 2013-04-12 02:11:25 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2013-04-12 02:11:25 +0300 |
commit | 4ddde5f4fa3f4b77c2ddf1d4848d06628d396842 (patch) | |
tree | 8653a426a81a23fccfdeea45c042d59a13691bbf | |
parent | 9ce9d5563195bf9d7d22356252f38bc95b247527 (diff) | |
download | manaplus-4ddde5f4fa3f4b77c2ddf1d4848d06628d396842.tar.gz manaplus-4ddde5f4fa3f4b77c2ddf1d4848d06628d396842.tar.bz2 manaplus-4ddde5f4fa3f4b77c2ddf1d4848d06628d396842.tar.xz manaplus-4ddde5f4fa3f4b77c2ddf1d4848d06628d396842.zip |
fix random rare crashes in npc and possible other windows.
32 files changed, 98 insertions, 12 deletions
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index fbd37f9a9..a89711137 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -307,6 +307,8 @@ void Gui::slowLogic() boldFont->slowLogic(4); if (mNpcFont) mNpcFont->slowLogic(5); + if (windowContainer) + windowContainer->slowLogic(); BLOCK_END("Gui::slowLogic") } @@ -732,3 +734,12 @@ void Gui::distributeGlobalFocusGainedEvent(const gcn::Event &focusEvent) (*iter)->focusGained(focusEvent); } } + +void Gui::removeDragged(gcn::Widget *widget) +{ + if (!mFocusHandler) + return; + + if (mFocusHandler->getDraggedWidget() == widget) + mFocusHandler->setDraggedWidget(nullptr); +} diff --git a/src/gui/gui.h b/src/gui/gui.h index 84142f3e1..a0ea4f496 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -151,6 +151,8 @@ class Gui final : public gcn::Gui void distributeGlobalFocusGainedEvent(const gcn::Event &focusEvent); + void removeDragged(gcn::Widget *widget); + protected: void handleMouseMoved(const gcn::MouseInput &mouseInput); diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index 32f17ecbd..5a886c454 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -281,6 +281,8 @@ void NpcDialog::action(const gcn::ActionEvent &event) if (mInputState == NPC_INPUT_LIST) { + if (gui) + gui->resetClickCount(); const int selectedIndex = mItemList->getSelected(); if (selectedIndex >= static_cast<int>(mItems.size()) diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index c8b0a0c8b..a9011f595 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -277,8 +277,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) void Viewport::logic() { BLOCK_START("Viewport::logic") - WindowContainer::logic(); - // Make the player follow the mouse position // if the mouse is dragged elsewhere than in a window. _followMouse(); diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp index 93c65e356..a946f352e 100644 --- a/src/gui/widgets/browserbox.cpp +++ b/src/gui/widgets/browserbox.cpp @@ -111,6 +111,9 @@ BrowserBox::BrowserBox(const Widget2 *const widget, const unsigned int mode, BrowserBox::~BrowserBox() { + if (gui) + gui->removeDragged(this); + mInstances --; if (mInstances == 0 && Theme::instance()) Theme::instance()->unload(mSkin); diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index 16f5b7db3..02e05a643 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -202,6 +202,9 @@ void Button::init() Button::~Button() { + if (gui) + gui->removeDragged(this); + mInstances--; if (mInstances == 0 && Theme::instance()) diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index 77f81f72b..63e73569f 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -80,6 +80,9 @@ CheckBox::CheckBox(const Widget2 *const widget, CheckBox::~CheckBox() { + if (gui) + gui->removeDragged(this); + instances--; if (instances == 0) diff --git a/src/gui/widgets/container.cpp b/src/gui/widgets/container.cpp index 067d54780..066e1c652 100644 --- a/src/gui/widgets/container.cpp +++ b/src/gui/widgets/container.cpp @@ -33,6 +33,9 @@ Container::Container(const Widget2 *const widget) : Container::~Container() { + if (gui) + gui->removeDragged(this); + while (!mWidgets.empty()) delete mWidgets.front(); } diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index 5cffb8d72..daec2e7fa 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -166,6 +166,9 @@ DropDown::DropDown(const Widget2 *const widget, DropDown::~DropDown() { + if (gui) + gui->removeDragged(this); + instances--; if (instances == 0) { diff --git a/src/gui/widgets/guitable.cpp b/src/gui/widgets/guitable.cpp index ec23fda38..42f9c9350 100644 --- a/src/gui/widgets/guitable.cpp +++ b/src/gui/widgets/guitable.cpp @@ -116,6 +116,9 @@ GuiTable::GuiTable(const Widget2 *const widget, GuiTable::~GuiTable() { + if (gui) + gui->removeDragged(this); + uninstallActionListeners(); delete mModel; mModel = nullptr; diff --git a/src/gui/widgets/icon.cpp b/src/gui/widgets/icon.cpp index 8937e202a..61b2611cf 100644 --- a/src/gui/widgets/icon.cpp +++ b/src/gui/widgets/icon.cpp @@ -45,6 +45,12 @@ Icon::Icon(const Widget2 *const widget, Image *const image) : setSize(mImage->mBounds.w, mImage->mBounds.h); } +Icon::~Icon() +{ + if (gui) + gui->removeDragged(this); +} + void Icon::setImage(Image *const image) { mImage = image; diff --git a/src/gui/widgets/icon.h b/src/gui/widgets/icon.h index 4350c7b34..7d681dd8b 100644 --- a/src/gui/widgets/icon.h +++ b/src/gui/widgets/icon.h @@ -52,6 +52,8 @@ class Icon final : public gcn::Widget, A_DELETE_COPY(Icon) + ~Icon(); + /** * Gets the current Image. */ diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index b677ce83a..a6a594c46 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -194,6 +194,9 @@ ItemContainer::ItemContainer(const Widget2 *const widget, ItemContainer::~ItemContainer() { + if (gui) + gui->removeDragged(this); + if (mSelImg) { mSelImg->decRef(); diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp index 13eff1e7d..ad6daa81f 100644 --- a/src/gui/widgets/label.cpp +++ b/src/gui/widgets/label.cpp @@ -46,6 +46,9 @@ Label::Label(const Widget2 *const widget, const std::string &caption) : Label::~Label() { + if (gui) + gui->removeDragged(this); + mInstances --; if (mInstances == 0 && Theme::instance()) Theme::instance()->unload(mSkin); diff --git a/src/gui/widgets/listbox.cpp b/src/gui/widgets/listbox.cpp index b89fc9688..7be2c15c3 100644 --- a/src/gui/widgets/listbox.cpp +++ b/src/gui/widgets/listbox.cpp @@ -64,6 +64,9 @@ ListBox::ListBox(const Widget2 *const widget, ListBox::~ListBox() { + if (gui) + gui->removeDragged(this); + if (Theme::instance()) Theme::instance()->unload(mSkin); } diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp index e6f5965d1..b713365b6 100644 --- a/src/gui/widgets/playerbox.cpp +++ b/src/gui/widgets/playerbox.cpp @@ -60,6 +60,9 @@ PlayerBox::PlayerBox(std::string skin) : PlayerBox::~PlayerBox() { + if (gui) + gui->removeDragged(this); + Theme *const theme = Theme::instance(); if (theme) { diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp index 7b7e088b6..ce5c9c01e 100644 --- a/src/gui/widgets/progressbar.cpp +++ b/src/gui/widgets/progressbar.cpp @@ -78,6 +78,9 @@ ProgressBar::ProgressBar(const Widget2 *const widget, float progress, ProgressBar::~ProgressBar() { + if (gui) + gui->removeDragged(this); + mInstances--; if (mSkin) { diff --git a/src/gui/widgets/progressindicator.cpp b/src/gui/widgets/progressindicator.cpp index c0667f720..6c58af2bf 100644 --- a/src/gui/widgets/progressindicator.cpp +++ b/src/gui/widgets/progressindicator.cpp @@ -51,6 +51,9 @@ ProgressIndicator::ProgressIndicator() : ProgressIndicator::~ProgressIndicator() { + if (gui) + gui->removeDragged(this); + delete mIndicator; mIndicator = nullptr; } diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index 06391217d..a2acf3d69 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -73,6 +73,9 @@ RadioButton::RadioButton(const Widget2 *const widget, RadioButton::~RadioButton() { + if (gui) + gui->removeDragged(this); + instances--; if (instances == 0) diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index 6d15c5520..b143f5c21 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -92,6 +92,9 @@ ScrollArea::ScrollArea(gcn::Widget *const widget, const bool opaque, ScrollArea::~ScrollArea() { + if (gui) + gui->removeDragged(this); + // Garbage collection delete getContent(); diff --git a/src/gui/widgets/shortcutcontainer.cpp b/src/gui/widgets/shortcutcontainer.cpp index cd9bcd7c0..5ebe67a4f 100644 --- a/src/gui/widgets/shortcutcontainer.cpp +++ b/src/gui/widgets/shortcutcontainer.cpp @@ -51,6 +51,9 @@ ShortcutContainer::ShortcutContainer() : ShortcutContainer::~ShortcutContainer() { + if (gui) + gui->removeDragged(this); + delete mVertexes; mVertexes = nullptr; } diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index 2ab5bae99..6e523c4ed 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -58,6 +58,9 @@ Slider::Slider(const double scaleStart, const double scaleEnd) : Slider::~Slider() { + if (gui) + gui->removeDragged(this); + mInstances--; if (mInstances == 0 && Theme::instance()) { diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 18e2510ee..29b2e70c4 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -83,6 +83,9 @@ Tab::Tab(const Widget2 *const widget) : Tab::~Tab() { + if (gui) + gui->removeDragged(this); + mInstances--; if (mInstances == 0 && Theme::instance()) { diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index a805aa5cc..e31d4f6cd 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -70,6 +70,9 @@ TabbedArea::TabbedArea(const Widget2 *const widget) : TabbedArea::~TabbedArea() { + if (gui) + gui->removeDragged(this); + remove(mTabContainer); remove(mWidgetContainer); diff --git a/src/gui/widgets/textbox.cpp b/src/gui/widgets/textbox.cpp index 69c93c025..dec73768e 100644 --- a/src/gui/widgets/textbox.cpp +++ b/src/gui/widgets/textbox.cpp @@ -41,6 +41,12 @@ TextBox::TextBox(const Widget2 *const widget) : setFrameSize(0); } +TextBox::~TextBox() +{ + if (gui) + gui->removeDragged(this); +} + void TextBox::setTextWrapped(const std::string &text, const int minDimension) { // Make sure parent scroll area sets width of this widget diff --git a/src/gui/widgets/textbox.h b/src/gui/widgets/textbox.h index 497d47b7c..1ec11311a 100644 --- a/src/gui/widgets/textbox.h +++ b/src/gui/widgets/textbox.h @@ -47,6 +47,8 @@ class TextBox final : public gcn::TextBox, A_DELETE_COPY(TextBox) + ~TextBox(); + /** * Sets the text after wrapping it to the current width of the widget. */ diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 6997b6d5d..e4568d391 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -92,6 +92,9 @@ TextField::TextField(const Widget2 *const widget, TextField::~TextField() { + if (gui) + gui->removeDragged(this); + delete mPopupMenu; mPopupMenu = nullptr; diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp index 8f0fa6104..d7885930d 100644 --- a/src/gui/widgets/textpreview.cpp +++ b/src/gui/widgets/textpreview.cpp @@ -65,6 +65,9 @@ TextPreview::TextPreview(const Widget2 *const widget, TextPreview::~TextPreview() { + if (gui) + gui->removeDragged(this); + instances--; if (instances == 0) diff --git a/src/gui/widgets/widget2.h b/src/gui/widgets/widget2.h index 29ab2c11f..d8d158cf2 100644 --- a/src/gui/widgets/widget2.h +++ b/src/gui/widgets/widget2.h @@ -23,6 +23,8 @@ #include "gui/theme.h" +#include "gui/gui.h" + class Widget2 { public: diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 7d80464d9..926821f18 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -156,6 +156,9 @@ Window::~Window() { logger->log("Window::~Window(\"%s\")", getCaption().c_str()); + if (gui) + gui->removeDragged(this); + Client::windowRemoved(this); saveWindowState(); diff --git a/src/gui/widgets/windowcontainer.cpp b/src/gui/widgets/windowcontainer.cpp index 2447e12e4..bb43a6261 100644 --- a/src/gui/widgets/windowcontainer.cpp +++ b/src/gui/widgets/windowcontainer.cpp @@ -35,14 +35,10 @@ WindowContainer::WindowContainer(const Widget2 *const widget) : { } -void WindowContainer::logic() +void WindowContainer::slowLogic() { - BLOCK_START("WindowContainer::logic") delete_all(mDeathList); mDeathList.clear(); - - gcn::Container::logic(); - BLOCK_END("WindowContainer::logic") } void WindowContainer::scheduleDelete(gcn::Widget *const widget) diff --git a/src/gui/widgets/windowcontainer.h b/src/gui/widgets/windowcontainer.h index cee1178e8..660d2ab8a 100644 --- a/src/gui/widgets/windowcontainer.h +++ b/src/gui/widgets/windowcontainer.h @@ -38,11 +38,7 @@ class WindowContainer : public Container public: WindowContainer(const Widget2 *const widget); - /** - * Do GUI logic. This functions adds automatic deletion of objects that - * volunteered to be deleted. - */ - void logic() override; + void slowLogic(); /** * Schedule a widget for deletion. It will be deleted at the start of |