diff --git a/www-client/falkon/0001-Load-markers-and-test.patch b/www-client/falkon/0001-Load-markers-and-test.patch new file mode 100644 index 0000000..b495097 --- /dev/null +++ b/www-client/falkon/0001-Load-markers-and-test.patch @@ -0,0 +1,78 @@ +From 9f5d59938267f897628b911acb42c15c2896007f Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Tue, 17 Jun 2025 11:12:02 -0400 +Subject: [PATCH 01/16] Load markers and test + +--- + src/lib/data/html.qrc | 1 + + src/lib/webengine/webpage.cpp | 6 ++++++ + src/lib/webengine/webpage.h | 2 ++ + src/lib/webengine/webview.cpp | 3 +++ + 4 files changed, 12 insertions(+) + +diff --git a/src/lib/data/html.qrc b/src/lib/data/html.qrc +index 34f890a2e..ecd44d677 100644 +--- a/src/lib/data/html.qrc ++++ b/src/lib/data/html.qrc +@@ -11,6 +11,7 @@ + html/config.html + html/restore.html + html/restore.user.js ++ html/marker.js + html/tabcrash.html + html/close.svg + html/configure.svg +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index 0794b092b..92c6300b8 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -305,6 +305,8 @@ void WebPage::finished() + + // AutoFill + m_autoFillUsernames = mApp->autoFill()->completePage(this, url()); ++ // inject marker.js ++ runJavaScript(QzTools::readAllFileContents(QSL(":html/marker.js"))); + } + + void WebPage::watchedFileChanged(const QString &file) +@@ -314,6 +316,10 @@ void WebPage::watchedFileChanged(const QString &file) + } + } + ++void WebPage::getLinkMarkers() { ++ runJavaScript(QLatin1String("Marker.generateMarker('a, input, button, [class*=\"btn\"], [aria-haspopup], [role=\"button\"], textarea, select, summary, [class=\"gap\"], [ng-click]')")); ++} ++ + void WebPage::handleUnknownProtocol(const QUrl &url) + { + const QString protocol = url.scheme(); +diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h +index 3f9bf151a..7db16f2cb 100644 +--- a/src/lib/webengine/webpage.h ++++ b/src/lib/webengine/webpage.h +@@ -78,6 +78,8 @@ public: + static void addSupportedScheme(const QString &scheme); + static void removeSupportedScheme(const QString &scheme); + ++ void getLinkMarkers(); ++ + Q_SIGNALS: + void privacyChanged(bool status); + void printRequested(); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index 4871e8b3f..56e3461be 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1234,6 +1234,9 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + event->accept(); + } + break; ++ case Qt::Key_F: ++ page()->getLinkMarkers(); ++ event->accept(); + + default: + break; +-- +2.53.0 + diff --git a/www-client/falkon/0001-Zoom-in-out-with-Plus-and-Minus.patch b/www-client/falkon/0001-Zoom-in-out-with-Plus-and-Minus.patch deleted file mode 100644 index c5357f7..0000000 --- a/www-client/falkon/0001-Zoom-in-out-with-Plus-and-Minus.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 05288a5f93c8d7123a807884ba2c003b7bcd9da2 Mon Sep 17 00:00:00 2001 -From: Jacopo De Simoi -Date: Tue, 5 Feb 2019 21:49:30 -0500 -Subject: [PATCH 01/19] Zoom in/out with Plus and Minus - ---- - src/lib/webengine/webview.cpp | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) - -diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp -index 0d68da7bb..ff0b5fb68 100644 ---- a/src/lib/webengine/webview.cpp -+++ b/src/lib/webengine/webview.cpp -@@ -1159,29 +1159,17 @@ void WebView::_keyPressEvent(QKeyEvent *event) - - switch (event->key()) { - case Qt::Key_ZoomIn: -+ case Qt::Key_Plus: - zoomIn(); - event->accept(); - break; - - case Qt::Key_ZoomOut: -+ case Qt::Key_Minus: - zoomOut(); - event->accept(); - break; - -- case Qt::Key_Plus: -- if (event->modifiers() & Qt::ControlModifier) { -- zoomIn(); -- event->accept(); -- } -- break; -- -- case Qt::Key_Minus: -- if (event->modifiers() & Qt::ControlModifier) { -- zoomOut(); -- event->accept(); -- } -- break; -- - case Qt::Key_0: - if (event->modifiers() & Qt::ControlModifier) { - zoomReset(); --- -2.41.0 - diff --git a/www-client/falkon/0002-Add-method-to-cleanup-link-markers.patch b/www-client/falkon/0002-Add-method-to-cleanup-link-markers.patch new file mode 100644 index 0000000..7b598d1 --- /dev/null +++ b/www-client/falkon/0002-Add-method-to-cleanup-link-markers.patch @@ -0,0 +1,132 @@ +From 639d16e98ca076d1b29b42ac5824eaffec16331a Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Tue, 22 Jul 2025 16:06:35 +0200 +Subject: [PATCH 02/16] Add method to cleanup link markers + +--- + src/lib/webengine/webpage.cpp | 5 ++++ + src/lib/webengine/webpage.h | 3 +- + src/lib/webengine/webview.cpp | 55 ++++++++++++++++++++--------------- + src/lib/webengine/webview.h | 1 + + 4 files changed, 39 insertions(+), 25 deletions(-) + +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index 92c6300b8..e14c51ba4 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -320,6 +320,11 @@ void WebPage::getLinkMarkers() { + runJavaScript(QLatin1String("Marker.generateMarker('a, input, button, [class*=\"btn\"], [aria-haspopup], [role=\"button\"], textarea, select, summary, [class=\"gap\"], [ng-click]')")); + } + ++void WebPage::clearLinkMarkers() { ++ runJavaScript("document.querySelector('.eaf-marker-container').remove();"); ++ runJavaScript("document.querySelector('.eaf-style').remove();"); ++} ++ + void WebPage::handleUnknownProtocol(const QUrl &url) + { + const QString protocol = url.scheme(); +diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h +index 7db16f2cb..3cfdbb38e 100644 +--- a/src/lib/webengine/webpage.h ++++ b/src/lib/webengine/webpage.h +@@ -79,8 +79,9 @@ public: + static void removeSupportedScheme(const QString &scheme); + + void getLinkMarkers(); ++ void clearLinkMarkers(); + +-Q_SIGNALS: ++ Q_SIGNALS: + void privacyChanged(bool status); + void printRequested(); + void navigationRequestAccepted(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index 56e3461be..01f402a75 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -54,30 +54,30 @@ + + bool WebView::s_forceContextMenuOnMouseRelease = false; + +-WebView::WebView(QWidget* parent) +- : QWebEngineView(parent) +- , m_progress(100) +- , m_backgroundActivity(false) +- , m_page(nullptr) +- , m_firstLoad(false) +-{ +- connect(this, &QWebEngineView::loadStarted, this, &WebView::slotLoadStarted); +- connect(this, &QWebEngineView::loadProgress, this, &WebView::slotLoadProgress); +- connect(this, &QWebEngineView::loadFinished, this, &WebView::slotLoadFinished); +- connect(this, &QWebEngineView::iconChanged, this, &WebView::slotIconChanged); +- connect(this, &QWebEngineView::urlChanged, this, &WebView::slotUrlChanged); +- connect(this, &QWebEngineView::titleChanged, this, &WebView::slotTitleChanged); +- connect(this, &QWebEngineView::printFinished, this, &WebView::slotPrintFinished); +- +- m_currentZoomLevel = zoomLevels().indexOf(100); +- +- setAcceptDrops(true); +- installEventFilter(this); +- if (parentWidget()) { +- parentWidget()->installEventFilter(this); +- } +- +- WebInspector::registerView(this); ++WebView::WebView(QWidget *parent) ++ : QWebEngineView(parent), m_progress(100), m_backgroundActivity(false), ++ m_page(nullptr), m_firstLoad(false), m_followLink(false) { ++ connect(this, &QWebEngineView::loadStarted, this, &WebView::slotLoadStarted); ++ connect(this, &QWebEngineView::loadProgress, this, ++ &WebView::slotLoadProgress); ++ connect(this, &QWebEngineView::loadFinished, this, ++ &WebView::slotLoadFinished); ++ connect(this, &QWebEngineView::iconChanged, this, &WebView::slotIconChanged); ++ connect(this, &QWebEngineView::urlChanged, this, &WebView::slotUrlChanged); ++ connect(this, &QWebEngineView::titleChanged, this, ++ &WebView::slotTitleChanged); ++ connect(this, &QWebEngineView::printFinished, this, ++ &WebView::slotPrintFinished); ++ ++ m_currentZoomLevel = zoomLevels().indexOf(100); ++ ++ setAcceptDrops(true); ++ installEventFilter(this); ++ if (parentWidget()) { ++ parentWidget()->installEventFilter(this); ++ } ++ ++ WebInspector::registerView(this); + } + + WebView::~WebView() +@@ -1235,7 +1235,14 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + } + break; + case Qt::Key_F: ++ if (!m_followLink) { + page()->getLinkMarkers(); ++ m_followLink = true; ++ } else { ++ page()->clearLinkMarkers(); ++ m_followLink = false; ++ } ++ + event->accept(); + + default: +diff --git a/src/lib/webengine/webview.h b/src/lib/webengine/webview.h +index 61e7281f8..bec16ea25 100644 +--- a/src/lib/webengine/webview.h ++++ b/src/lib/webengine/webview.h +@@ -190,6 +190,7 @@ private: + + WebPage* m_page; + bool m_firstLoad; ++ bool m_followLink; + + QPointer m_rwhvqt; + WheelHelper m_wheelHelper; +-- +2.53.0 + diff --git a/www-client/falkon/0002-Zoom-in-with-too.patch b/www-client/falkon/0002-Zoom-in-with-too.patch deleted file mode 100644 index 2212bc3..0000000 --- a/www-client/falkon/0002-Zoom-in-with-too.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1bce476a2b27e442f54af15e94b4805addd29272 Mon Sep 17 00:00:00 2001 -From: Jacopo De Simoi -Date: Tue, 5 Feb 2019 21:50:51 -0500 -Subject: [PATCH 02/19] Zoom in with = too - ---- - src/lib/webengine/webview.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp -index ff0b5fb68..4047e24dc 100644 ---- a/src/lib/webengine/webview.cpp -+++ b/src/lib/webengine/webview.cpp -@@ -1160,6 +1160,7 @@ void WebView::_keyPressEvent(QKeyEvent *event) - switch (event->key()) { - case Qt::Key_ZoomIn: - case Qt::Key_Plus: -+ case Qt::Key_Equal: - zoomIn(); - event->accept(); - break; --- -2.41.0 - diff --git a/www-client/falkon/0003-Back-Forward-with-c-v.patch b/www-client/falkon/0003-Back-Forward-with-c-v.patch deleted file mode 100644 index ac76132..0000000 --- a/www-client/falkon/0003-Back-Forward-with-c-v.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d7ceeb8ec5e4774d84f33bcdb4f20fc8132bcdfb Mon Sep 17 00:00:00 2001 -From: Jacopo De Simoi -Date: Tue, 5 Feb 2019 22:02:11 -0500 -Subject: [PATCH 03/19] Back/Forward with c/v - ---- - src/lib/app/browserwindow.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp -index bf1381d73..8f432415b 100644 ---- a/src/lib/app/browserwindow.cpp -+++ b/src/lib/app/browserwindow.cpp -@@ -1270,6 +1270,7 @@ void BrowserWindow::keyPressEvent(QKeyEvent* event) - - switch (event->key()) { - case Qt::Key_Back: -+ case Qt::Key_C: - if (view) { - view->back(); - event->accept(); -@@ -1277,6 +1278,7 @@ void BrowserWindow::keyPressEvent(QKeyEvent* event) - break; - - case Qt::Key_Forward: -+ case Qt::Key_V: - if (view) { - view->forward(); - event->accept(); --- -2.41.0 - diff --git a/www-client/falkon/0003-fix-compilation-squash.patch b/www-client/falkon/0003-fix-compilation-squash.patch new file mode 100644 index 0000000..1cec113 --- /dev/null +++ b/www-client/falkon/0003-fix-compilation-squash.patch @@ -0,0 +1,27 @@ +From 71cde1693896f99c8cd8b958abe20195cc57fe3e Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Tue, 22 Jul 2025 16:11:20 +0200 +Subject: [PATCH 03/16] fix compilation --- squash + +--- + src/lib/webengine/webpage.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index e14c51ba4..92796df43 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -321,8 +321,8 @@ void WebPage::getLinkMarkers() { + } + + void WebPage::clearLinkMarkers() { +- runJavaScript("document.querySelector('.eaf-marker-container').remove();"); +- runJavaScript("document.querySelector('.eaf-style').remove();"); ++ runJavaScript(QLatin1String("document.querySelector('.eaf-marker-container').remove();")); ++ runJavaScript(QLatin1String("document.querySelector('.eaf-style').remove();")); + } + + void WebPage::handleUnknownProtocol(const QUrl &url) +-- +2.53.0 + diff --git a/www-client/falkon/0004-Use-standard-wording-for-show-hide-in-Qt.patch b/www-client/falkon/0004-Use-standard-wording-for-show-hide-in-Qt.patch new file mode 100644 index 0000000..8b38c0a --- /dev/null +++ b/www-client/falkon/0004-Use-standard-wording-for-show-hide-in-Qt.patch @@ -0,0 +1,64 @@ +From c6ee23bb6cdb9fc84f19017ea55d1c000c55d0f0 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 17 Dec 2025 14:44:51 -0500 +Subject: [PATCH 04/16] Use standard wording for show/hide in Qt + +--- + src/lib/webengine/webpage.cpp | 4 ++-- + src/lib/webengine/webpage.h | 4 ++-- + src/lib/webengine/webview.cpp | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index 92796df43..c269f9666 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -316,11 +316,11 @@ void WebPage::watchedFileChanged(const QString &file) + } + } + +-void WebPage::getLinkMarkers() { ++void WebPage::showLinkMarkers() { + runJavaScript(QLatin1String("Marker.generateMarker('a, input, button, [class*=\"btn\"], [aria-haspopup], [role=\"button\"], textarea, select, summary, [class=\"gap\"], [ng-click]')")); + } + +-void WebPage::clearLinkMarkers() { ++void WebPage::hideLinkMarkers() { + runJavaScript(QLatin1String("document.querySelector('.eaf-marker-container').remove();")); + runJavaScript(QLatin1String("document.querySelector('.eaf-style').remove();")); + } +diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h +index 3cfdbb38e..2b459bfd4 100644 +--- a/src/lib/webengine/webpage.h ++++ b/src/lib/webengine/webpage.h +@@ -78,8 +78,8 @@ public: + static void addSupportedScheme(const QString &scheme); + static void removeSupportedScheme(const QString &scheme); + +- void getLinkMarkers(); +- void clearLinkMarkers(); ++ void showLinkMarkers(); ++ void hideLinkMarkers(); + + Q_SIGNALS: + void privacyChanged(bool status); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index 01f402a75..c91ac1e7a 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1236,10 +1236,10 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + break; + case Qt::Key_F: + if (!m_followLink) { +- page()->getLinkMarkers(); ++ page()->showLinkMarkers(); + m_followLink = true; + } else { +- page()->clearLinkMarkers(); ++ page()->hideLinkMarkers(); + m_followLink = false; + } + +-- +2.53.0 + diff --git a/www-client/falkon/0005-Clear-link-markers-when-needed.patch b/www-client/falkon/0005-Clear-link-markers-when-needed.patch new file mode 100644 index 0000000..2ad1cca --- /dev/null +++ b/www-client/falkon/0005-Clear-link-markers-when-needed.patch @@ -0,0 +1,72 @@ +From 6af474b8550a75a0f8e4e84782875107e6522746 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Fri, 19 Dec 2025 09:13:05 -0500 +Subject: [PATCH 05/16] Clear link markers when needed + +--- + src/lib/webengine/webpage.cpp | 3 +++ + src/lib/webengine/webpage.h | 4 +++- + src/lib/webengine/webview.cpp | 2 ++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index c269f9666..4a953ae23 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -105,6 +105,8 @@ WebPage::WebPage(QObject* parent) + connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, [this](const QUrl &, QAuthenticator *auth, const QString &proxyHost) { + mApp->networkManager()->proxyAuthentication(proxyHost, auth, view()); + }); ++ connect(this, &QWebEnginePage::scrollPositionChanged, this, &WebPage::hideLinkMarkers); ++ connect(this, &QWebEnginePage::contentsSizeChanged, this, &WebPage::hideLinkMarkers); + + // Workaround QWebEnginePage not scrolling to anchors when opened in background tab + m_contentsResizedConnection = connect(this, &QWebEnginePage::contentsSizeChanged, this, [this]() { +@@ -323,6 +325,7 @@ void WebPage::showLinkMarkers() { + void WebPage::hideLinkMarkers() { + runJavaScript(QLatin1String("document.querySelector('.eaf-marker-container').remove();")); + runJavaScript(QLatin1String("document.querySelector('.eaf-style').remove();")); ++ Q_EMIT linkMarkersCleared(); + } + + void WebPage::handleUnknownProtocol(const QUrl &url) +diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h +index 2b459bfd4..ad8739801 100644 +--- a/src/lib/webengine/webpage.h ++++ b/src/lib/webengine/webpage.h +@@ -79,16 +79,18 @@ public: + static void removeSupportedScheme(const QString &scheme); + + void showLinkMarkers(); +- void hideLinkMarkers(); + + Q_SIGNALS: + void privacyChanged(bool status); + void printRequested(); + void navigationRequestAccepted(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame); ++ void linkMarkersCleared(); + + protected Q_SLOTS: + void progress(int prog); + void finished(); ++ void hideLinkMarkers(); ++ + + private Q_SLOTS: + void urlChanged(const QUrl &url); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index c91ac1e7a..c6e52dfa5 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -161,6 +161,8 @@ void WebView::setPage(WebPage *page) + + connect(m_page, &WebPage::privacyChanged, this, &WebView::privacyChanged); + connect(m_page, &WebPage::printRequested, this, &WebView::printPage); ++ connect(m_page, &WebPage::linkMarkersCleared, ++ [=]() {m_followLink = false;}); + + // Set default zoom level + zoomReset(); +-- +2.53.0 + diff --git a/www-client/falkon/0006-add-the-forgotten-js-file.patch b/www-client/falkon/0006-add-the-forgotten-js-file.patch new file mode 100644 index 0000000..f9136e2 --- /dev/null +++ b/www-client/falkon/0006-add-the-forgotten-js-file.patch @@ -0,0 +1,306 @@ +From 02be1f34051e681d35cf4e7f0d04b2d841a12380 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Fri, 19 Dec 2025 09:32:02 -0500 +Subject: [PATCH 06/16] add the forgotten js file + +--- + src/lib/data/html/marker.js | 287 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 287 insertions(+) + create mode 100644 src/lib/data/html/marker.js + +diff --git a/src/lib/data/html/marker.js b/src/lib/data/html/marker.js +new file mode 100644 +index 000000000..d04075029 +--- /dev/null ++++ b/src/lib/data/html/marker.js +@@ -0,0 +1,287 @@ ++(function(_) { ++ let self; ++ _.Marker = self = {}; ++ ++ ++ function getVisibleElements(filter) { ++ let all = Array.from(document.documentElement.getElementsByTagName("*")); ++ let visibleElements = []; ++ for (let i = 0; i < all.length; i++) { ++ let e = all[i]; ++ // include elements in a shadowRoot. ++ if (e.shadowRoot) { ++ let cc = e.shadowRoot.querySelectorAll('*'); ++ for (let j = 0; j < cc.length; j++) { ++ all.push(cc[j]); ++ } ++ } ++ let rect = e.getBoundingClientRect(); ++ if ( (rect.top <= window.innerHeight) && (rect.bottom >= 0) ++ && (rect.left <= window.innerWidth) && (rect.right >= 0) ++ && rect.height > 0 ++ && getComputedStyle(e).visibility !== 'hidden' ++ ) { ++ filter(e, visibleElements); ++ } ++ } ++ return visibleElements; ++ } ++ ++ function moveCursorToEnd(el) { ++ if (typeof el.selectionStart == "number") { ++ el.selectionStart = el.selectionEnd = el.value.length; ++ } else if (typeof el.createTextRange != "undefined") { ++ el.focus(); ++ let range = el.createTextRange(); ++ range.collapse(false); ++ range.select(); ++ } ++ } ++ ++ function cssSelector(el) { ++ let path = [], parent; ++ while (parent = el.parentNode) { ++ path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el)+1})`); ++ el = parent; ++ } ++ return `${path.join(' > ')}`.toLowerCase(); ++ } ++ ++ function getCoords(node){ ++ if (node.getBoundingClientRect){ ++ let rect = node.getBoundingClientRect(); ++ return [ rect.top, rect.left, rect.right, rect.bottom, cssSelector(node) ]; ++ } ++ ++ return getCoords(node.parentNode); // TextNode not define getBoundingClientRect ++ } ++ ++ function isElementOnScreen(rect){ ++ let clientHeight = document.documentElement.clientHeight; ++ let clientWidth = document.documentElement.clientWidth; ++ return (rect[0] >= 0 && rect[0] <= clientHeight && ++ rect[1] >= 0 && rect[1] <= clientWidth && ++ rect[2] != 0 && rect[3] != 0); ++ } ++ ++ function isElementOnTop(element, rect){ ++ let topElement = document.elementFromPoint((rect[1] + rect[2])/2, (rect[0] + rect[3])/2); ++ return topElement != undefined && (element.isSameNode(topElement) || element.contains(topElement) || topElement.contains(element)); ++ } ++ ++ function hasCopy(validRects, rect){ ++ for(let i = 0; i < validRects.length; i++) { ++ let each = validRects[i]; ++ if(each[0] === rect[0] && each[1] === rect[1]){ ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ function addElementToRects(validRects, elements){ ++ let rect; ++ for(let i = 0; i < elements.length; i++) { ++ rect = getCoords(elements[i]); ++ if(!hasCopy(validRects, rect) && ++ isElementOnScreen(rect) && ++ isElementOnTop(elements[i], rect)){ ++ validRects.push(rect); ++ } ++ } ++ } ++ ++ function cAdd1(keyCounter, index, maxDigit){ ++ if(keyCounter[index] + 1 == maxDigit){ ++ keyCounter[index] = 0; ++ cAdd1(keyCounter, index + 1, maxDigit); ++ } else { ++ keyCounter[index]++; ++ } ++ } ++ ++ function generateKeys(markerContainer) { ++ let lettersString = "%1"; ++ let letters = lettersString.split(""); ++ let nodeNum = markerContainer.children.length; ++ let keyLen = nodeNum == 1 ? 1 : Math.ceil(Math.log(nodeNum)/Math.log(letters.length)); ++ let keyCounter = []; ++ for(let i = 0; i < keyLen; i++) keyCounter[i] = 0; ++ for(let l = 0; l < nodeNum; l++) { ++ let keyStr = ''; ++ for(let k = 0; k < keyLen; k++) { ++ let key = letters[keyCounter[k]]; ++ keyStr = key + keyStr; ++ cAdd1(keyCounter, 0, letters.length); ++ } ++ let mark = document.createElement('span'); ++ mark.setAttribute('class', 'eaf-mark'); ++ mark.textContent = keyStr; ++ markerContainer.children[l].appendChild(mark); ++ markerContainer.children[l].id = keyStr; ++ } ++ } ++ ++ ++ self.generateMarker = (selectors) => { ++ ++ let style = document.createElement('style'); ++ document.head.appendChild(style); ++ style.type = 'text/css'; ++ style.setAttribute('class', 'eaf-style'); ++ style.appendChild(document.createTextNode('\ ++.eaf-mark {\ ++background: none;\ ++border: none;\ ++bottom: auto;\ ++box-shadow: none;\ ++color: black !important;\ ++cursor: auto;\ ++display: inline;\ ++float: none;\ ++font-size: inherit;\ ++font-variant: normal;\ ++font-weight: bold;\ ++height: auto;\ ++left: auto;\ ++letter-spacing: 0;\ ++line-height: 100%;\ ++margin: 0;\ ++max-height: none;\ ++max-width: none;\ ++min-height: 0;\ ++min-width: 0;\ ++opacity: 1;\ ++padding: 0;\ ++position: static;\ ++right: auto;\ ++text-align: left;\ ++text-decoration: none;\ ++text-indent: 0;\ ++text-shadow: none;\ ++text-transform: none;\ ++top: auto;\ ++vertical-align: baseline;\ ++white-space: normal;\ ++width: auto;\ ++z-index: 100000;\ ++}')); ++ style.appendChild(document.createTextNode('\ ++.eaf-marker {\ ++position: fixed;\ ++display: block;\ ++white-space: nowrap;\ ++overflow: hidden;\ ++font-size: 11.5px;\ ++background: linear-gradient(to bottom, #ffdd6e 0%, #deb050 100%);\ ++padding-left: 3px;\ ++padding-right: 3px;\ ++border: 1px solid #c38a22;\ ++border-radius: 3px;\ ++box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.3);\ ++z-index: 100000;\ ++}')); ++ ++ let validRects = []; ++ if (typeof(selectors)=="function"){ ++ addElementToRects(validRects, selectors()); ++ }else if (typeof(selectors) == "string"){ ++ selectors = selectors.split(","); ++ selectors.forEach((s)=>addElementToRects(validRects, document.querySelectorAll(s.trim()))); ++ } ++ ++ let body = document.querySelector('body'); ++ let markerContainer = document.createElement('div'); ++ markerContainer.setAttribute('class', 'eaf-marker-container'); ++ body.insertAdjacentElement('afterend', markerContainer); ++ for(let i = 0; i < validRects.length; i++) { ++ let marker = document.createElement('div'); ++ marker.setAttribute('class', 'eaf-marker'); ++ marker.setAttribute('style', 'left: ' + validRects[i][1] + 'px; top: ' + validRects[i][0] + 'px;'); ++ marker.setAttribute('pointed-link', validRects[i][4]); ++ ++ markerContainer.appendChild(marker); ++ } ++ generateKeys(markerContainer); ++ } ++ ++ self.gotoMarker = (key, callback)=>{ ++ let markers = document.querySelectorAll('.eaf-marker'); ++ let match; ++ for(let i = 0; i < markers.length; i++) { ++ if(markers[i].id === key.toUpperCase()) { ++ match = markers[i]; ++ break; ++ } ++ } ++ if (match !== undefined && callback !== undefined){ ++ let selectors = match.getAttribute('pointed-link'); ++ let node = document.querySelector(selectors); ++ return callback(node); ++ } else ++ return ""; ++ } ++ ++ // this is callback function which call by core/browser.py get_mark_link ++ self.getMarkerLink = (node) => { ++ if(node.nodeName.toLowerCase() === 'select'){ ++ node.focus(); ++ }else if(node.nodeName.toLowerCase() === 'input' || ++ node.nodeName.toLowerCase() === 'textarea') { ++ if((node.getAttribute('type') === 'submit') || ++ (node.getAttribute('type') === 'checkbox')){ ++ node.click(); ++ } else { ++ node.focus(); // focus ++ node.click(); // show blink cursor ++ moveCursorToEnd(node); // move cursor to the end of line after focus. ++ } ++ } else if((node.nodeName.toLowerCase() === 'button') || // normal button ++ (node.nodeName.toLowerCase() === 'summary') || // summary button ++ (node.hasAttribute('aria-haspopup')) || // menu button ++ (node.getAttribute('role') === 'button') || // role="button" buttons ++ (node.hasAttribute('ng-click')) || // ng-click buttons ++ (node.classList.contains('btn')) || // class="btn" buttons ++ (node.classList.contains('gap')) || // class="gap" links ++ (node.getAttribute('href') === '') || // special href button ++ (node.getAttribute('href') === '#')){ // special href # button ++ node.click(); ++ } else if(node.nodeName.toLowerCase() === 'p'|| ++ node.nodeName.toLowerCase() === 'span') { // select text section ++ window.getSelection().selectAllChildren(node); ++ } else if(node.href != undefined && node.href != '' && node.getAttribute('href') != ''){ ++ return node.href; ++ } else if(node.nodeName.toLowerCase() === 'a') { ++ node.click(); // most general a tag without href ++ } ++ return ""; ++ } ++ ++ ++ self.generateTextNodeMarker = () => { ++ ++ let elements = getVisibleElements(function(e, v) { ++ let aa = e.childNodes; ++ for (let i = 0, len = aa.length; i < len; i++) { ++ if (aa[i].nodeType == Node.TEXT_NODE && aa[i].data.length > 0) { ++ v.push(e); ++ break; ++ } ++ } ++ }); ++ ++ elements = Array.prototype.concat.apply([], elements.map(function (e) { ++ let aa = e.childNodes; ++ let bb = []; ++ for (let i = 0, len = aa.length; i < len; i++) { ++ if (aa[i].nodeType == Node.TEXT_NODE && aa[i].data.trim().length > 1) { ++ bb.push(aa[i]); ++ } ++ } ++ return bb; ++ })); ++ ++ return elements; ++ } ++ ++})(window); +-- +2.53.0 + diff --git a/www-client/falkon/0007-Put-in-a-working-implementation.patch b/www-client/falkon/0007-Put-in-a-working-implementation.patch new file mode 100644 index 0000000..5da1487 --- /dev/null +++ b/www-client/falkon/0007-Put-in-a-working-implementation.patch @@ -0,0 +1,105 @@ +From d061f8e6adbc3b8c3b0ef6d98099a37a3ba40054 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Mon, 23 Feb 2026 12:44:31 -0500 +Subject: [PATCH 07/16] Put in a working implementation + +--- + src/lib/webengine/webpage.cpp | 4 ++++ + src/lib/webengine/webpage.h | 3 +++ + src/lib/webengine/webview.cpp | 26 ++++++++++++++++++++------ + src/lib/webengine/webview.h | 1 + + 4 files changed, 28 insertions(+), 6 deletions(-) + +diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp +index 4a953ae23..c186695db 100644 +--- a/src/lib/webengine/webpage.cpp ++++ b/src/lib/webengine/webpage.cpp +@@ -816,3 +816,7 @@ void WebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, cons + + std::cout << qPrintable(sourceID) << ":" << lineNumber << " " << qPrintable(message) << '\n'; + } ++ ++void WebPage::followLinkMarker(QString label) { ++ runJavaScript(QString::fromLatin1("Marker.gotoMarker('")+label+QString::fromLatin1("',Marker.getMarkerLink)"),[this](const QVariant& v) { QString url=v.toString(); if (!url.isEmpty()) load(v.toUrl());}); ++} +diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h +index ad8739801..a5fd57c23 100644 +--- a/src/lib/webengine/webpage.h ++++ b/src/lib/webengine/webpage.h +@@ -79,6 +79,9 @@ public: + static void removeSupportedScheme(const QString &scheme); + + void showLinkMarkers(); ++ void followLinkMarker(QString); ++ void markerCallback(const QVariant &); ++ + + Q_SIGNALS: + void privacyChanged(bool status); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index c6e52dfa5..de99f8831 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1228,7 +1228,26 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) { + event->accept(); + } ++ if (m_followLink) { ++ // We are following links; therefore we need to process the ++ // key ++ switch (event->key()) { ++ case Qt::Key_Space: ++ // Accept current label ++ page()->followLinkMarker(m_currentLinkMarkerLabel); ++ case Qt::Key_Escape: ++ page()->hideLinkMarkers(); ++ m_currentLinkMarkerLabel=QString(); ++ m_followLink = false; ++ event->accept(); ++ break; + ++ default: ++ m_currentLinkMarkerLabel += event->text(); ++ qDebug() << "process letter" << m_currentLinkMarkerLabel; ++ break; ++ } ++ } else { + switch (event->key()) { + case Qt::Key_Escape: + if (isFullScreen()) { +@@ -1237,19 +1256,14 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + } + break; + case Qt::Key_F: +- if (!m_followLink) { + page()->showLinkMarkers(); + m_followLink = true; +- } else { +- page()->hideLinkMarkers(); +- m_followLink = false; +- } +- + event->accept(); + + default: + break; + } ++ } + } + + void WebView::_contextMenuEvent(QContextMenuEvent *event) +diff --git a/src/lib/webengine/webview.h b/src/lib/webengine/webview.h +index bec16ea25..5130174b7 100644 +--- a/src/lib/webengine/webview.h ++++ b/src/lib/webengine/webview.h +@@ -191,6 +191,7 @@ private: + WebPage* m_page; + bool m_firstLoad; + bool m_followLink; ++ QString m_currentLinkMarkerLabel; + + QPointer m_rwhvqt; + WheelHelper m_wheelHelper; +-- +2.53.0 + diff --git a/www-client/falkon/0008-Move-marker-handling-to-keypress.patch b/www-client/falkon/0008-Move-marker-handling-to-keypress.patch new file mode 100644 index 0000000..89d9d27 --- /dev/null +++ b/www-client/falkon/0008-Move-marker-handling-to-keypress.patch @@ -0,0 +1,103 @@ +From 23d255b888d51226239f9c1567407ecc0d8c84a3 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Thu, 30 Apr 2026 23:02:31 -0400 +Subject: [PATCH 08/16] Move marker handling to keypress + +This is done to avoid clashes with other key handling +routines (e.g. writing in a form) + +There are still issues with (e.g.) pages entirely made of forms so +that the key would never be handled by us. This will only get clearer +by eating the dog food in real life. +--- + src/lib/webengine/webview.cpp | 46 ++++++++++++++++++----------------- + 1 file changed, 24 insertions(+), 22 deletions(-) + +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index de99f8831..ca3d8180e 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1178,9 +1178,29 @@ void WebView::_keyPressEvent(QKeyEvent *event) + event->accept(); + return; + } ++ if (m_followLink) { ++ // We are following links; therefore we need to process the ++ // key ++ switch (event->key()) { ++ case Qt::Key_Enter: ++ case Qt::Key_Return: ++ // Accept current label ++ page()->followLinkMarker(m_currentLinkMarkerLabel); ++ case Qt::Key_Escape: ++ page()->hideLinkMarkers(); ++ m_currentLinkMarkerLabel = QString(); ++ m_followLink = false; ++ event->accept(); ++ break; + +- switch (event->key()) { +- case Qt::Key_ZoomIn: ++ default: ++ m_currentLinkMarkerLabel += event->text(); ++ qDebug() << "process letter" << m_currentLinkMarkerLabel; ++ break; ++ } ++ } else { ++ switch (event->key()) { ++ case Qt::Key_ZoomIn: + zoomIn(); + event->accept(); + break; +@@ -1221,6 +1241,7 @@ void WebView::_keyPressEvent(QKeyEvent *event) + default: + break; + } ++ } + } + + void WebView::_keyReleaseEvent(QKeyEvent *event) +@@ -1228,26 +1249,7 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) { + event->accept(); + } +- if (m_followLink) { +- // We are following links; therefore we need to process the +- // key +- switch (event->key()) { +- case Qt::Key_Space: +- // Accept current label +- page()->followLinkMarker(m_currentLinkMarkerLabel); +- case Qt::Key_Escape: +- page()->hideLinkMarkers(); +- m_currentLinkMarkerLabel=QString(); +- m_followLink = false; +- event->accept(); +- break; + +- default: +- m_currentLinkMarkerLabel += event->text(); +- qDebug() << "process letter" << m_currentLinkMarkerLabel; +- break; +- } +- } else { + switch (event->key()) { + case Qt::Key_Escape: + if (isFullScreen()) { +@@ -1258,12 +1260,12 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + case Qt::Key_F: + page()->showLinkMarkers(); + m_followLink = true; ++ + event->accept(); + + default: + break; + } +- } + } + + void WebView::_contextMenuEvent(QContextMenuEvent *event) +-- +2.53.0 + diff --git a/www-client/falkon/0009-Reset-the-label-when-the-markers-disappear.patch b/www-client/falkon/0009-Reset-the-label-when-the-markers-disappear.patch new file mode 100644 index 0000000..6c7383d --- /dev/null +++ b/www-client/falkon/0009-Reset-the-label-when-the-markers-disappear.patch @@ -0,0 +1,26 @@ +From 019199187164af4c13d62462a24ecc8eae412149 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Thu, 29 Oct 2020 11:18:11 -0400 +Subject: [PATCH 09/16] Reset the label when the markers disappear + +This should really be made into a slot. +--- + src/lib/webengine/webview.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index ca3d8180e..ea5e356d1 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -162,7 +162,7 @@ void WebView::setPage(WebPage *page) + connect(m_page, &WebPage::privacyChanged, this, &WebView::privacyChanged); + connect(m_page, &WebPage::printRequested, this, &WebView::printPage); + connect(m_page, &WebPage::linkMarkersCleared, +- [=]() {m_followLink = false;}); ++ [=]() {m_followLink = false;m_currentLinkMarkerLabel=QString(); }); + + // Set default zoom level + zoomReset(); +-- +2.53.0 + diff --git a/www-client/falkon/0010-Lunarize-the-markers.patch b/www-client/falkon/0010-Lunarize-the-markers.patch new file mode 100644 index 0000000..fefcdbf --- /dev/null +++ b/www-client/falkon/0010-Lunarize-the-markers.patch @@ -0,0 +1,47 @@ +From cd13e15084a229685f23cff79ed5ccbabd8b9daf Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Mon, 2 Nov 2020 12:08:46 -0500 +Subject: [PATCH 10/16] Lunarize the markers + +This is merely an aesthetic change; will need to adjust this in the +future +--- + src/lib/data/html/marker.js | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/lib/data/html/marker.js b/src/lib/data/html/marker.js +index d04075029..35db02098 100644 +--- a/src/lib/data/html/marker.js ++++ b/src/lib/data/html/marker.js +@@ -135,7 +135,7 @@ background: none;\ + border: none;\ + bottom: auto;\ + box-shadow: none;\ +-color: black !important;\ ++color: #969696!important;\ + cursor: auto;\ + display: inline;\ + float: none;\ +@@ -172,13 +172,12 @@ position: fixed;\ + display: block;\ + white-space: nowrap;\ + overflow: hidden;\ +-font-size: 11.5px;\ +-background: linear-gradient(to bottom, #ffdd6e 0%, #deb050 100%);\ +-padding-left: 3px;\ +-padding-right: 3px;\ +-border: 1px solid #c38a22;\ +-border-radius: 3px;\ +-box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.3);\ ++font-size: 14px;\ ++background: #F6F6F6;\ ++padding-left: 6px;\ ++padding-right: 6px;\ ++border: 1px solid #262626;\ ++border-radius: 1px;\ + z-index: 100000;\ + }')); + +-- +2.53.0 + diff --git a/www-client/falkon/0011-Do-not-propagate-keypresses-to-view-when-markers-are.patch b/www-client/falkon/0011-Do-not-propagate-keypresses-to-view-when-markers-are.patch new file mode 100644 index 0000000..b05f25e --- /dev/null +++ b/www-client/falkon/0011-Do-not-propagate-keypresses-to-view-when-markers-are.patch @@ -0,0 +1,35 @@ +From dbb54db080f741ee3d51e11b1ce8b5e92f833fb4 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 16:48:54 -0400 +Subject: [PATCH 11/16] Do not propagate keypresses to view when markers are + active + +--- + src/lib/webengine/webview.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index ea5e356d1..1929e361e 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1196,6 +1196,7 @@ void WebView::_keyPressEvent(QKeyEvent *event) + default: + m_currentLinkMarkerLabel += event->text(); + qDebug() << "process letter" << m_currentLinkMarkerLabel; ++ event->accept(); + break; + } + } else { +@@ -1356,7 +1357,8 @@ bool WebView::eventFilter(QObject *obj, QEvent *event) + } + } + +- if (obj == parentWidget()) { ++ if (obj == parentWidget() ++ || ((obj == m_rwhvqt) && (m_followLink))) { + switch (event->type()) { + case QEvent::KeyPress: + HANDLE_EVENT(_keyPressEvent, QKeyEvent); +-- +2.53.0 + diff --git a/www-client/falkon/0012-Prevent-triggering-markers-with-modifiers.patch b/www-client/falkon/0012-Prevent-triggering-markers-with-modifiers.patch new file mode 100644 index 0000000..ee76f2d --- /dev/null +++ b/www-client/falkon/0012-Prevent-triggering-markers-with-modifiers.patch @@ -0,0 +1,30 @@ +From 2bad488dcf8aaa99473cba510661a9134850b571 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 16:53:02 -0400 +Subject: [PATCH 12/16] Prevent triggering markers with modifiers + +--- + src/lib/webengine/webview.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index 1929e361e..aa6c9839d 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1259,11 +1259,11 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + } + break; + case Qt::Key_F: ++ if (!event->modifiers()) { + page()->showLinkMarkers(); + m_followLink = true; +- + event->accept(); +- ++ } + default: + break; + } +-- +2.53.0 + diff --git a/www-client/falkon/0013-Colemak-markers.patch b/www-client/falkon/0013-Colemak-markers.patch new file mode 100644 index 0000000..b1e9d3e --- /dev/null +++ b/www-client/falkon/0013-Colemak-markers.patch @@ -0,0 +1,25 @@ +From 74f4eff8b5771c4eb328cfc25d4d5f561822baf8 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 16:57:31 -0400 +Subject: [PATCH 13/16] Colemak markers + +--- + src/lib/data/html/marker.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/data/html/marker.js b/src/lib/data/html/marker.js +index 35db02098..7694164f1 100644 +--- a/src/lib/data/html/marker.js ++++ b/src/lib/data/html/marker.js +@@ -101,7 +101,7 @@ + } + + function generateKeys(markerContainer) { +- let lettersString = "%1"; ++ let lettersString = "ARSTDHNEIOPL"; + let letters = lettersString.split(""); + let nodeNum = markerContainer.children.length; + let keyLen = nodeNum == 1 ? 1 : Math.ceil(Math.log(nodeNum)/Math.log(letters.length)); +-- +2.53.0 + diff --git a/www-client/falkon/0014-fix-marker-shortcut.patch b/www-client/falkon/0014-fix-marker-shortcut.patch new file mode 100644 index 0000000..838d432 --- /dev/null +++ b/www-client/falkon/0014-fix-marker-shortcut.patch @@ -0,0 +1,25 @@ +From 424a120837aebe78dabd6601813b58fafcfdb116 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 20:17:42 -0400 +Subject: [PATCH 14/16] fix marker shortcut + +--- + src/lib/webengine/webview.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index aa6c9839d..dcc4d2e84 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1258,7 +1258,7 @@ void WebView::_keyReleaseEvent(QKeyEvent *event) + event->accept(); + } + break; +- case Qt::Key_F: ++ case Qt::Key_T: + if (!event->modifiers()) { + page()->showLinkMarkers(); + m_followLink = true; +-- +2.53.0 + diff --git a/www-client/falkon/0015-Use-sans-serif-family.patch b/www-client/falkon/0015-Use-sans-serif-family.patch new file mode 100644 index 0000000..a6aef7a --- /dev/null +++ b/www-client/falkon/0015-Use-sans-serif-family.patch @@ -0,0 +1,33 @@ +From d1ca5bcfed4e513ee5087c70a7651839a1343d20 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 22:28:46 -0400 +Subject: [PATCH 15/16] Use sans-serif family + +--- + src/lib/data/html/marker.js | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/lib/data/html/marker.js b/src/lib/data/html/marker.js +index 7694164f1..37934e6e8 100644 +--- a/src/lib/data/html/marker.js ++++ b/src/lib/data/html/marker.js +@@ -141,7 +141,7 @@ display: inline;\ + float: none;\ + font-size: inherit;\ + font-variant: normal;\ +-font-weight: bold;\ ++font-weight: regular;\ + height: auto;\ + left: auto;\ + letter-spacing: 0;\ +@@ -172,6 +172,7 @@ position: fixed;\ + display: block;\ + white-space: nowrap;\ + overflow: hidden;\ ++font-family: sans-serif;\ + font-size: 14px;\ + background: #F6F6F6;\ + padding-left: 6px;\ +-- +2.53.0 + diff --git a/www-client/falkon/0016-Add-shortcuts-for-zooming-and-back-forward.patch b/www-client/falkon/0016-Add-shortcuts-for-zooming-and-back-forward.patch new file mode 100644 index 0000000..ccf832d --- /dev/null +++ b/www-client/falkon/0016-Add-shortcuts-for-zooming-and-back-forward.patch @@ -0,0 +1,45 @@ +From ac9a424b3da19bd8117cb4ec90c7b51d5ac17c01 Mon Sep 17 00:00:00 2001 +From: Jacopo De Simoi +Date: Wed, 6 May 2026 22:29:12 -0400 +Subject: [PATCH 16/16] Add shortcuts for zooming and back/forward + +--- + src/lib/app/browserwindow.cpp | 2 ++ + src/lib/webengine/webview.cpp | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp +index e847068bf..4b13751b8 100644 +--- a/src/lib/app/browserwindow.cpp ++++ b/src/lib/app/browserwindow.cpp +@@ -1288,6 +1288,7 @@ void BrowserWindow::keyPressEvent(QKeyEvent* event) + + switch (event->key()) { + case Qt::Key_Back: ++ case Qt::Key_C: + if (view) { + view->back(); + event->accept(); +@@ -1295,6 +1296,7 @@ void BrowserWindow::keyPressEvent(QKeyEvent* event) + break; + + case Qt::Key_Forward: ++ case Qt::Key_V: + if (view) { + view->forward(); + event->accept(); +diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp +index dcc4d2e84..c793b8bc7 100644 +--- a/src/lib/webengine/webview.cpp ++++ b/src/lib/webengine/webview.cpp +@@ -1212,6 +1212,7 @@ void WebView::_keyPressEvent(QKeyEvent *event) + break; + + case Qt::Key_Plus: ++ case Qt::Key_Equal: + if (event->modifiers() & Qt::ControlModifier) { + zoomIn(); + event->accept(); +-- +2.53.0 +