diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2017-08-06 22:12:08 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2017-08-06 22:24:59 +0200 |
| commit | 9d586aec3a5615377e389318e97e7d756c970c96 (patch) | |
| tree | 8f2bf46ab5020a97482fbe87b6f1337842c70a19 /src | |
| parent | be1dc86b5434e84a88ba2e62873d87c62f8880c0 (diff) | |
Make sure QtLooper doesn't use QSocketNotifier before QApplication is created
Diffstat (limited to 'src')
| -rw-r--r-- | src/gui_gtk.cc | 11 | ||||
| -rw-r--r-- | src/gui_main.hh | 2 | ||||
| -rw-r--r-- | src/gui_qt.cc | 80 | ||||
| -rw-r--r-- | src/monitor-gui.cc | 2 |
4 files changed, 73 insertions, 22 deletions
diff --git a/src/gui_gtk.cc b/src/gui_gtk.cc index 2056034..20a6147 100644 --- a/src/gui_gtk.cc +++ b/src/gui_gtk.cc @@ -593,6 +593,8 @@ public: config_(new GtkConfig()), menu_(nullptr), statusbar_(nullptr) { } + Looper* create_looper() override; + void set_menu(GuiMenu* menu) override { assert(menu); menu_ = menu; @@ -2353,6 +2355,10 @@ private: std::unordered_map<int, std::unique_ptr<Fd>> fds_; }; +Looper* GtkGuiMain::create_looper() { + return new GtkLooper(); +} + } // namespace // static @@ -2433,11 +2439,6 @@ GuiMessage* GuiMessage::create(Type type, } // static -Looper* GuiMain::createLooper() { - return new GtkLooper(); -} - -// static AttributedText* AttributedText::create() { return new GtkAttributedText(); } diff --git a/src/gui_main.hh b/src/gui_main.hh index d56804c..1070c0d 100644 --- a/src/gui_main.hh +++ b/src/gui_main.hh @@ -34,7 +34,7 @@ public: static GuiMain* create(std::string const& title, uint32_t width, uint32_t height); - static Looper* createLooper(); + virtual Looper* create_looper() = 0; virtual void set_menu(GuiMenu* menu) = 0; virtual GuiMenu* menu() const = 0; diff --git a/src/gui_qt.cc b/src/gui_qt.cc index 0abc052..fe9d1c4 100644 --- a/src/gui_qt.cc +++ b/src/gui_qt.cc @@ -450,12 +450,16 @@ QString show_file_dialog(QWidget* parent, std::string const& title, class QtGuiMain : public GuiMain, public QtGuiWindow { public: + typedef std::function<void(GuiMain*)> RunWhenStartedCallback; + QtGuiMain(std::string const& title, uint32_t width, uint32_t height) : title_(title), width_(width), height_(height), split_(0.7), menu_(nullptr), statusbar_(nullptr), config_(new QtGuiConfig()), - splitter_(nullptr), top_(nullptr), bottom_(nullptr) { + splitter_(nullptr), top_(nullptr), bottom_(nullptr), started_(false) { } + Looper* create_looper() override; + void set_menu(GuiMenu* menu) override { menu_ = static_cast<QtGuiMenu*>(menu); } @@ -592,6 +596,14 @@ public: return ret.isNull() ? "" : ret.toStdString(); } + void run_when_started(RunWhenStartedCallback const& callback) { + if (started_) { + callback(this); + return; + } + run_when_started_.emplace_back(callback); + } + private: static bool valid_utf8(std::string const& data) { QTextCodec::ConverterState state; @@ -629,6 +641,15 @@ private: } } + void start() { + assert(!started_); + started_ = true; + for (auto& callback : run_when_started_) { + callback(this); + } + run_when_started_.clear(); + } + std::string title_; uint32_t width_; uint32_t height_; @@ -645,6 +666,8 @@ private: QSplitter* splitter_; QWidget* top_; QTextEdit* bottom_; + bool started_; + std::vector<RunWhenStartedCallback> run_when_started_; }; class QtChildGuiMenu : public QtCommonMenu { @@ -1659,6 +1682,8 @@ bool QtGuiMain::run(int argc, char** argv) { app.setApplicationName(QString::fromStdString(title_)); app.setApplicationVersion(VERSION); + start(); + QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); @@ -1729,14 +1754,20 @@ bool QtGuiMain::run(int argc, char** argv) { class QtLooper : public Looper { public: - QtLooper() { + QtLooper(QtGuiMain* main) + : init_(false) { + main->run_when_started([=](GuiMain*) { + init(); + }); } void add(int fd, uint8_t events, FdCallback const& callback) override { auto& handle = fds_[fd]; handle.reset(new Fd(fd, callback)); - handle->read_->setEnabled(events & EVENT_READ); - handle->write_->setEnabled(events & EVENT_WRITE); + handle->events_ = events; + if (init_) { + handle->init(); + } } void modify(int fd, uint8_t events) override { @@ -1746,8 +1777,12 @@ public: return; } auto& handle = it->second; - handle->read_->setEnabled(events & EVENT_READ); - handle->write_->setEnabled(events & EVENT_WRITE); + if (init_) { + handle->read_->setEnabled(events & EVENT_READ); + handle->write_->setEnabled(events & EVENT_WRITE); + } else { + handle->events_ = events; + } } void remove(int fd) override { @@ -1757,7 +1792,7 @@ public: return; } auto& handle = it->second; - if (handle->in_callback_) { + if (init_ && handle->in_callback_) { handle.release()->delayed_delete_ = true; } fds_.erase(fd); @@ -1798,6 +1833,8 @@ public: private: struct Fd { + int fd_; + uint8_t events_; FdCallback callback_; std::unique_ptr<QSocketNotifier> read_; std::unique_ptr<QSocketNotifier> write_; @@ -1805,15 +1842,22 @@ private: bool delayed_delete_; Fd(int fd, FdCallback const& fd_callback) - : callback_(fd_callback), - read_(new QSocketNotifier(fd, QSocketNotifier::Read)), - write_(new QSocketNotifier(fd, QSocketNotifier::Write)), + : fd_(fd), + events_(0), + callback_(fd_callback), in_callback_(false), delayed_delete_(false) { + } + + void init() { + read_.reset(new QSocketNotifier(fd_, QSocketNotifier::Read)); + write_.reset(new QSocketNotifier(fd_, QSocketNotifier::Write)); QObject::connect(read_.get(), &QSocketNotifier::activated, [=](int fd) { callback(fd, EVENT_READ); }); QObject::connect(write_.get(), &QSocketNotifier::activated, [=](int fd) { callback(fd, EVENT_WRITE); }); + read_->setEnabled(events_ & EVENT_READ); + write_->setEnabled(events_ & EVENT_WRITE); } void callback(int fd, uint8_t events) { @@ -1831,10 +1875,21 @@ private: } }; + void init() { + for (auto& pair : fds_) { + pair.second->init(); + } + } + + bool init_; std::unordered_map<int, std::unique_ptr<Fd>> fds_; std::unordered_set<QTimer*> timers_; }; +Looper* QtGuiMain::create_looper() { + return new QtLooper(this); +} + } // namespace // static @@ -1913,11 +1968,6 @@ GuiMessage* GuiMessage::create(Type type, } // static -Looper* GuiMain::createLooper() { - return new QtLooper(); -} - -// static AttributedText* AttributedText::create() { return HtmlAttributedText::create(); } diff --git a/src/monitor-gui.cc b/src/monitor-gui.cc index 7cb6ab3..66c5e43 100644 --- a/src/monitor-gui.cc +++ b/src/monitor-gui.cc @@ -673,7 +673,7 @@ public: main_(GuiMain::create(APP_TITLE, 800, 500)), menu_(GuiMenu::create()), statusbar_(GuiStatusBar::create()), - looper_(main_->createLooper()), + looper_(main_->create_looper()), has_selection_(false), has_related_(false), selection_(0), |
