#include #include #include #include #include #include #include #include #include #include #include #include #include bool is_valid_url(const std::string & url); void open_url(const std::string & url); void search(); void page_scroll(int scroll); class Main; void get_window_id(); uint32_t parent_id = 0; bool is_valid_url(const std::string & url) { std::regex r(".*://.*\\..*"); std::smatch m; return std::regex_match(url, m, r); } QWebEngineView * web; Main * view; Display * dpy; class Main : public QMainWindow { protected: void keyPressEvent(QKeyEvent * event) { if (event->text() == "o") search(); else if (event->text() == "j") page_scroll(20); else if (event->text() == "k") page_scroll(-20); else if (event->text() == "H") web->back(); else if (event->text() == "L") web->forward(); else if (event->text() == "r") web->reload(); } }; std::string read_from_dmenu() { std::string output; std::string cmd = "printf '' | dmenu -p 'open: ' -w "; cmd += std::to_string(view->winId()); FILE * f = popen(cmd.c_str(), "r"); char string[8092] = {0}; fgets(string, 8092, f); fclose(f); if (string[0] != 0) { output = string; output.pop_back(); } return output; } void open_url(const std::string & url) { web->load(QString::fromStdString(url)); } void search() { auto url = read_from_dmenu(); if (url.empty()) return; if (is_valid_url(url)) { open_url(url); return; } if (is_valid_url("https://" + url)) { open_url("https://" + url); return; } open_url("https://duckduckgo.com/?q=" + url); } void page_scroll(int scroll) { std::string js = "window.scrollBy(0, " + std::to_string(scroll) + ");"; web->page()->runJavaScript(QString::fromStdString(js)); } void help(char *arg0) { std::cout << arg0 << '\n'; std::cout << "-e [xid] - embed in other X window\n"; } int main(int argc, char **argv) { QApplication app(argc, argv); view = new Main(); web = new QWebEngineView(); std::cout << getenv("WWW_HOME") << '\n'; web->load(QUrl(getenv("WWW_HOME"))); if (argc == 3) { if (argv[1] == std::string("-e")) { dpy = XOpenDisplay(NULL); parent_id = std::stoi(argv[2]); XReparentWindow(dpy, view->winId(), parent_id, 0, 0); XFlush(dpy); } else { help(argv[0]); } } else if (argc != 1) { help(argv[0]); } view->show(); view->setCentralWidget(web); web->connect(web, &QWebEngineView::titleChanged, [&](const QString & title) { view->setWindowTitle(title); }); if (parent_id != 0) { web->setContextMenuPolicy(Qt::CustomContextMenu); web->connect(web, &QWebEngineView::customContextMenuRequested, [&](){ auto menu = web->page()->createStandardContextMenu(); menu->popup(QCursor::pos()); return menu; }); } return app.exec(); }