diff --git a/extra/falkon/build b/extra/falkon/build
index f1c13bd8..94cffbb2 100755
--- a/extra/falkon/build
+++ b/extra/falkon/build
@@ -2,7 +2,9 @@
export DESTDIR="$1"
-patch -p1 < 0001-falkon-no-execinfo.patch
+for patch in *.patch; do
+ patch -p1 < "$patch"
+done
# Get rid of i18n.
rm -rf po poqm
diff --git a/extra/falkon/checksums b/extra/falkon/checksums
index 6da82863..f24ce9c3 100644
--- a/extra/falkon/checksums
+++ b/extra/falkon/checksums
@@ -1,3 +1,4 @@
ce743cd80c0e2d525a784e29c9b487f73480119b0567f9ce8ef1f44cca527587 falkon-3.1.0.tar.xz
37734210642c99c6f4b047bbf15fb208348fdd6564b2fcf674e282505770c983 0001-falkon-no-execinfo.patch
+22952f0d1a0862692d1561418ea27b66f18e11354066b985c6f02588e7232bac 0002-falkon-open-mpv.patch
929dc4ee0e1ec87510696894e0ba3d0218707d6fe9903be3cde5c4ff71a50aa2 falkon-privacy
diff --git a/extra/falkon/patches/0002-falkon-open-mpv.patch b/extra/falkon/patches/0002-falkon-open-mpv.patch
new file mode 100644
index 00000000..edc8d4f6
--- /dev/null
+++ b/extra/falkon/patches/0002-falkon-open-mpv.patch
@@ -0,0 +1,415 @@
+diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
+index 54b28ba9..bcd42cc9 100644
+--- a/src/plugins/CMakeLists.txt
++++ b/src/plugins/CMakeLists.txt
+@@ -8,6 +8,7 @@ add_subdirectory(PIM)
+ add_subdirectory(StatusBarIcons)
+ add_subdirectory(TabManager)
+ add_subdirectory(VerticalTabs)
++add_subdirectory(OpenInMpv)
+
+ if (GNOME_KEYRING_FOUND)
+ add_subdirectory(GnomeKeyringPasswords)
+diff --git a/src/plugins/OpenInMpv/CMakeLists.txt b/src/plugins/OpenInMpv/CMakeLists.txt
+new file mode 100644
+index 00000000..5f7d66a6
+--- /dev/null
++++ b/src/plugins/OpenInMpv/CMakeLists.txt
+@@ -0,0 +1,16 @@
++set( OpenInMpv_SRCS
++ openinmpv.cpp
++ icon.cpp
++ )
++
++
++set( OpenInMpv_RSCS
++ openinmpv.qrc
++)
++qt5_add_resources(RSCS ${OpenInMpv_RSCS})
++
++ecm_create_qm_loader( OpenInMpv_SRCS falkon_OpenInMpv_qt )
++
++add_library(OpenInMpv MODULE ${OpenInMpv_SRCS} ${RSCS})
++install(TARGETS OpenInMpv DESTINATION ${FALKON_INSTALL_PLUGINDIR})
++target_link_libraries(OpenInMpv FalkonPrivate)
+diff --git a/src/plugins/OpenInMpv/Messages.sh b/src/plugins/OpenInMpv/Messages.sh
+new file mode 100644
+index 00000000..35ba0d26
+--- /dev/null
++++ b/src/plugins/OpenInMpv/Messages.sh
+@@ -0,0 +1,2 @@
++#! /bin/sh
++$EXTRACT_TR_STRINGS `find . -name '*.cpp' -o -name '*.h' -o -name '*.ui'` -o $podir/falkon_testplugin_qt.pot
+diff --git a/src/plugins/OpenInMpv/data/icon-white.svg b/src/plugins/OpenInMpv/data/icon-white.svg
+new file mode 100644
+index 00000000..25718f8f
+--- /dev/null
++++ b/src/plugins/OpenInMpv/data/icon-white.svg
+@@ -0,0 +1,14 @@
++
+diff --git a/src/plugins/OpenInMpv/data/icon.svg b/src/plugins/OpenInMpv/data/icon.svg
+new file mode 100644
+index 00000000..5a002c43
+--- /dev/null
++++ b/src/plugins/OpenInMpv/data/icon.svg
+@@ -0,0 +1,14 @@
++
+diff --git a/src/plugins/OpenInMpv/icon.cpp b/src/plugins/OpenInMpv/icon.cpp
+new file mode 100644
+index 00000000..931e529a
+--- /dev/null
++++ b/src/plugins/OpenInMpv/icon.cpp
+@@ -0,0 +1,19 @@
++#include "icon.h"
++
++OpenInMpvIcon::OpenInMpvIcon(QObject *parent)
++ : AbstractButtonInterface(parent)
++{
++ setIcon(QIcon::fromTheme(QSL("openinmpv-icon"), QIcon(QSL(":openinmpv/data/icon.svg"))));
++ setTitle(tr("Open In Mpv"));
++ setToolTip(tr("Open In Mpv"));
++}
++
++QString OpenInMpvIcon::id() const
++{
++ return QSL("openinmpv");
++}
++
++QString OpenInMpvIcon::name() const
++{
++ return tr("Open In Mpv");
++}
+diff --git a/src/plugins/OpenInMpv/icon.h b/src/plugins/OpenInMpv/icon.h
+new file mode 100644
+index 00000000..bf87c751
+--- /dev/null
++++ b/src/plugins/OpenInMpv/icon.h
+@@ -0,0 +1,21 @@
++#ifndef OPENINMPVICON_H
++#define OPENINMPVICON_H
++
++#include
++
++class OpenInMpvIcon : public AbstractButtonInterface
++{
++ Q_OBJECT
++
++public:
++ explicit OpenInMpvIcon(QObject *parent = nullptr);
++
++ QString id() const override;
++ QString name() const override;
++
++private:
++ void updateState();
++ void clicked(ClickController *controller);
++};
++
++#endif //OPENINMPVICON_H
+diff --git a/src/plugins/OpenInMpv/metadata.desktop b/src/plugins/OpenInMpv/metadata.desktop
+new file mode 100644
+index 00000000..7956c63a
+--- /dev/null
++++ b/src/plugins/OpenInMpv/metadata.desktop
+@@ -0,0 +1,11 @@
++[Desktop Entry]
++Name=Open in Mpv
++Comment=Open in Mpv
++
++Icon=configure
++Type=Service
++
++X-Falkon-Author=David Rosca
++X-Falkon-Email=nowrep@gmail.com
++X-Falkon-Version=0.1.7
++X-Falkon-Settings=false
+diff --git a/src/plugins/OpenInMpv/openinmpv.cpp b/src/plugins/OpenInMpv/openinmpv.cpp
+new file mode 100644
+index 00000000..c4f82dc6
+--- /dev/null
++++ b/src/plugins/OpenInMpv/openinmpv.cpp
+@@ -0,0 +1,174 @@
++/* ============================================================
++* Falkon - Qt web browser
++* Copyright (C) 2010-2018 David Rosca
++*
++* This program is free software: you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation, either version 3 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program. If not, see .
++* ============================================================ */
++#include "openinmpv.h"
++#include "browserwindow.h"
++#include "webview.h"
++#include "pluginproxy.h"
++#include "mainapplication.h"
++#include "sidebar.h"
++#include "webhittestresult.h"
++#include "../config.h"
++#include "desktopfile.h"
++#include "navigationbar.h"
++
++#include
++#include
++#include
++
++#include "icon.h"
++
++OpenInMpv::OpenInMpv()
++ : QObject()
++{
++ // Don't do anything expensive in constructor!
++ // It will be called even if user doesn't have the plugin allowed
++}
++
++DesktopFile OpenInMpv::metaData() const
++{
++ return DesktopFile(QSL(":openinmpv/metadata.desktop"));
++}
++
++void OpenInMpv::init(InitState state, const QString &)
++{
++ m_icon = new OpenInMpvIcon();
++ m_icon->setIcon(QIcon(QL1S(":openinmpv/data/icon.svg")));
++ connect(m_icon, SIGNAL(clicked(ClickController*)), this, SLOT(actionIconSlot()));
++ connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, &OpenInMpv::mainWindowCreated);
++ connect(mApp->plugins(), &PluginProxy::mainWindowDeleted, this, &OpenInMpv::mainWindowDeleted);
++
++ if (state == LateInitState) {
++ const auto windows = mApp->windows();
++ for (BrowserWindow *window : windows) {
++ mainWindowCreated(window);
++ }
++ }
++
++}
++
++void OpenInMpv::mainWindowCreated(BrowserWindow *window)
++{
++ window->navigationBar()->addToolButton(m_icon);
++}
++
++void OpenInMpv::mainWindowDeleted(BrowserWindow *window)
++{
++ window->navigationBar()->removeToolButton(m_icon);
++}
++
++void OpenInMpv::unload()
++{
++ const auto windows = mApp->windows();
++ for (BrowserWindow *window : windows) {
++ mainWindowDeleted(window);
++ }
++}
++
++bool OpenInMpv::testPlugin()
++{
++ // This function is called right after init()
++ // There should be some testing if plugin is loaded correctly
++ // If this function returns false, plugin is automatically unloaded
++
++ return (Qz::VERSION == QLatin1String(FALKON_VERSION));
++}
++
++//void OpenInMpv::showSettings(QWidget* parent)
++//{
++// // This function will be called from Preferences after clicking on Settings button.
++// // Settings button will be enabled if PluginSpec.hasSettings == true
++
++// if (!m_settings) {
++// m_settings = new QDialog(parent);
++// QPushButton* b = new QPushButton("Example Plugin v0.0.1");
++// QPushButton* closeButton = new QPushButton(tr("Close"));
++// QLabel* label = new QLabel();
++// label->setPixmap(QPixmap(":icons/other/about.svg"));
++
++// QVBoxLayout* l = new QVBoxLayout(m_settings.data());
++// l->addWidget(label);
++// l->addWidget(b);
++// l->addWidget(closeButton);
++// m_settings.data()->setLayout(l);
++
++// m_settings.data()->setAttribute(Qt::WA_DeleteOnClose);
++// m_settings.data()->setWindowTitle(tr("Example Plugin Settings"));
++// m_settings.data()->setWindowIcon(QIcon(":icons/falkon.svg"));
++// connect(closeButton, SIGNAL(clicked()), m_settings.data(), SLOT(close()));
++// }
++
++// m_settings.data()->show();
++// m_settings.data()->raise();
++//}
++
++void OpenInMpv::populateWebViewMenu(QMenu* menu, WebView*, const WebHitTestResult &r)
++{
++ // Called from WebView when creating context menu
++
++// m_view = view;
++
++ QUrl link;
++
++ if (!r.linkUrl().isEmpty()) {
++// qDebug() << __FUNCTION__ << "linkUrl";
++ link = r.linkUrl();
++ } else if (!r.mediaUrl().isEmpty()) {
++// qDebug() << __FUNCTION__ << "mediaUrl";
++ link = r.mediaUrl();
++ }
++
++ if (link.isEmpty()) {
++ return;
++ }
++
++ menu->addAction(tr("Open In Mpv"), this, SLOT(actionSlot()))->setData(link);
++}
++
++void OpenInMpv::work(const QUrl url) {
++ QStringList arguments;
++// arguments << "--player-operation-mode=pseudo-gui" << "--" << url.toString();
++ arguments << url.toString();
++// QProcess p;
++// p.setStandardInputFile(QProcess::nullDevice());
++// p.setStandardOutputFile(QProcess::nullDevice());
++// p.setProgram("/bin/mpv");
++// p.setArguments(arguments);
++// bool success = p.startDetached();
++
++ /*bool success = */QProcess::startDetached("/bin/mpv", arguments);
++// if (!success) {
++// QString info = "- " + tr("Executable: ") + "/bin/mpv
- " + tr("Arguments: ") + "" + arguments.join(" ") + "
";
++// QMessageBox::critical(m_view, tr("Cannot start external viewer"), tr("Cannot start external viewer! %1").arg(info));
++// }
++}
++void OpenInMpv::actionSlot()
++{
++ const QUrl url = qobject_cast(sender())->data().toUrl();
++ work(url);
++}
++
++void OpenInMpv::actionIconSlot()
++{
++ WebView *view = m_icon->webView();
++ if (!view) {
++ return;
++ }
++
++ const QUrl pageUrl = view->url();
++ work(pageUrl);
++}
+diff --git a/src/plugins/OpenInMpv/openinmpv.h b/src/plugins/OpenInMpv/openinmpv.h
+new file mode 100644
+index 00000000..1b4ab0d4
+--- /dev/null
++++ b/src/plugins/OpenInMpv/openinmpv.h
+@@ -0,0 +1,65 @@
++/* ============================================================
++* Falkon - Qt web browser
++* Copyright (C) 2010-2014 David Rosca
++*
++* This program is free software: you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation, either version 3 of the License, or
++* (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program. If not, see .
++* ============================================================ */
++#ifndef OPENINMPVPLUGIN_H
++#define OPENINMPVPLUGIN_H
++
++// Include plugininterface.h for your version of Falkon
++#include "plugininterface.h"
++
++#include
++#include
++#include
++#include
++
++class BrowserWindow;
++class OpenInMpvIcon;
++
++class OpenInMpv : public QObject, public PluginInterface
++{
++ Q_OBJECT
++ Q_INTERFACES(PluginInterface)
++ Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.OpenInMpv")
++
++public:
++ explicit OpenInMpv();
++
++ DesktopFile metaData() const override;
++ void init(InitState state, const QString &settingsPath) override;
++ void unload() override;
++ bool testPlugin() override;
++// void showSettings(QWidget *parent) override;
++
++ void populateWebViewMenu(QMenu *menu, WebView *view, const WebHitTestResult &r) override;
++// bool mousePress(Qz::ObjectName type, QObject *obj, QMouseEvent *event) override;
++
++public slots:
++ void mainWindowCreated(BrowserWindow *window);
++ void mainWindowDeleted(BrowserWindow *window);
++private Q_SLOTS:
++ void actionSlot();
++ void actionIconSlot();
++private:
++// QPointer m_settings;
++
++// WebView* m_view;
++ QString m_settingsPath;
++ OpenInMpvIcon* m_icon;
++ void work(const QUrl);
++};
++
++#endif // OPENINMPVPLUGIN_H
+diff --git a/src/plugins/OpenInMpv/openinmpv.qrc b/src/plugins/OpenInMpv/openinmpv.qrc
+new file mode 100644
+index 00000000..7c448114
+--- /dev/null
++++ b/src/plugins/OpenInMpv/openinmpv.qrc
+@@ -0,0 +1,7 @@
++
++
++ metadata.desktop
++ data/icon-white.svg
++ data/icon.svg
++
++
diff --git a/extra/falkon/sources b/extra/falkon/sources
index 43bec6ae..09aed90f 100644
--- a/extra/falkon/sources
+++ b/extra/falkon/sources
@@ -1,3 +1,4 @@
https://download.kde.org/stable/falkon/3.1/falkon-3.1.0.tar.xz
patches/0001-falkon-no-execinfo.patch
+patches/0002-falkon-open-mpv.patch
files/falkon-privacy
diff --git a/extra/falkon/version b/extra/falkon/version
index 980778df..9a72ed12 100644
--- a/extra/falkon/version
+++ b/extra/falkon/version
@@ -1 +1 @@
-3.1.0 1
+3.1.0 2