summaryrefslogtreecommitdiff
path: root/src/gui_qt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui_qt.cc')
-rw-r--r--src/gui_qt.cc80
1 files changed, 65 insertions, 15 deletions
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();
}