#include #include #include #include #include #include #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); void goto_end(bool end); void get_window_id(); void history_move(bool back); void reload(); uint32_t parent_id = 0; #include "webengine.hpp" #include "config.hpp" bool is_valid_url(const std::string & url) { std::regex r(".*://.*\\..*"); std::smatch m; return std::regex_match(url, m, r); } QWebEngineView * web; QMainWindow * view; Display * dpy; std::string read_from_dmenu() { std::string output; std::string cmd = std::string("printf '' | dmenu -p 'open: ' ") + dmenu_args + " -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; } inline void __web_load(const std::string &url) { web->load(QString::fromStdString(url)); } void open_url(const std::string & url) { if (url.empty()) return; if (is_valid_url(url)) { __web_load(url); return; } if (is_valid_url("https://" + url)) { __web_load("https://" + url); return; } __web_load(search_engine + url); } void search() { auto url = read_from_dmenu(); open_url(url); } void page_scroll(int scroll) { std::string js = "window.scrollBy({ top: " + std::to_string(scroll) + ", behavior: 'smooth' });"; web->page()->runJavaScript(QString::fromStdString(js)); } void goto_end(bool end) { std::string js; if (end) js = "window.scroll({ top: document.body.scrollHeight, behavior: 'smooth' })"; else js = "window.scroll({ top: 0, behavior: 'smooth' })"; web->page()->runJavaScript(QString::fromStdString(js)); } void history_move(bool back) { if (back) web->back(); else web->forward(); } void reload() { web->reload(); } void help(char *arg0) { std::cout << arg0; std::cout << " [url] [-e ]\n"; exit(-1); } int main(int argc, char **argv) { QApplication app(argc, argv); QWebEngineProfile profile; WebEnginePage page(&profile); QProgressBar progressbar; QLabel url_label; QWidget *main = new QWidget; QVBoxLayout layout(main); std::string url = getenv("WWW_HOME"); bool url_set_by_arg = false; view = new QMainWindow(); web = new QWebEngineView(); web->setPage(&page); page.setBackgroundColor(QColor(40, 40, 40)); progressbar.setMaximum(100); progressbar.setMinimum(0); progressbar.setTextVisible(false); progressbar.setMaximumHeight(10); progressbar.setStyleSheet("QProgressBar::chunk { background: #b16286; border-radius: 0px }"); url_label.setMaximumHeight(30); url_label.setMargin(5); url_label.setStyleSheet("QLabel { background: #1d2021; color: #ebdbb2 }"); for (int i = 1; i < argc; ++i) { if (argv[i] == std::string("-e")) { if (++i == argc || (argv[i][0] < '0' || argv[i][0] > '9')) help(argv[0]); dpy = XOpenDisplay(NULL); parent_id = std::stoi(argv[i]); XReparentWindow(dpy, view->winId(), parent_id, 0, 0); XFlush(dpy); } else if (!url_set_by_arg) { url = argv[i]; url_set_by_arg = true; } else { help(argv[0]); } } open_url(url); layout.setContentsMargins(0, 0, 0, 0); layout.setSpacing(0); layout.addWidget(web); layout.addWidget(&progressbar); layout.addWidget(&url_label); view->setCentralWidget(main); view->show(); 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; }); } web->connect(web, &QWebEngineView::loadProgress, [&](int progress) { progressbar.show(); progressbar.setValue(progress); }); web->connect(web, &QWebEngineView::loadFinished, [&](bool ok) { progressbar.hide(); }); web->connect(web, &QWebEngineView::urlChanged, [&](const QUrl & url) { url_label.setText(url.toString()); }); register_shortcuts(view); return app.exec(); }