Falkon Develop
Cross-platform Qt-based web browser
mousegestures.cpp
Go to the documentation of this file.
1/* ============================================================
2* Mouse Gestures plugin for Falkon
3* Copyright (C) 2013-2017 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
18#include "mousegestures.h"
19#include "webpage.h"
20#include "tabbedwebview.h"
21#include "tabwidget.h"
22#include "mainapplication.h"
23#include "browserwindow.h"
24#include "locationbar.h"
26
28#include "QjtMouseGesture.h"
29
30#include <QMouseEvent>
31#include <QWebEngineHistory>
32#include <QSettings>
33
34MouseGestures::MouseGestures(const QString &settingsPath, QObject* parent)
35 : QObject(parent)
36 , m_filter(nullptr)
37 , m_settingsFile(settingsPath + QL1S("/extensions.ini"))
38 , m_button(Qt::MiddleButton)
39{
41}
42
43void MouseGestures::initFilter()
44{
45 if (m_filter) {
46 m_filter->clearGestures(true);
47 delete m_filter;
48 }
49
50 m_filter = new QjtMouseGestureFilter(false, m_button, 20);
51
52 auto* upGesture = new QjtMouseGesture(DirectionList() << Up, m_filter);
53 connect(upGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upGestured);
54
55 auto* downGesture = new QjtMouseGesture(DirectionList() << Down, m_filter);
56 connect(downGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downGestured);
57
58 auto* leftGesture = new QjtMouseGesture(DirectionList() << Left, m_filter);
59 connect(leftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::leftGestured);
60
61 auto* rightGesture = new QjtMouseGesture(DirectionList() << Right, m_filter);
62 connect(rightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::rightGestured);
63
64 auto* downRightGesture = new QjtMouseGesture(DirectionList() << Down << Right, m_filter);
65 connect(downRightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downRightGestured);
66
67 auto* downLeftGesture = new QjtMouseGesture(DirectionList() << Down << Left, m_filter);
68 connect(downLeftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downLeftGestured);
69
70 auto* downUpGesture = new QjtMouseGesture(DirectionList() << Down << Up, m_filter);
71 connect(downUpGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downUpGestured);
72
73 auto* upDownGesture = new QjtMouseGesture(DirectionList() << Up << Down, m_filter);
74 connect(upDownGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upDownGestured);
75
76 auto* upLeftGesture = new QjtMouseGesture(DirectionList() << Up << Left, m_filter);
77 connect(upLeftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upLeftGestured);
78
79 auto* upRightGesture = new QjtMouseGesture(DirectionList() << Up << Right, m_filter);
80 connect(upRightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upRightGestured);
81
82 m_filter->addGesture(upGesture);
83 m_filter->addGesture(downGesture);
84 m_filter->addGesture(leftGesture);
85 m_filter->addGesture(rightGesture);
86
87 m_filter->addGesture(downRightGesture);
88 m_filter->addGesture(downLeftGesture);
89 m_filter->addGesture(downUpGesture);
90 m_filter->addGesture(upDownGesture);
91 m_filter->addGesture(upLeftGesture);
92 m_filter->addGesture(upRightGesture);
93}
94
95bool MouseGestures::mousePress(QObject* obj, QMouseEvent* event)
96{
97 m_view = qobject_cast<WebView*>(obj);
98
99 if (m_enableRockerNavigation && event->buttons() == (Qt::RightButton | Qt::LeftButton)) {
100 bool accepted = false;
101
102 if (event->button() == Qt::LeftButton && m_view.data()->history()->canGoBack()) {
103 m_view.data()->back();
104 accepted = true;
105 }
106 else if (event->button() == Qt::RightButton && m_view.data()->history()->canGoForward()) {
107 m_view.data()->forward();
108 accepted = true;
109 }
110
111 if (accepted) {
112 m_blockNextLeftMouseRelease = true;
113 m_blockNextRightMouseRelease = true;
114 return true;
115 }
116 }
117
118 m_filter->mouseButtonPressEvent(event);
119
120 return false;
121}
122
123bool MouseGestures::mouseRelease(QObject* obj, QMouseEvent* event)
124{
125 Q_UNUSED(obj)
126
127 if (m_blockNextRightMouseRelease && event->button() == Qt::RightButton) {
128 m_blockNextRightMouseRelease = false;
129 return true;
130 }
131
132 if (m_blockNextLeftMouseRelease && event->button() == Qt::LeftButton) {
133 m_blockNextLeftMouseRelease = false;
134 return true;
135 }
136
137 return m_filter->mouseButtonReleaseEvent(event);
138}
139
140bool MouseGestures::mouseMove(QObject* obj, QMouseEvent* event)
141{
142 Q_UNUSED(obj)
143
144 m_filter->mouseMoveEvent(event);
145
146 return false;
147}
148
149void MouseGestures::showSettings(QWidget* parent)
150{
151 if (!m_settings) {
152 m_settings = new MouseGesturesSettingsDialog(this, parent);
153 }
154
155 m_settings.data()->show();
156 m_settings.data()->raise();
157}
158
160{
161 delete m_settings.data();
162}
163
164void MouseGestures::upGestured()
165{
166 if (!m_view) {
167 return;
168 }
169
170 m_view.data()->stop();
171}
172
173void MouseGestures::downGestured()
174{
175 auto* view = qobject_cast<TabbedWebView*>(m_view.data());
176 if (!view)
177 return;
178
179 BrowserWindow* window = view->browserWindow();
180 if (!window)
181 return;
182
183 TabWidget* tabWidget = window->tabWidget();
184 tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true);
185 tabWidget->setCurrentTabFresh(true);
186
187 if (window->isFullScreen())
189}
190
191void MouseGestures::leftGestured()
192{
193 if (!m_view) {
194 return;
195 }
196
197 if (QApplication::isRightToLeft()) {
198 m_view.data()->forward();
199 }
200 else {
201 m_view.data()->back();
202 }
203}
204
205void MouseGestures::rightGestured()
206{
207 if (!m_view) {
208 return;
209 }
210
211 if (QApplication::isRightToLeft()) {
212 m_view.data()->back();
213 }
214 else {
215 m_view.data()->forward();
216 }
217}
218
219void MouseGestures::downRightGestured()
220{
221 auto *view = qobject_cast<TabbedWebView*>(m_view.data());
222 if (!view)
223 return;
224
225 BrowserWindow *window = view->browserWindow();
226 if (!window)
227 return;
228
229 TabWidget *tabWidget = window->tabWidget();
230 if (!m_view) {
231 return;
232 }
233
234 tabWidget->requestCloseTab(view->tabIndex());
235}
236
237void MouseGestures::downLeftGestured()
238{
239 if (!m_view) {
240 return;
241 }
242
243 m_view.data()->load(mApp->getWindow()->homepageUrl());
244}
245
246void MouseGestures::downUpGestured()
247{
248 auto* view = qobject_cast<TabbedWebView*>(m_view.data());
249 if (!view)
250 return;
251
252 BrowserWindow* window = view->browserWindow();
253 if (!window)
254 return;
255
256 TabWidget* tabWidget = window->tabWidget();
257 tabWidget->duplicateTab(tabWidget->currentIndex());
258}
259
260void MouseGestures::upDownGestured()
261{
262 if (!m_view) {
263 return;
264 }
265
266 m_view.data()->reload();
267}
268
269void MouseGestures::upLeftGestured()
270{
271 auto* view = qobject_cast<TabbedWebView*>(m_view.data());
272 if (!view)
273 return;
274
275 BrowserWindow* window = view->browserWindow();
276 if (!window)
277 return;
278
279 if (QApplication::isRightToLeft())
280 window->tabWidget()->nextTab();
281 else
282 window->tabWidget()->previousTab();
283}
284
285void MouseGestures::upRightGestured()
286{
287 auto* view = qobject_cast<TabbedWebView*>(m_view.data());
288 if (!view)
289 return;
290
291 BrowserWindow* window = view->browserWindow();
292 if (!window)
293 return;
294
295 if (QApplication::isRightToLeft())
296 window->tabWidget()->previousTab();
297 else
298 window->tabWidget()->nextTab();
299}
300
301void MouseGestures::init()
302{
303 initFilter();
304
305 // We need to override right mouse button events
306 m_oldWebViewForceContextMenuOnRelease = WebView::forceContextMenuOnMouseRelease();
307 WebView::setForceContextMenuOnMouseRelease(m_button == Qt::RightButton || m_enableRockerNavigation);
308}
309
310void MouseGestures::setGestureButton(Qt::MouseButton button)
311{
312 m_button = button;
313 init();
314}
315
317{
318 switch (index) {
319 case 0:
320 m_button = Qt::MiddleButton;
321 break;
322
323 case 1:
324 m_button = Qt::RightButton;
325 break;
326
327 default:
328 m_button = Qt::NoButton;
329 }
330
331 setGestureButton(m_button);
332}
333
334Qt::MouseButton MouseGestures::gestureButton() const
335{
336 return m_button;
337}
338
340{
341 switch (m_button) {
342 case Qt::MiddleButton:
343 return 0;
344
345 case Qt::RightButton:
346 return 1;
347
348 default:
349 return 2;
350 }
351}
352
354{
355 return m_enableRockerNavigation;
356}
357
359{
360 m_enableRockerNavigation = enable;
361 init();
362}
363
365{
366 QSettings settings(m_settingsFile, QSettings::IniFormat);
367
368 settings.beginGroup("MouseGestures");
369 setGestureButtonByIndex(settings.value("Button", 0).toInt());
370 m_enableRockerNavigation = settings.value("RockerNavigation", true).toBool();
371 settings.endGroup();
372
373 init();
374}
375
377{
378 QSettings settings(m_settingsFile, QSettings::IniFormat);
379
380 settings.beginGroup("MouseGestures");
381 settings.setValue("Button", buttonToIndex());
382 settings.setValue("RockerNavigation", m_enableRockerNavigation);
383 settings.endGroup();
384}
385
387{
388 m_filter->clearGestures(true);
389 delete m_filter;
390
391 // Restore original value
392 WebView::setForceContextMenuOnMouseRelease(m_oldWebViewForceContextMenuOnRelease);
393}
QList< Direction > DirectionList
TabWidget * tabWidget() const
void showNavigationWithFullScreen()
bool mousePress(QObject *obj, QMouseEvent *event)
Qt::MouseButton gestureButton() const
MouseGestures(const QString &settingsPath, QObject *parent=nullptr)
void showSettings(QWidget *parent)
void setRockerNavigationEnabled(bool enable)
bool rockerNavigationEnabled() const
bool mouseRelease(QObject *obj, QMouseEvent *event)
void setGestureButton(Qt::MouseButton button)
void setGestureButtonByIndex(int index)
bool mouseMove(QObject *obj, QMouseEvent *event)
int buttonToIndex() const
bool mouseButtonReleaseEvent(QMouseEvent *event, QObject *obj=nullptr)
bool mouseMoveEvent(QMouseEvent *event, QObject *obj=nullptr)
void addGesture(QjtMouseGesture *gesture)
void clearGestures(bool deleteGestures=false)
bool mouseButtonPressEvent(QMouseEvent *event, QObject *obj=nullptr)
int currentIndex() const
void requestCloseTab(int index=-1)
Definition: tabwidget.cpp:471
void previousTab()
Definition: tabwidget.cpp:546
void nextTab()
Definition: tabwidget.cpp:541
int duplicateTab(int index)
Definition: tabwidget.cpp:725
int addView(const LoadRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine=false, bool pinned=false)
Definition: tabwidget.cpp:314
void setCurrentTabFresh(bool currentTabFresh)
Definition: tabwidget.cpp:224
static bool forceContextMenuOnMouseRelease()
Definition: webview.cpp:272
static void setForceContextMenuOnMouseRelease(bool force)
Definition: webview.cpp:278
#define mApp
@ NT_SelectedNewEmptyTab
Definition: qzcommon.h:103
#define QL1S(x)
Definition: qzcommon.h:44