diff --git a/bin/themes/linux/images/exit-fullscreen.svg b/bin/themes/linux/images/exit-fullscreen.svg
new file mode 100644
index 00000000..27b9f154
--- /dev/null
+++ b/bin/themes/linux/images/exit-fullscreen.svg
@@ -0,0 +1,13 @@
+
diff --git a/bin/themes/windows/images/exit-fullscreen.svg b/bin/themes/windows/images/exit-fullscreen.svg
new file mode 100644
index 00000000..27b9f154
--- /dev/null
+++ b/bin/themes/windows/images/exit-fullscreen.svg
@@ -0,0 +1,13 @@
+
diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp
index 7271601f..02746680 100644
--- a/src/lib/app/browserwindow.cpp
+++ b/src/lib/app/browserwindow.cpp
@@ -1,1617 +1,1619 @@
/* ============================================================
* 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 "browserwindow.h"
#include "tabwidget.h"
#include "tabbar.h"
#include "webpage.h"
#include "tabbedwebview.h"
#include "lineedit.h"
#include "history.h"
#include "locationbar.h"
#include "websearchbar.h"
#include "pluginproxy.h"
#include "sidebar.h"
#include "downloadmanager.h"
#include "cookiejar.h"
#include "cookiemanager.h"
#include "bookmarkstoolbar.h"
#include "clearprivatedata.h"
#include "autofill.h"
#include "mainapplication.h"
#include "checkboxdialog.h"
#include "clickablelabel.h"
#include "docktitlebarwidget.h"
#include "iconprovider.h"
#include "progressbar.h"
#include "closedwindowsmanager.h"
#include "statusbarmessage.h"
#include "browsinglibrary.h"
#include "navigationbar.h"
#include "bookmarksimport/bookmarksimportdialog.h"
#include "qztools.h"
#include "reloadstopbutton.h"
#include "enhancedmenu.h"
#include "navigationcontainer.h"
#include "settings.h"
#include "qzsettings.h"
#include "speeddial.h"
#include "menubar.h"
#include "bookmarkstools.h"
#include "bookmarksmenu.h"
#include "historymenu.h"
#include "mainmenu.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef QZ_WS_X11
#include
#include
#include
#endif
static const int savedWindowVersion = 2;
BrowserWindow::SavedWindow::SavedWindow()
{
}
BrowserWindow::SavedWindow::SavedWindow(BrowserWindow *window)
{
windowState = window->isFullScreen() ? QByteArray() : window->saveState();
windowGeometry = window->saveGeometry();
windowUiState = window->saveUiState();
#ifdef QZ_WS_X11
virtualDesktop = window->getCurrentVirtualDesktop();
#endif
const int tabsCount = window->tabCount();
tabs.reserve(tabsCount);
for (int i = 0; i < tabsCount; ++i) {
TabbedWebView *webView = window->weView(i);
if (!webView) {
continue;
}
WebTab* webTab = webView->webTab();
if (!webTab) {
continue;
}
WebTab::SavedTab tab(webTab);
if (!tab.isValid()) {
continue;
}
if (webTab->isCurrentTab()) {
currentTab = tabs.size();
}
tabs.append(tab);
}
}
bool BrowserWindow::SavedWindow::isValid() const
{
return currentTab > -1;
}
void BrowserWindow::SavedWindow::clear()
{
windowState.clear();
windowGeometry.clear();
virtualDesktop = -1;
currentTab = -1;
tabs.clear();
}
QDataStream &operator<<(QDataStream &stream, const BrowserWindow::SavedWindow &window)
{
stream << savedWindowVersion;
stream << window.windowState;
stream << window.windowGeometry;
stream << window.virtualDesktop;
stream << window.currentTab;
stream << window.tabs.count();
for (int i = 0; i < window.tabs.count(); ++i) {
stream << window.tabs.at(i);
}
stream << window.windowUiState;
return stream;
}
QDataStream &operator>>(QDataStream &stream, BrowserWindow::SavedWindow &window)
{
int version;
stream >> version;
if (version < 1) {
return stream;
}
stream >> window.windowState;
stream >> window.windowGeometry;
stream >> window.virtualDesktop;
stream >> window.currentTab;
int tabsCount = -1;
stream >> tabsCount;
window.tabs.reserve(tabsCount);
for (int i = 0; i < tabsCount; ++i) {
WebTab::SavedTab tab;
stream >> tab;
window.tabs.append(tab);
}
if (version >= 2) {
stream >> window.windowUiState;
}
return stream;
}
BrowserWindow::BrowserWindow(Qz::BrowserWindowType type, const QUrl &startUrl)
: QMainWindow(0)
, m_startUrl(startUrl)
, m_windowType(type)
, m_startTab(0)
, m_startPage(0)
, m_sideBarManager(new SideBarManager(this))
, m_statusBarMessage(new StatusBarMessage(this))
, m_isHtmlFullScreen(false)
, m_hideNavigationTimer(0)
{
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_DontCreateNativeAncestors);
setObjectName("mainwindow");
setWindowTitle(tr("Falkon"));
setProperty("private", mApp->isPrivate());
setupUi();
setupMenu();
m_hideNavigationTimer = new QTimer(this);
m_hideNavigationTimer->setInterval(1000);
m_hideNavigationTimer->setSingleShot(true);
connect(m_hideNavigationTimer, SIGNAL(timeout()), this, SLOT(hideNavigationSlot()));
connect(mApp, SIGNAL(settingsReloaded()), this, SLOT(loadSettings()));
QTimer::singleShot(0, this, SLOT(postLaunch()));
if (mApp->isPrivate()) {
QzTools::setWmClass("Falkon Browser (Private Window)", this);
}
else {
QzTools::setWmClass("Falkon Browser", this);
}
}
BrowserWindow::~BrowserWindow()
{
mApp->plugins()->emitMainWindowDeleted(this);
foreach (const QPointer &pointer, m_deleteOnCloseWidgets) {
if (pointer) {
pointer->deleteLater();
}
}
}
void BrowserWindow::setStartTab(WebTab* tab)
{
m_startTab = tab;
}
void BrowserWindow::setStartPage(WebPage *page)
{
m_startPage = page;
}
void BrowserWindow::postLaunch()
{
loadSettings();
bool addTab = true;
QUrl startUrl;
switch (mApp->afterLaunch()) {
case MainApplication::OpenBlankPage:
startUrl = QUrl();
break;
case MainApplication::OpenSpeedDial:
startUrl = QUrl("falkon:speeddial");
break;
case MainApplication::OpenHomePage:
case MainApplication::RestoreSession:
case MainApplication::SelectSession:
startUrl = m_homepage;
break;
default:
break;
}
show();
switch (m_windowType) {
case Qz::BW_FirstAppWindow:
if (mApp->isStartingAfterCrash()) {
addTab = false;
startUrl.clear();
m_tabWidget->addView(QUrl("falkon:restore"), Qz::NT_CleanSelectedTabAtTheEnd);
}
else if (mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) {
addTab = m_tabWidget->count() <= 0;
}
break;
case Qz::BW_NewWindow:
case Qz::BW_MacFirstWindow:
addTab = true;
break;
case Qz::BW_OtherRestoredWindow:
addTab = false;
break;
}
if (!m_startUrl.isEmpty()) {
startUrl = m_startUrl;
addTab = true;
}
if (m_startTab) {
addTab = false;
m_tabWidget->addView(m_startTab, Qz::NT_SelectedTab);
}
if (m_startPage) {
addTab = false;
m_tabWidget->addView(QUrl());
weView()->setPage(m_startPage);
}
if (addTab) {
m_tabWidget->addView(startUrl, Qz::NT_CleanSelectedTabAtTheEnd);
if (startUrl.isEmpty() || startUrl.toString() == QLatin1String("falkon:speeddial")) {
locationBar()->setFocus();
}
}
// Something went really wrong .. add one tab
if (m_tabWidget->count() <= 0) {
m_tabWidget->addView(m_homepage, Qz::NT_SelectedTabAtTheEnd);
}
mApp->plugins()->emitMainWindowCreated(this);
emit startingCompleted();
raise();
activateWindow();
updateStartupFocus();
}
void BrowserWindow::setupUi()
{
Settings settings;
settings.beginGroup("Browser-View-Settings");
const QByteArray windowGeometry = settings.value(QSL("WindowGeometry")).toByteArray();
const QStringList keys = {
QSL("LocationBarWidth"),
QSL("WebSearchBarWidth"),
QSL("SideBarWidth"),
QSL("WebViewWidth"),
QSL("SideBar")
};
QHash uiState;
for (const QString &key : keys) {
if (settings.contains(key)) {
uiState[key] = settings.value(key);
}
}
settings.endGroup();
QWidget* widget = new QWidget(this);
widget->setCursor(Qt::ArrowCursor);
setCentralWidget(widget);
m_mainLayout = new QVBoxLayout(widget);
m_mainLayout->setContentsMargins(0, 0, 0, 0);
m_mainLayout->setSpacing(0);
m_mainSplitter = new QSplitter(this);
m_mainSplitter->setObjectName("sidebar-splitter");
m_tabWidget = new TabWidget(this);
m_superMenu = new QMenu(this);
m_navigationToolbar = new NavigationBar(this);
m_bookmarksToolbar = new BookmarksToolbar(this);
m_navigationContainer = new NavigationContainer(this);
m_navigationContainer->addWidget(m_navigationToolbar);
m_navigationContainer->addWidget(m_bookmarksToolbar);
m_navigationContainer->setTabBar(m_tabWidget->tabBar());
m_mainSplitter->addWidget(m_tabWidget);
m_mainSplitter->setCollapsible(0, false);
m_mainLayout->addWidget(m_navigationContainer);
m_mainLayout->addWidget(m_mainSplitter);
statusBar()->setObjectName("mainwindow-statusbar");
statusBar()->setCursor(Qt::ArrowCursor);
m_progressBar = new ProgressBar(statusBar());
m_ipLabel = new QLabel(this);
m_ipLabel->setObjectName("statusbar-ip-label");
m_ipLabel->setToolTip(tr("IP Address of current page"));
statusBar()->addPermanentWidget(m_progressBar);
statusBar()->addPermanentWidget(m_ipLabel);
QDesktopWidget* desktop = mApp->desktop();
int windowWidth = desktop->availableGeometry().width() / 1.3;
int windowHeight = desktop->availableGeometry().height() / 1.3;
// Let the WM decides where to put new browser window
if (m_windowType != Qz::BW_FirstAppWindow && m_windowType != Qz::BW_MacFirstWindow && mApp->getWindow()) {
#ifdef Q_WS_WIN
// Windows WM places every new window in the middle of screen .. for some reason
QPoint p = mApp->getWindow()->geometry().topLeft();
p.setX(p.x() + 30);
p.setY(p.y() + 30);
if (!desktop->availableGeometry(mApp->getWindow()).contains(p)) {
p.setX(desktop->availableGeometry(mApp->getWindow()).x() + 30);
p.setY(desktop->availableGeometry(mApp->getWindow()).y() + 30);
}
setGeometry(QRect(p, mApp->getWindow()->size()));
#else
resize(mApp->getWindow()->size());
#endif
} else if (!restoreGeometry(windowGeometry)) {
#ifdef Q_WS_WIN
setGeometry(QRect(desktop->availableGeometry(mApp->getWindow()).x() + 30,
desktop->availableGeometry(mApp->getWindow()).y() + 30, windowWidth, windowHeight));
#else
resize(windowWidth, windowHeight);
#endif
}
// Workaround for Oxygen tooltips not having transparent background
QPalette pal = QToolTip::palette();
QColor col = pal.window().color();
col.setAlpha(0);
pal.setColor(QPalette::Window, col);
QToolTip::setPalette(pal);
restoreUiState(uiState);
// Set some sane minimum width
setMinimumWidth(300);
}
void BrowserWindow::setupMenu()
{
#ifdef Q_OS_MACOS
static MainMenu* macMainMenu = 0;
if (!macMainMenu) {
macMainMenu = new MainMenu(this, 0);
macMainMenu->initMenuBar(new QMenuBar(0));
connect(mApp, SIGNAL(activeWindowChanged(BrowserWindow*)), macMainMenu, SLOT(setWindow(BrowserWindow*)));
}
else {
macMainMenu->setWindow(this);
}
m_mainMenu = macMainMenu;
#else
setMenuBar(new MenuBar(this));
m_mainMenu = new MainMenu(this, this);
m_mainMenu->initMenuBar(menuBar());
#endif
m_mainMenu->initSuperMenu(m_superMenu);
// Setup other shortcuts
QShortcut* reloadBypassCacheAction = new QShortcut(QKeySequence(QSL("Ctrl+F5")), this);
QShortcut* reloadBypassCacheAction2 = new QShortcut(QKeySequence(QSL("Ctrl+Shift+R")), this);
connect(reloadBypassCacheAction, SIGNAL(activated()), this, SLOT(reloadBypassCache()));
connect(reloadBypassCacheAction2, SIGNAL(activated()), this, SLOT(reloadBypassCache()));
QShortcut* closeTabAction = new QShortcut(QKeySequence(QSL("Ctrl+W")), this);
QShortcut* closeTabAction2 = new QShortcut(QKeySequence(QSL("Ctrl+F4")), this);
connect(closeTabAction, SIGNAL(activated()), this, SLOT(closeTab()));
connect(closeTabAction2, SIGNAL(activated()), this, SLOT(closeTab()));
QShortcut* reloadAction = new QShortcut(QKeySequence("Ctrl+R"), this);
connect(reloadAction, SIGNAL(activated()), this, SLOT(reload()));
QShortcut* openLocationAction = new QShortcut(QKeySequence("Alt+D"), this);
connect(openLocationAction, SIGNAL(activated()), this, SLOT(openLocation()));
QShortcut* inspectorAction = new QShortcut(QKeySequence(QSL("F12")), this);
connect(inspectorAction, SIGNAL(activated()), this, SLOT(toggleWebInspector()));
QShortcut* restoreClosedWindow = new QShortcut(QKeySequence(QSL("Ctrl+Shift+N")), this);
connect(restoreClosedWindow, &QShortcut::activated, mApp->closedWindowsManager(), &ClosedWindowsManager::restoreClosedWindow);
}
void BrowserWindow::updateStartupFocus()
{
QTimer::singleShot(500, this, [this]() {
// Scroll to current tab
tabWidget()->tabBar()->ensureVisible();
// Update focus
if (!m_startPage && LocationBar::convertUrlToText(weView()->page()->requestedUrl()).isEmpty())
locationBar()->setFocus();
else
weView()->setFocus();
});
}
QAction* BrowserWindow::createEncodingAction(const QString &codecName,
const QString &activeCodecName, QMenu* menu)
{
QAction* action = new QAction(codecName, menu);
action->setData(codecName);
action->setCheckable(true);
connect(action, SIGNAL(triggered()), this, SLOT(changeEncoding()));
if (activeCodecName.compare(codecName, Qt::CaseInsensitive) == 0) {
action->setChecked(true);
}
return action;
}
void BrowserWindow::createEncodingSubMenu(const QString &name, QStringList &codecNames, QMenu* menu)
{
if (codecNames.isEmpty()) {
return;
}
QCollator collator;
collator.setNumericMode(true);
std::sort(codecNames.begin(), codecNames.end(), [collator](const QString &a, const QString &b) {
return collator.compare(a, b) < 0;
});
QMenu* subMenu = new QMenu(name, menu);
const QString activeCodecName = mApp->webSettings()->defaultTextEncoding();
QActionGroup *group = new QActionGroup(subMenu);
foreach (const QString &codecName, codecNames) {
QAction *act = createEncodingAction(codecName, activeCodecName, subMenu);
group->addAction(act);
subMenu->addAction(act);
}
menu->addMenu(subMenu);
}
QHash BrowserWindow::saveUiState()
{
saveSideBarSettings();
QHash state;
state[QSL("LocationBarWidth")] = m_navigationToolbar->splitter()->sizes().at(0);
state[QSL("WebSearchBarWidth")] = m_navigationToolbar->splitter()->sizes().at(1);
state[QSL("SideBarWidth")] = m_sideBarWidth;
state[QSL("WebViewWidth")] = m_webViewWidth;
state[QSL("SideBar")] = m_sideBarManager->activeSideBar();
return state;
}
void BrowserWindow::restoreUiState(const QHash &state)
{
const int locationBarWidth = state.value(QSL("LocationBarWidth"), 480).toInt();
const int websearchBarWidth = state.value(QSL("WebSearchBarWidth"), 140).toInt();
m_navigationToolbar->setSplitterSizes(locationBarWidth, websearchBarWidth);
m_sideBarWidth = state.value(QSL("SideBarWidth"), 250).toInt();
m_webViewWidth = state.value(QSL("WebViewWidth"), 2000).toInt();
if (m_sideBar) {
m_mainSplitter->setSizes({m_sideBarWidth, m_webViewWidth});
}
const QString activeSideBar = state.value(QSL("SideBar")).toString();
if (activeSideBar.isEmpty() && m_sideBar) {
m_sideBar->close();
} else {
m_sideBarManager->showSideBar(activeSideBar, false);
}
}
void BrowserWindow::loadSettings()
{
Settings settings;
//Url settings
settings.beginGroup("Web-URL-Settings");
m_homepage = settings.value("homepage", "falkon:start").toUrl();
settings.endGroup();
//Browser Window settings
settings.beginGroup("Browser-View-Settings");
bool showStatusBar = settings.value("showStatusBar", false).toBool();
bool showBookmarksToolbar = settings.value("showBookmarksToolbar", true).toBool();
bool showNavigationToolbar = settings.value("showNavigationToolbar", true).toBool();
bool showMenuBar = settings.value("showMenubar", false).toBool();
// Make sure both menubar and navigationbar are not hidden
// Fixes #781
if (!showNavigationToolbar) {
showMenuBar = true;
settings.setValue("showMenubar", true);
}
settings.endGroup();
settings.beginGroup("Shortcuts");
m_useTabNumberShortcuts = settings.value("useTabNumberShortcuts", true).toBool();
m_useSpeedDialNumberShortcuts = settings.value("useSpeedDialNumberShortcuts", true).toBool();
m_useSingleKeyShortcuts = settings.value("useSingleKeyShortcuts", false).toBool();
settings.endGroup();
settings.beginGroup("Web-Browser-Settings");
QAction *quitAction = m_mainMenu->action(QSL("Standard/Quit"));
if (settings.value("closeAppWithCtrlQ", true).toBool()) {
quitAction->setShortcut(QzTools::actionShortcut(QKeySequence::Quit, QKeySequence(QSL("Ctrl+Q"))));
} else {
quitAction->setShortcut(QKeySequence());
}
settings.endGroup();
statusBar()->setVisible(!isFullScreen() && showStatusBar);
m_bookmarksToolbar->setVisible(showBookmarksToolbar);
m_navigationToolbar->setVisible(showNavigationToolbar);
#ifndef Q_OS_MACOS
menuBar()->setVisible(!isFullScreen() && showMenuBar);
#endif
m_navigationToolbar->setSuperMenuVisible(!showMenuBar);
}
void BrowserWindow::goForward()
{
weView()->forward();
}
void BrowserWindow::reload()
{
weView()->reload();
}
void BrowserWindow::reloadBypassCache()
{
weView()->reloadBypassCache();
}
void BrowserWindow::goBack()
{
weView()->back();
}
int BrowserWindow::tabCount() const
{
return m_tabWidget->count();
}
TabbedWebView* BrowserWindow::weView() const
{
return weView(m_tabWidget->currentIndex());
}
TabbedWebView* BrowserWindow::weView(int index) const
{
WebTab* webTab = qobject_cast(m_tabWidget->widget(index));
if (!webTab) {
return 0;
}
return webTab->webView();
}
LocationBar* BrowserWindow::locationBar() const
{
return qobject_cast(m_tabWidget->locationBars()->currentWidget());
}
TabWidget* BrowserWindow::tabWidget() const
{
return m_tabWidget;
}
BookmarksToolbar* BrowserWindow::bookmarksToolbar() const
{
return m_bookmarksToolbar;
}
StatusBarMessage* BrowserWindow::statusBarMessage() const
{
return m_statusBarMessage;
}
NavigationBar* BrowserWindow::navigationBar() const
{
return m_navigationToolbar;
}
SideBarManager* BrowserWindow::sideBarManager() const
{
return m_sideBarManager;
}
QLabel* BrowserWindow::ipLabel() const
{
return m_ipLabel;
}
QMenu* BrowserWindow::superMenu() const
{
return m_superMenu;
}
QUrl BrowserWindow::homepageUrl() const
{
return m_homepage;
}
Qz::BrowserWindowType BrowserWindow::windowType() const
{
return m_windowType;
}
QAction* BrowserWindow::action(const QString &name) const
{
return m_mainMenu->action(name);
}
void BrowserWindow::setWindowTitle(const QString &t)
{
QString title = t;
if (mApp->isPrivate()) {
title.append(tr(" (Private Browsing)"));
}
QMainWindow::setWindowTitle(title);
}
void BrowserWindow::changeEncoding()
{
if (QAction* action = qobject_cast(sender())) {
const QString encoding = action->data().toString();
mApp->webSettings()->setDefaultTextEncoding(encoding);
Settings settings;
settings.setValue("Web-Browser-Settings/DefaultEncoding", encoding);
weView()->reload();
}
}
void BrowserWindow::printPage()
{
weView()->printPage();
}
void BrowserWindow::bookmarkPage()
{
TabbedWebView* view = weView();
BookmarksTools::addBookmarkDialog(this, view->url(), view->title());
}
void BrowserWindow::bookmarkAllTabs()
{
BookmarksTools::bookmarkAllTabsDialog(this, m_tabWidget);
}
void BrowserWindow::addBookmark(const QUrl &url, const QString &title)
{
BookmarksTools::addBookmarkDialog(this, url, title);
}
void BrowserWindow::goHome()
{
loadAddress(m_homepage);
}
void BrowserWindow::goHomeInNewTab()
{
m_tabWidget->addView(m_homepage, Qz::NT_SelectedTab);
}
void BrowserWindow::loadActionUrl(QObject* obj)
{
if (!obj) {
obj = sender();
}
if (QAction* action = qobject_cast(obj)) {
loadAddress(action->data().toUrl());
}
}
void BrowserWindow::loadActionUrlInNewTab(QObject* obj)
{
if (!obj) {
obj = sender();
}
if (QAction* action = qobject_cast(obj)) {
m_tabWidget->addView(action->data().toUrl(), Qz::NT_SelectedTabAtTheEnd);
}
}
void BrowserWindow::loadAddress(const QUrl &url)
{
if (weView()->webTab()->isPinned()) {
int index = m_tabWidget->addView(url, qzSettings->newTabPosition);
weView(index)->setFocus();
} else {
weView()->load(url);
weView()->setFocus();
}
}
void BrowserWindow::showHistoryManager()
{
mApp->browsingLibrary()->showHistory(this);
}
void BrowserWindow::showSource(WebView *view)
{
if (!view)
view = weView();
view->showSource();
}
void BrowserWindow::showNormal()
{
if (m_normalWindowState & Qt::WindowMaximized) {
QMainWindow::showMaximized();
} else {
QMainWindow::showNormal();
}
}
SideBar* BrowserWindow::addSideBar()
{
if (m_sideBar) {
return m_sideBar.data();
}
m_sideBar = new SideBar(m_sideBarManager, this);
m_mainSplitter->insertWidget(0, m_sideBar.data());
m_mainSplitter->setCollapsible(0, false);
m_mainSplitter->setSizes({m_sideBarWidth, m_webViewWidth});
return m_sideBar.data();
}
void BrowserWindow::saveSideBarSettings()
{
if (m_sideBar) {
// That +1 is important here, without it, the sidebar width would
// decrease by 1 pixel every close
m_sideBarWidth = m_mainSplitter->sizes().at(0) + 1;
m_webViewWidth = width() - m_sideBarWidth;
}
Settings().setValue(QSL("Browser-View-Settings/SideBar"), m_sideBarManager->activeSideBar());
}
void BrowserWindow::toggleShowMenubar()
{
#ifdef Q_OS_MACOS
// We use one shared global menubar on Mac that can't be hidden
return;
#endif
setUpdatesEnabled(false);
menuBar()->setVisible(!menuBar()->isVisible());
m_navigationToolbar->setSuperMenuVisible(!menuBar()->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showMenubar", menuBar()->isVisible());
// Make sure we show Navigation Toolbar when Menu Bar is hidden
if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) {
toggleShowNavigationToolbar();
}
}
void BrowserWindow::toggleShowStatusBar()
{
setUpdatesEnabled(false);
statusBar()->setVisible(!statusBar()->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showStatusBar", statusBar()->isVisible());
}
void BrowserWindow::toggleShowBookmarksToolbar()
{
setUpdatesEnabled(false);
m_bookmarksToolbar->setVisible(!m_bookmarksToolbar->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showBookmarksToolbar", m_bookmarksToolbar->isVisible());
Settings().setValue("Browser-View-Settings/instantBookmarksToolbar", false);
}
void BrowserWindow::toggleShowNavigationToolbar()
{
setUpdatesEnabled(false);
m_navigationToolbar->setVisible(!m_navigationToolbar->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showNavigationToolbar", m_navigationToolbar->isVisible());
#ifndef Q_OS_MACOS
// Make sure we show Menu Bar when Navigation Toolbar is hidden
if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) {
toggleShowMenubar();
}
#endif
}
void BrowserWindow::toggleTabsOnTop(bool enable)
{
qzSettings->tabsOnTop = enable;
m_navigationContainer->toggleTabsOnTop(enable);
}
void BrowserWindow::toggleFullScreen()
{
if (m_isHtmlFullScreen) {
weView()->triggerPageAction(QWebEnginePage::ExitFullScreen);
return;
}
if (isFullScreen())
showNormal();
else
showFullScreen();
}
void BrowserWindow::toggleHtmlFullScreen(bool enable)
{
if (enable)
showFullScreen();
else
showNormal();
if (m_sideBar)
m_sideBar.data()->setHidden(enable);
m_isHtmlFullScreen = enable;
}
void BrowserWindow::showWebInspector()
{
if (weView() && weView()->webTab()) {
weView()->webTab()->showWebInspector();
}
}
void BrowserWindow::toggleWebInspector()
{
if (weView() && weView()->webTab()) {
weView()->webTab()->toggleWebInspector();
}
}
void BrowserWindow::refreshHistory()
{
m_navigationToolbar->refreshHistory();
}
void BrowserWindow::currentTabChanged()
{
TabbedWebView* view = weView();
m_navigationToolbar->setCurrentView(view);
if (!view) {
return;
}
setWindowTitle(tr("%1 - Falkon").arg(view->webTab()->title()));
m_ipLabel->setText(view->getIp());
view->setFocus();
updateLoadingActions();
// Setting correct tab order (LocationBar -> WebSearchBar -> WebView)
setTabOrder(locationBar(), m_navigationToolbar->webSearchBar());
setTabOrder(m_navigationToolbar->webSearchBar(), view);
}
void BrowserWindow::updateLoadingActions()
{
TabbedWebView* view = weView();
if (!view) {
return;
}
bool isLoading = view->isLoading();
m_ipLabel->setVisible(!isLoading);
m_progressBar->setVisible(isLoading);
action(QSL("View/Stop"))->setEnabled(isLoading);
action(QSL("View/Reload"))->setEnabled(!isLoading);
if (isLoading) {
m_progressBar->setValue(view->loadingProgress());
m_navigationToolbar->showStopButton();
}
else {
m_navigationToolbar->showReloadButton();
}
}
void BrowserWindow::addDeleteOnCloseWidget(QWidget* widget)
{
if (!m_deleteOnCloseWidgets.contains(widget)) {
m_deleteOnCloseWidgets.append(widget);
}
}
void BrowserWindow::restoreWindow(const SavedWindow &window)
{
restoreState(window.windowState);
restoreGeometry(window.windowGeometry);
restoreUiState(window.windowUiState);
#ifdef QZ_WS_X11
moveToVirtualDesktop(window.virtualDesktop);
#endif
show(); // Window has to be visible before adding QWebEngineView's
m_tabWidget->restoreState(window.tabs, window.currentTab);
updateStartupFocus();
}
void BrowserWindow::createToolbarsMenu(QMenu* menu)
{
removeActions(menu->actions());
menu->clear();
QAction* action;
#ifndef Q_OS_MACOS
action = menu->addAction(tr("&Menu Bar"), this, SLOT(toggleShowMenubar()));
action->setCheckable(true);
action->setChecked(menuBar()->isVisible());
#endif
action = menu->addAction(tr("&Navigation Toolbar"), this, SLOT(toggleShowNavigationToolbar()));
action->setCheckable(true);
action->setChecked(m_navigationToolbar->isVisible());
action = menu->addAction(tr("&Bookmarks Toolbar"), this, SLOT(toggleShowBookmarksToolbar()));
action->setCheckable(true);
action->setChecked(Settings().value("Browser-View-Settings/showBookmarksToolbar").toBool());
menu->addSeparator();
action = menu->addAction(tr("&Tabs on Top"), this, SLOT(toggleTabsOnTop(bool)));
action->setCheckable(true);
action->setChecked(qzSettings->tabsOnTop);
addActions(menu->actions());
}
void BrowserWindow::createSidebarsMenu(QMenu* menu)
{
m_sideBarManager->createMenu(menu);
}
void BrowserWindow::createEncodingMenu(QMenu* menu)
{
const QString activeCodecName = mApp->webSettings()->defaultTextEncoding();
QStringList isoCodecs;
QStringList utfCodecs;
QStringList windowsCodecs;
QStringList isciiCodecs;
QStringList ibmCodecs;
QStringList otherCodecs;
QStringList allCodecs;
foreach (const int mib, QTextCodec::availableMibs()) {
const QString codecName = QString::fromUtf8(QTextCodec::codecForMib(mib)->name());
if (!allCodecs.contains(codecName))
allCodecs.append(codecName);
else
continue;
if (codecName.startsWith(QLatin1String("ISO")))
isoCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("UTF")))
utfCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("windows")))
windowsCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("Iscii")))
isciiCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("IBM")))
ibmCodecs.append(codecName);
else
otherCodecs.append(codecName);
}
if (!menu->isEmpty())
menu->addSeparator();
createEncodingSubMenu("ISO", isoCodecs, menu);
createEncodingSubMenu("UTF", utfCodecs, menu);
createEncodingSubMenu("Windows", windowsCodecs, menu);
createEncodingSubMenu("Iscii", isciiCodecs, menu);
createEncodingSubMenu("IBM", ibmCodecs, menu);
createEncodingSubMenu(tr("Other"), otherCodecs, menu);
}
void BrowserWindow::removeActions(const QList &actions)
{
foreach (QAction *action, actions) {
removeAction(action);
}
}
void BrowserWindow::addTab()
{
m_tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true);
m_tabWidget->setCurrentTabFresh(true);
if (isFullScreen())
showNavigationWithFullScreen();
}
void BrowserWindow::webSearch()
{
m_navigationToolbar->webSearchBar()->setFocus();
m_navigationToolbar->webSearchBar()->selectAll();
}
void BrowserWindow::searchOnPage()
{
if (weView() && weView()->webTab()) {
weView()->webTab()->showSearchToolBar();
}
}
void BrowserWindow::openFile()
{
const QString fileTypes = QString("%1(*.html *.htm *.shtml *.shtm *.xhtml);;"
"%2(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff);;"
"%3(*.txt);;"
"%4(*.*)").arg(tr("HTML files"), tr("Image files"), tr("Text files"), tr("All files"));
const QString filePath = QzTools::getOpenFileName("MainWindow-openFile", this, tr("Open file..."), QDir::homePath(), fileTypes);
if (!filePath.isEmpty()) {
loadAddress(QUrl::fromLocalFile(filePath));
}
}
void BrowserWindow::openLocation()
{
if (isFullScreen()) {
showNavigationWithFullScreen();
}
locationBar()->setFocus();
locationBar()->selectAll();
}
bool BrowserWindow::fullScreenNavigationVisible() const
{
return m_navigationContainer->isVisible();
}
void BrowserWindow::showNavigationWithFullScreen()
{
if (m_isHtmlFullScreen)
return;
if (m_hideNavigationTimer->isActive()) {
m_hideNavigationTimer->stop();
}
m_navigationContainer->show();
}
void BrowserWindow::hideNavigationWithFullScreen()
{
if (m_tabWidget->isCurrentTabFresh())
return;
if (!m_hideNavigationTimer->isActive()) {
m_hideNavigationTimer->start();
}
}
void BrowserWindow::hideNavigationSlot()
{
TabbedWebView* view = weView();
bool mouseInView = view && view->underMouse();
if (isFullScreen() && mouseInView) {
m_navigationContainer->hide();
}
}
bool BrowserWindow::event(QEvent* event)
{
switch (event->type()) {
case QEvent::WindowStateChange:
if (!(m_oldWindowState & Qt::WindowFullScreen) && windowState() & Qt::WindowFullScreen) {
// Enter fullscreen
m_normalWindowState = m_oldWindowState;
m_statusBarVisible = statusBar()->isVisible();
#ifndef Q_OS_MACOS
m_menuBarVisible = menuBar()->isVisible();
menuBar()->hide();
#endif
statusBar()->hide();
m_navigationContainer->hide();
+ m_navigationToolbar->enterFullScreen();
}
else if (m_oldWindowState & Qt::WindowFullScreen && !(windowState() & Qt::WindowFullScreen)) {
// Leave fullscreen
statusBar()->setVisible(m_statusBarVisible);
#ifndef Q_OS_MACOS
menuBar()->setVisible(m_menuBarVisible);
#endif
m_navigationContainer->show();
m_navigationToolbar->setSuperMenuVisible(!m_menuBarVisible);
+ m_navigationToolbar->leaveFullScreen();
m_isHtmlFullScreen = false;
}
if (m_hideNavigationTimer) {
m_hideNavigationTimer->stop();
}
m_oldWindowState = windowState();
break;
default:
break;
}
return QMainWindow::event(event);
}
void BrowserWindow::resizeEvent(QResizeEvent* event)
{
m_bookmarksToolbar->setMaximumWidth(width());
QMainWindow::resizeEvent(event);
}
void BrowserWindow::keyPressEvent(QKeyEvent* event)
{
if (mApp->plugins()->processKeyPress(Qz::ON_BrowserWindow, this, event)) {
return;
}
int number = -1;
TabbedWebView* view = weView();
switch (event->key()) {
case Qt::Key_Back:
if (view) {
view->back();
event->accept();
}
break;
case Qt::Key_Forward:
if (view) {
view->forward();
event->accept();
}
break;
case Qt::Key_Stop:
if (view) {
view->stop();
event->accept();
}
break;
case Qt::Key_Reload:
case Qt::Key_Refresh:
if (view) {
view->reload();
event->accept();
}
break;
case Qt::Key_HomePage:
goHome();
event->accept();
break;
case Qt::Key_Favorites:
mApp->browsingLibrary()->showBookmarks(this);
event->accept();
break;
case Qt::Key_Search:
searchOnPage();
event->accept();
break;
case Qt::Key_F6:
case Qt::Key_OpenUrl:
openLocation();
event->accept();
break;
case Qt::Key_History:
showHistoryManager();
event->accept();
break;
case Qt::Key_AddFavorite:
bookmarkPage();
event->accept();
break;
case Qt::Key_News:
action(QSL("Tools/RssReader"))->trigger();
event->accept();
break;
case Qt::Key_Tools:
action(QSL("Standard/Preferences"))->trigger();
event->accept();
break;
case Qt::Key_Tab:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->nextTab();
event->accept();
}
break;
case Qt::Key_Backtab:
if (event->modifiers() == (Qt::ControlModifier + Qt::ShiftModifier)) {
m_tabWidget->previousTab();
event->accept();
}
break;
case Qt::Key_PageDown:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->nextTab();
event->accept();
}
break;
case Qt::Key_PageUp:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->previousTab();
event->accept();
}
break;
case Qt::Key_Equal:
if (view && event->modifiers() == Qt::ControlModifier) {
view->zoomIn();
event->accept();
}
break;
case Qt::Key_I:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("Tools/SiteInfo"))->trigger();
event->accept();
}
break;
case Qt::Key_U:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("View/PageSource"))->trigger();
event->accept();
}
break;
case Qt::Key_F:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("Edit/Find"))->trigger();
event->accept();
}
break;
case Qt::Key_Slash:
if (m_useSingleKeyShortcuts) {
action(QSL("Edit/Find"))->trigger();
event->accept();
}
break;
case Qt::Key_1:
number = 1;
break;
case Qt::Key_2:
number = 2;
break;
case Qt::Key_3:
number = 3;
break;
case Qt::Key_4:
number = 4;
break;
case Qt::Key_5:
number = 5;
break;
case Qt::Key_6:
number = 6;
break;
case Qt::Key_7:
number = 7;
break;
case Qt::Key_8:
number = 8;
break;
case Qt::Key_9:
number = 9;
break;
default:
break;
}
if (number != -1) {
if (event->modifiers() & Qt::AltModifier && m_useTabNumberShortcuts) {
if (number == 9) {
number = m_tabWidget->count();
}
m_tabWidget->setCurrentIndex(number - 1);
event->accept();
return;
}
if (event->modifiers() & Qt::ControlModifier && m_useSpeedDialNumberShortcuts) {
const QUrl url = mApp->plugins()->speedDial()->urlForShortcut(number - 1);
if (url.isValid()) {
loadAddress(url);
event->accept();
return;
}
}
if (event->modifiers() == Qt::NoModifier && m_useSingleKeyShortcuts) {
if (number == 1)
m_tabWidget->previousTab();
if (number == 2)
m_tabWidget->nextTab();
}
}
QMainWindow::keyPressEvent(event);
}
void BrowserWindow::keyReleaseEvent(QKeyEvent* event)
{
if (mApp->plugins()->processKeyRelease(Qz::ON_BrowserWindow, this, event)) {
return;
}
switch (event->key()) {
case Qt::Key_F:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("Edit/Find"))->trigger();
event->accept();
}
break;
default:
break;
}
QMainWindow::keyReleaseEvent(event);
}
void BrowserWindow::closeEvent(QCloseEvent* event)
{
if (mApp->isClosing()) {
saveSettings();
return;
}
Settings settings;
bool askOnClose = settings.value("Browser-Tabs-Settings/AskOnClosing", true).toBool();
if ((mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) && mApp->windowCount() == 1) {
askOnClose = false;
}
if (askOnClose && m_tabWidget->normalTabsCount() > 1) {
CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, this);
dialog.setDefaultButton(QMessageBox::No);
//~ singular There is still %n open tab and your session won't be stored.\nAre you sure you want to close this window?
//~ plural There are still %n open tabs and your session won't be stored.\nAre you sure you want to close this window?
dialog.setText(tr("There are still %n open tabs and your session won't be stored.\nAre you sure you want to close this window?", "", m_tabWidget->count()));
dialog.setCheckBoxText(tr("Don't ask again"));
dialog.setWindowTitle(tr("There are still open tabs"));
dialog.setIcon(QMessageBox::Warning);
if (dialog.exec() != QMessageBox::Yes) {
event->ignore();
return;
}
if (dialog.isChecked()) {
settings.setValue("Browser-Tabs-Settings/AskOnClosing", false);
}
}
saveSettings();
mApp->closedWindowsManager()->saveWindow(this);
#ifndef Q_OS_MACOS
if (mApp->windowCount() == 1)
mApp->quitApplication();
#endif
event->accept();
}
void BrowserWindow::closeWindow()
{
#ifdef Q_OS_MACOS
close();
return;
#endif
if (mApp->windowCount() > 1) {
close();
}
}
void BrowserWindow::saveSettings()
{
if (mApp->isPrivate()) {
return;
}
Settings settings;
settings.beginGroup("Browser-View-Settings");
settings.setValue("WindowGeometry", saveGeometry());
const auto state = saveUiState();
for (auto it = state.constBegin(); it != state.constEnd(); ++it) {
settings.setValue(it.key(), it.value());
}
settings.endGroup();
}
void BrowserWindow::closeTab()
{
// Don't close pinned tabs with keyboard shortcuts (Ctrl+W, Ctrl+F4)
if (weView() && !weView()->webTab()->isPinned()) {
m_tabWidget->requestCloseTab();
}
}
#ifdef QZ_WS_X11
int BrowserWindow::getCurrentVirtualDesktop() const
{
if (QGuiApplication::platformName() != QL1S("xcb"))
return 0;
xcb_intern_atom_cookie_t intern_atom;
xcb_intern_atom_reply_t *atom_reply = 0;
xcb_atom_t atom;
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply = 0;
uint32_t value;
intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP");
atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0);
if (!atom_reply)
goto error;
atom = atom_reply->atom;
cookie = xcb_get_property(QX11Info::connection(), false, winId(), atom, XCB_ATOM_CARDINAL, 0, 1);
reply = xcb_get_property_reply(QX11Info::connection(), cookie, 0);
if (!reply || reply->type != XCB_ATOM_CARDINAL || reply->value_len != 1 || reply->format != sizeof(uint32_t) * 8)
goto error;
value = *reinterpret_cast(xcb_get_property_value(reply));
free(reply);
free(atom_reply);
return value;
error:
free(reply);
free(atom_reply);
return 0;
}
void BrowserWindow::moveToVirtualDesktop(int desktopId)
{
if (QGuiApplication::platformName() != QL1S("xcb"))
return;
// Don't move when window is already visible or it is first app window
if (desktopId < 0 || isVisible() || m_windowType == Qz::BW_FirstAppWindow)
return;
xcb_intern_atom_cookie_t intern_atom;
xcb_intern_atom_reply_t *atom_reply = 0;
xcb_atom_t atom;
intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP");
atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0);
if (!atom_reply)
goto error;
atom = atom_reply->atom;
xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, winId(), atom,
XCB_ATOM_CARDINAL, 32, 1, (const void*) &desktopId);
error:
free(atom_reply);
}
#endif
diff --git a/src/lib/navigation/navigationbar.cpp b/src/lib/navigation/navigationbar.cpp
index 926647cb..0f620d58 100644
--- a/src/lib/navigation/navigationbar.cpp
+++ b/src/lib/navigation/navigationbar.cpp
@@ -1,623 +1,654 @@
/* ============================================================
* 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 "navigationbar.h"
#include "toolbutton.h"
#include "browserwindow.h"
#include "mainapplication.h"
#include "iconprovider.h"
#include "websearchbar.h"
#include "reloadstopbutton.h"
#include "enhancedmenu.h"
#include "tabwidget.h"
#include "tabbedwebview.h"
#include "webpage.h"
#include "qzsettings.h"
#include "qztools.h"
#include "abstractbuttoninterface.h"
#include "navigationbartoolbutton.h"
#include "navigationbarconfigdialog.h"
#include
#include
#include
#include
#include
#include
#include
static QString titleForUrl(QString title, const QUrl &url)
{
if (title.isEmpty()) {
title = url.toString(QUrl::RemoveFragment);
}
if (title.isEmpty()) {
return NavigationBar::tr("Empty Page");
}
return QzTools::truncatedText(title, 40);
}
static QIcon iconForPage(const QUrl &url, const QIcon &sIcon)
{
QIcon icon;
icon.addPixmap(url.scheme() == QL1S("qupzilla") ? QIcon(QSL(":icons/qupzilla.png")).pixmap(16) : IconProvider::iconForUrl(url).pixmap(16));
icon.addPixmap(sIcon.pixmap(16), QIcon::Active);
return icon;
}
NavigationBar::NavigationBar(BrowserWindow* window)
: QWidget(window)
, m_window(window)
{
setObjectName(QSL("navigationbar"));
m_layout = new QHBoxLayout(this);
m_layout->setMargin(style()->pixelMetric(QStyle::PM_ToolBarItemMargin, 0, this)
+ style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, 0, this));
m_layout->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing, 0, this));
setLayout(m_layout);
m_buttonBack = new ToolButton(this);
m_buttonBack->setObjectName("navigation-button-back");
m_buttonBack->setToolTip(tr("Back"));
m_buttonBack->setToolButtonStyle(Qt::ToolButtonIconOnly);
m_buttonBack->setToolbarButtonLook(true);
m_buttonBack->setShowMenuOnRightClick(true);
m_buttonBack->setAutoRaise(true);
m_buttonBack->setEnabled(false);
m_buttonBack->setFocusPolicy(Qt::NoFocus);
m_buttonForward = new ToolButton(this);
m_buttonForward->setObjectName("navigation-button-next");
m_buttonForward->setToolTip(tr("Forward"));
m_buttonForward->setToolButtonStyle(Qt::ToolButtonIconOnly);
m_buttonForward->setToolbarButtonLook(true);
m_buttonForward->setShowMenuOnRightClick(true);
m_buttonForward->setAutoRaise(true);
m_buttonForward->setEnabled(false);
m_buttonForward->setFocusPolicy(Qt::NoFocus);
QHBoxLayout* backNextLayout = new QHBoxLayout();
backNextLayout->setContentsMargins(0, 0, 0, 0);
backNextLayout->setSpacing(0);
backNextLayout->addWidget(m_buttonBack);
backNextLayout->addWidget(m_buttonForward);
QWidget *backNextWidget = new QWidget(this);
backNextWidget->setLayout(backNextLayout);
m_reloadStop = new ReloadStopButton(this);
ToolButton *buttonHome = new ToolButton(this);
buttonHome->setObjectName("navigation-button-home");
buttonHome->setToolTip(tr("Home"));
buttonHome->setToolButtonStyle(Qt::ToolButtonIconOnly);
buttonHome->setToolbarButtonLook(true);
buttonHome->setAutoRaise(true);
buttonHome->setFocusPolicy(Qt::NoFocus);
ToolButton *buttonAddTab = new ToolButton(this);
buttonAddTab->setObjectName("navigation-button-addtab");
buttonAddTab->setToolTip(tr("New Tab"));
buttonAddTab->setToolButtonStyle(Qt::ToolButtonIconOnly);
buttonAddTab->setToolbarButtonLook(true);
buttonAddTab->setAutoRaise(true);
buttonAddTab->setFocusPolicy(Qt::NoFocus);
m_menuBack = new Menu(this);
m_menuBack->setCloseOnMiddleClick(true);
m_buttonBack->setMenu(m_menuBack);
connect(m_buttonBack, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowHistoryBackMenu()));
m_menuForward = new Menu(this);
m_menuForward->setCloseOnMiddleClick(true);
m_buttonForward->setMenu(m_menuForward);
connect(m_buttonForward, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowHistoryNextMenu()));
ToolButton *buttonTools = new ToolButton(this);
buttonTools->setObjectName("navigation-button-tools");
buttonTools->setPopupMode(QToolButton::InstantPopup);
buttonTools->setToolbarButtonLook(true);
buttonTools->setToolTip(tr("Tools"));
buttonTools->setAutoRaise(true);
buttonTools->setFocusPolicy(Qt::NoFocus);
buttonTools->setShowMenuInside(true);
m_menuTools = new Menu(this);
buttonTools->setMenu(m_menuTools);
connect(buttonTools, &ToolButton::aboutToShowMenu, this, &NavigationBar::aboutToShowToolsMenu);
m_supMenu = new ToolButton(this);
m_supMenu->setObjectName("navigation-button-supermenu");
m_supMenu->setPopupMode(QToolButton::InstantPopup);
m_supMenu->setToolbarButtonLook(true);
m_supMenu->setToolTip(tr("Main Menu"));
m_supMenu->setAutoRaise(true);
m_supMenu->setFocusPolicy(Qt::NoFocus);
m_supMenu->setMenu(m_window->superMenu());
m_supMenu->setShowMenuInside(true);
m_searchLine = new WebSearchBar(m_window);
m_navigationSplitter = new QSplitter(this);
m_navigationSplitter->addWidget(m_window->tabWidget()->locationBars());
m_navigationSplitter->addWidget(m_searchLine);
m_navigationSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_navigationSplitter->setCollapsible(0, false);
+ m_exitFullscreen = new ToolButton(this);
+ m_exitFullscreen->setObjectName("navigation-button-exitfullscreen");
+ m_exitFullscreen->setToolTip(tr("Exit Fullscreen"));
+ m_exitFullscreen->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ m_exitFullscreen->setToolbarButtonLook(true);
+ m_exitFullscreen->setFocusPolicy(Qt::NoFocus);
+ m_exitFullscreen->setAutoRaise(true);
+ m_exitFullscreen->setVisible(false);
+
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(m_buttonBack, SIGNAL(clicked()), this, SLOT(goBack()));
connect(m_buttonBack, SIGNAL(middleMouseClicked()), this, SLOT(goBackInNewTab()));
connect(m_buttonBack, SIGNAL(controlClicked()), this, SLOT(goBackInNewTab()));
connect(m_buttonForward, SIGNAL(clicked()), this, SLOT(goForward()));
connect(m_buttonForward, SIGNAL(middleMouseClicked()), this, SLOT(goForwardInNewTab()));
connect(m_buttonForward, SIGNAL(controlClicked()), this, SLOT(goForwardInNewTab()));
connect(m_reloadStop, SIGNAL(stopClicked()), this, SLOT(stop()));
connect(m_reloadStop, SIGNAL(reloadClicked()), this, SLOT(reload()));
connect(buttonHome, SIGNAL(clicked()), m_window, SLOT(goHome()));
connect(buttonHome, SIGNAL(middleMouseClicked()), m_window, SLOT(goHomeInNewTab()));
connect(buttonHome, SIGNAL(controlClicked()), m_window, SLOT(goHomeInNewTab()));
connect(buttonAddTab, SIGNAL(clicked()), m_window, SLOT(addTab()));
connect(buttonAddTab, SIGNAL(middleMouseClicked()), m_window->tabWidget(), SLOT(addTabFromClipboard()));
+ connect(m_exitFullscreen, SIGNAL(clicked(bool)), m_window, SLOT(toggleFullScreen()));
connect(mApp, &MainApplication::settingsReloaded, this, &NavigationBar::loadSettings);
addWidget(backNextWidget, QSL("button-backforward"), tr("Back and Forward buttons"));
addWidget(m_reloadStop, QSL("button-reloadstop"), tr("Reload button"));
addWidget(buttonHome, QSL("button-home"), tr("Home button"));
addWidget(buttonAddTab, QSL("button-addtab"), tr("Add tab button"));
addWidget(m_navigationSplitter, QSL("locationbar"), tr("Address and Search bar"));
addWidget(buttonTools, QSL("button-tools"), tr("Tools button"));
+ addWidget(m_exitFullscreen, QSL("button-exitfullscreen"), tr("Exit Fullscreen button"));
loadSettings();
}
NavigationBar::~NavigationBar()
{
setCurrentView(nullptr);
}
void NavigationBar::setSplitterSizes(int locationBar, int websearchBar)
{
QList sizes;
if (locationBar == 0) {
int splitterWidth = m_navigationSplitter->width();
sizes << (int)((double)splitterWidth * .80) << (int)((double)splitterWidth * .20);
}
else {
sizes << locationBar << websearchBar;
}
m_navigationSplitter->setSizes(sizes);
}
void NavigationBar::setCurrentView(TabbedWebView *view)
{
for (const WidgetData &data : qAsConst(m_widgets)) {
if (data.button) {
data.button->setWebView(view);
}
}
}
void NavigationBar::showReloadButton()
{
m_reloadStop->showReloadButton();
}
void NavigationBar::showStopButton()
{
m_reloadStop->showStopButton();
}
+void NavigationBar::enterFullScreen()
+{
+ if (m_layout->indexOf(m_exitFullscreen) != -1) {
+ m_exitFullscreen->show();
+ }
+}
+
+void NavigationBar::leaveFullScreen()
+{
+ if (m_layout->indexOf(m_exitFullscreen) != -1) {
+ m_exitFullscreen->hide();
+ }
+}
+
void NavigationBar::setSuperMenuVisible(bool visible)
{
m_supMenu->setVisible(visible);
}
int NavigationBar::layoutMargin() const
{
return m_layout->margin();
}
void NavigationBar::setLayoutMargin(int margin)
{
m_layout->setMargin(margin);
}
int NavigationBar::layoutSpacing() const
{
return m_layout->spacing();
}
void NavigationBar::setLayoutSpacing(int spacing)
{
m_layout->setSpacing(spacing);
}
void NavigationBar::addWidget(QWidget *widget, const QString &id, const QString &name)
{
if (!widget || id.isEmpty() || name.isEmpty()) {
return;
}
WidgetData data;
data.id = id;
data.name = name;
data.widget = widget;
m_widgets[id] = data;
reloadLayout();
}
void NavigationBar::removeWidget(const QString &id)
{
if (!m_widgets.contains(id)) {
return;
}
m_widgets.remove(id);
reloadLayout();
}
void NavigationBar::addToolButton(AbstractButtonInterface *button)
{
if (!button || !button->isValid()) {
return;
}
WidgetData data;
data.id = button->id();
data.name = button->name();
data.widget = new NavigationBarToolButton(button, this);
data.button = button;
m_widgets[data.id] = data;
data.button->setWebView(m_window->weView());
reloadLayout();
}
void NavigationBar::removeToolButton(AbstractButtonInterface *button)
{
if (!button || !m_widgets.contains(button->id())) {
return;
}
delete m_widgets.take(button->id()).widget;
}
void NavigationBar::aboutToShowHistoryBackMenu()
{
if (!m_menuBack || !m_window->weView()) {
return;
}
m_menuBack->clear();
QWebEngineHistory* history = m_window->weView()->history();
int curindex = history->currentItemIndex();
int count = 0;
for (int i = curindex - 1; i >= 0; i--) {
QWebEngineHistoryItem item = history->itemAt(i);
if (item.isValid()) {
QString title = titleForUrl(item.title(), item.url());
const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowBack));
Action* act = new Action(icon, title);
act->setData(i);
connect(act, SIGNAL(triggered()), this, SLOT(loadHistoryIndex()));
connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab()));
m_menuBack->addAction(act);
}
count++;
if (count == 20) {
break;
}
}
m_menuBack->addSeparator();
m_menuBack->addAction(tr("Clear history"), this, SLOT(clearHistory()));
}
void NavigationBar::aboutToShowHistoryNextMenu()
{
if (!m_menuForward || !m_window->weView()) {
return;
}
m_menuForward->clear();
QWebEngineHistory* history = m_window->weView()->history();
int curindex = history->currentItemIndex();
int count = 0;
for (int i = curindex + 1; i < history->count(); i++) {
QWebEngineHistoryItem item = history->itemAt(i);
if (item.isValid()) {
QString title = titleForUrl(item.title(), item.url());
const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowForward));
Action* act = new Action(icon, title);
act->setData(i);
connect(act, SIGNAL(triggered()), this, SLOT(loadHistoryIndex()));
connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab()));
m_menuForward->addAction(act);
}
count++;
if (count == 20) {
break;
}
}
m_menuForward->addSeparator();
m_menuForward->addAction(tr("Clear history"), this, SLOT(clearHistory()));
}
void NavigationBar::aboutToShowToolsMenu()
{
m_menuTools->clear();
m_window->createToolbarsMenu(m_menuTools->addMenu(tr("Toolbars")));
m_window->createSidebarsMenu(m_menuTools->addMenu(tr("Sidebar")));
m_menuTools->addSeparator();
for (const WidgetData &data : qAsConst(m_widgets)) {
AbstractButtonInterface *button = data.button;
if (button && !m_layoutIds.contains(data.id)) {
QString title = button->title();
if (!button->badgeText().isEmpty()) {
title.append(QSL(" (%1)").arg(button->badgeText()));
}
m_menuTools->addAction(button->icon(), title, this, &NavigationBar::toolActionActivated)->setData(data.id);
}
}
m_menuTools->addSeparator();
m_menuTools->addAction(IconProvider::settingsIcon(), tr("Configure Toolbar"), this, SLOT(openConfigurationDialog()));
}
void NavigationBar::clearHistory()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
history->clear();
refreshHistory();
}
void NavigationBar::contextMenuRequested(const QPoint &pos)
{
QMenu menu;
m_window->createToolbarsMenu(&menu);
menu.addSeparator();
menu.addAction(IconProvider::settingsIcon(), tr("Configure Toolbar"), this, SLOT(openConfigurationDialog()));
menu.exec(mapToGlobal(pos));
}
void NavigationBar::openConfigurationDialog()
{
NavigationBarConfigDialog *dialog = new NavigationBarConfigDialog(this);
dialog->show();
}
void NavigationBar::toolActionActivated()
{
QAction *act = qobject_cast(sender());
if (!act) {
return;
}
const QString id = act->data().toString();
if (!m_widgets.contains(id)) {
return;
}
WidgetData data = m_widgets.value(id);
if (!data.button) {
return;
}
ToolButton *buttonTools = qobject_cast(m_widgets.value(QSL("button-tools")).widget);
if (!buttonTools) {
return;
}
AbstractButtonInterface::ClickController c;
c.visualParent = buttonTools;
c.popupPosition = [=](const QSize &size) {
QPoint pos = buttonTools->mapToGlobal(buttonTools->rect().bottomRight());
if (QApplication::isRightToLeft()) {
pos.setX(pos.x() - buttonTools->rect().width());
} else {
pos.setX(pos.x() - size.width());
}
return pos;
};
buttonTools->setDown(true);
emit data.button->clicked(&c);
buttonTools->setDown(false);
}
void NavigationBar::loadSettings()
{
const QStringList defaultIds = {
QSL("button-backforward"),
QSL("button-reloadstop"),
QSL("button-home"),
QSL("locationbar"),
QSL("button-tools")
};
Settings settings;
settings.beginGroup(QSL("NavigationBar"));
m_layoutIds = settings.value(QSL("Layout"), defaultIds).toStringList();
m_searchLine->setVisible(settings.value(QSL("ShowSearchBar"), true).toBool());
settings.endGroup();
m_layoutIds.removeDuplicates();
if (!m_layoutIds.contains(QSL("locationbar"))) {
m_layoutIds.append(QSL("locationbar"));
}
reloadLayout();
}
void NavigationBar::reloadLayout()
{
if (m_widgets.isEmpty()) {
return;
}
setUpdatesEnabled(false);
// Clear layout
while (m_layout->count() != 0) {
QLayoutItem *item = m_layout->takeAt(0);
if (!item) {
continue;
}
QWidget *widget = item->widget();
if (!widget) {
continue;
}
widget->setParent(nullptr);
}
// Hide all widgets
for (const WidgetData &data : m_widgets) {
data.widget->hide();
}
// Add widgets to layout
for (const QString &id : qAsConst(m_layoutIds)) {
const WidgetData data = m_widgets.value(id);
if (data.widget) {
m_layout->addWidget(data.widget);
data.widget->show();
}
}
m_layout->addWidget(m_supMenu);
// Make sure search bar is visible
if (m_searchLine->isVisible() && m_navigationSplitter->sizes().at(1) == 0) {
const int locationBarSize = m_navigationSplitter->sizes().at(0);
setSplitterSizes(locationBarSize - 50, 50);
}
+ if (m_window->isFullScreen()) {
+ enterFullScreen();
+ } else {
+ leaveFullScreen();
+ }
+
setUpdatesEnabled(true);
}
void NavigationBar::loadHistoryIndex()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
if (QAction* action = qobject_cast(sender())) {
loadHistoryItem(history->itemAt(action->data().toInt()));
}
}
void NavigationBar::loadHistoryIndexInNewTab(int index)
{
if (QAction* action = qobject_cast(sender())) {
index = action->data().toInt();
}
if (index == -1) {
return;
}
QWebEngineHistory* history = m_window->weView()->page()->history();
loadHistoryItemInNewTab(history->itemAt(index));
}
void NavigationBar::refreshHistory()
{
if (mApp->isClosing() || !m_window->weView()) {
return;
}
QWebEngineHistory* history = m_window->weView()->page()->history();
m_buttonBack->setEnabled(history->canGoBack());
m_buttonForward->setEnabled(history->canGoForward());
}
void NavigationBar::stop()
{
m_window->action(QSL("View/Stop"))->trigger();
}
void NavigationBar::reload()
{
m_window->action(QSL("View/Reload"))->trigger();
}
void NavigationBar::goBack()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
history->back();
}
void NavigationBar::goBackInNewTab()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
if (!history->canGoBack()) {
return;
}
loadHistoryItemInNewTab(history->backItem());
}
void NavigationBar::goForward()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
history->forward();
}
void NavigationBar::goForwardInNewTab()
{
QWebEngineHistory* history = m_window->weView()->page()->history();
if (!history->canGoForward()) {
return;
}
loadHistoryItemInNewTab(history->forwardItem());
}
void NavigationBar::loadHistoryItem(const QWebEngineHistoryItem &item)
{
m_window->weView()->page()->history()->goToItem(item);
refreshHistory();
}
void NavigationBar::loadHistoryItemInNewTab(const QWebEngineHistoryItem &item)
{
TabWidget* tabWidget = m_window->tabWidget();
int tabIndex = tabWidget->duplicateTab(tabWidget->currentIndex());
QWebEngineHistory* history = m_window->weView(tabIndex)->page()->history();
history->goToItem(item);
if (qzSettings->newTabPosition == Qz::NT_SelectedTab) {
tabWidget->setCurrentIndex(tabIndex);
}
}
diff --git a/src/lib/navigation/navigationbar.h b/src/lib/navigation/navigationbar.h
index 0574de80..f1719634 100644
--- a/src/lib/navigation/navigationbar.h
+++ b/src/lib/navigation/navigationbar.h
@@ -1,126 +1,131 @@
/* ============================================================
* 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 .
* ============================================================ */
#ifndef NAVIGATIONBAR_H
#define NAVIGATIONBAR_H
#include
#include "qzcommon.h"
class QUrl;
class QHBoxLayout;
class QSplitter;
class QWebEngineHistoryItem;
class ToolButton;
class WebSearchBar;
class BrowserWindow;
class ReloadStopButton;
class Menu;
class AbstractButtonInterface;
class TabbedWebView;
class FALKON_EXPORT NavigationBar : public QWidget
{
Q_OBJECT
Q_PROPERTY(int layoutMargin READ layoutMargin WRITE setLayoutMargin)
Q_PROPERTY(int layoutSpacing READ layoutSpacing WRITE setLayoutSpacing)
public:
explicit NavigationBar(BrowserWindow* window);
~NavigationBar();
void setSplitterSizes(int locationBar, int websearchBar);
void setCurrentView(TabbedWebView *view);
+
void showReloadButton();
void showStopButton();
+ void enterFullScreen();
+ void leaveFullScreen();
+
WebSearchBar* webSearchBar() { return m_searchLine; }
QSplitter* splitter() { return m_navigationSplitter; }
void setSuperMenuVisible(bool visible);
int layoutMargin() const;
void setLayoutMargin(int margin);
int layoutSpacing() const;
void setLayoutSpacing(int spacing);
void addWidget(QWidget *widget, const QString &id, const QString &name);
void removeWidget(const QString &id);
void addToolButton(AbstractButtonInterface *button);
void removeToolButton(AbstractButtonInterface *button);
public slots:
void refreshHistory();
void stop();
void reload();
void goBack();
void goBackInNewTab();
void goForward();
void goForwardInNewTab();
private slots:
void aboutToShowHistoryNextMenu();
void aboutToShowHistoryBackMenu();
void aboutToShowToolsMenu();
void loadHistoryIndex();
void loadHistoryIndexInNewTab(int index = -1);
void clearHistory();
void contextMenuRequested(const QPoint &pos);
void openConfigurationDialog();
void toolActionActivated();
private:
void loadSettings();
void reloadLayout();
void loadHistoryItem(const QWebEngineHistoryItem &item);
void loadHistoryItemInNewTab(const QWebEngineHistoryItem &item);
BrowserWindow* m_window;
QHBoxLayout* m_layout;
QSplitter* m_navigationSplitter;
WebSearchBar* m_searchLine;
Menu* m_menuBack;
Menu* m_menuForward;
ToolButton* m_buttonBack;
ToolButton* m_buttonForward;
ReloadStopButton* m_reloadStop;
Menu *m_menuTools;
ToolButton* m_supMenu;
+ ToolButton *m_exitFullscreen;
struct WidgetData {
QString id;
QString name;
QWidget *widget = nullptr;
AbstractButtonInterface *button = nullptr;
};
QStringList m_layoutIds;
QHash m_widgets;
friend class NavigationBarConfigDialog;
};
#endif // NAVIGATIONBAR_H
diff --git a/themes/chrome/main.css b/themes/chrome/main.css
index 9397e78e..ed6dc01b 100644
--- a/themes/chrome/main.css
+++ b/themes/chrome/main.css
@@ -1,356 +1,361 @@
/*************************************
* Chrome Theme *
* Author: nowrep *
* Based on: Firefox Chromifox Theme *
*************************************/
*[html-link-look="true"]
{
color: palette(link);
text-decoration: underline;
}
/*MainWindow*/
#mainwindow
{
background: #e4edf9 url(images/toolbar-bg.png) repeat-x;
}
#mainwindow-menubar
{
background: transparent;
border: none;
}
#mainwindow-menubar:item
{
color: black;
spacing: 5px;
padding: 2px 6px;
background: transparent;
}
#mainwindow-menubar::item:pressed
{
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #a1c0e6, stop:1 #86abd9);
border: 1px solid #4b6e99;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom: none;
}
#mainwindow-statusbar
{
background-color: #e4edf9;
}
#statusbar-ip-label
{
padding-right: 5px;
}
/*NavigationBar*/
#navigationbar
{
qproperty-layoutMargin: 3;
qproperty-layoutSpacing: 3;
}
#navigationbar QSplitter::handle
{
background-color:transparent;
}
#navigation-button-back
{
qproperty-multiIcon: url(images/navigation-back.png);
}
#navigation-button-next
{
qproperty-multiIcon: url(images/navigation-forward.png);
}
#navigation-button-stop
{
qproperty-multiIcon: url(images/navigation-stop.png);
}
#navigation-button-reload
{
qproperty-multiIcon: url(images/navigation-reload.png);
}
#navigation-button-home
{
qproperty-multiIcon: url(images/navigation-home.png);
}
#navigation-button-addtab
{
qproperty-multiIcon: url(images/navigation-addtab.png);
}
#navigation-button-tools
{
qproperty-icon: url(images/navigation-tools.png);
}
+#navigation-button-exitfullscreen
+{
+ qproperty-icon: url(images/navigation-exit-fullscreen.png);
+}
+
#navigation-button-supermenu
{
qproperty-multiIcon: url(images/navigation-supermenu.png);
}
#navigation-toolbutton-badge
{
background: palette(dark);
color: palette(bright-text);
margin: 0px 1px;
}
ToolButton[toolbar-look="true"]
{
qproperty-iconSize: 19px 19px;
qproperty-fixedsize: 31px 29px;
border-image: url(images/toolbutton.png);
}
ToolButton[toolbar-look="true"]:hover
{
border-image: url(images/toolbutton-h.png);
}
ToolButton[toolbar-look="true"]:pressed
{
border-image: url(images/toolbutton-a.png);
}
/*TabWidget*/
#tabbar
{
qproperty-tabPadding: -1;
qproperty-baseColor: 0;
}
#tabbar::scroller
{
width: 0px;
}
#tabbar-button-right
{
qproperty-icon: url(images/tab-right-arrow.png);
qproperty-fixedsize: 15px 25px;
}
#tabbar-button-left
{
qproperty-icon: url(images/tab-left-arrow.png);
qproperty-fixedsize: 15px 25px;
}
#tabwidget-button-opentabs
{
qproperty-multiIcon: url(images/tabs-list-button.png);
}
#tabwidget-button-closedtabs
{
qproperty-multiIcon: url(images/tabs-closed-button.png);
}
#tabwidget-button-addtab
{
qproperty-multiIcon: url(images/tabbar-addtab.png);
}
/*IconProvider*/
IconProvider
{
qproperty-bookmarkIcon: url(images/star-a.png);
}
/*LocationBar*/
#locationbar
{
background: transparent;
border-image: url(images/lineedit-bg.png);
border-width: 3px;
color:black;
padding-right: 0px;
padding-left: 0px;
padding-top: -2px;
padding-bottom: -2px;
qproperty-fixedheight: 27;
qproperty-leftMargin: 28;
}
#locationbar-bookmarkicon
{
margin-bottom: 2px;
qproperty-pixmap: url(images/star.png);
}
#locationbar-bookmarkicon[bookmarked="true"]
{
qproperty-pixmap: url(images/star-a.png);
}
#locationbar-siteicon
{
border-image: url(images/siteicon-bg.png);
qproperty-fixedsize:30px 27px;
padding-left: 0px;
}
#locationbar-siteicon[secured="true"]
{
border-image: url(images/siteicon-secure-bg.png);
}
#locationbar-goicon
{
qproperty-pixmap: url(images/gotoaddress.png);
}
#locationbar-down-icon
{
margin-bottom: 1px;
qproperty-pixmap: url(images/navigation-dropdown.png);
}
#locationbar-autofillicon
{
margin-bottom: 1px;
qproperty-pixmap: url(images/key.png);
}
/*SideBar*/
#sidebar
{
background: transparent;
}
#sidebar-splitter::handle
{
background-color:transparent;
}
/*WebSearchBar*/
#websearchbar
{
background: transparent;
border-image: url(images/lineedit-bg.png);
border-width: 3px;
color:black;
padding-right: 0px;
padding-left: 0px;
padding-top: -2px;
padding-bottom: -2px;
qproperty-fixedheight: 27;
qproperty-leftMargin: 35;
}
#websearchbar-searchbutton
{
margin-top: 2px;
margin-right: 2px;
qproperty-pixmap: url(images/search-icon.png);
}
#websearchbar-searchprovider-comobobox
{
border-image: url(images/searchbar-provider-bg.png);
padding-left:-8px;
qproperty-fixedsize: 37px 27px;
}
/*SourceViewer*/
#sourceviewer-textedit
{
border:none;
}
/*SourceViewerSearch*/
SourceViewerSearch #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*SearchToolbar*/
SearchToolBar #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*AboutDialog*/
AboutDialog #label
{
background:white;
}
AboutDialog #textBrowser
{
border:none;
margin-top: -2px; /* Workarounding rounded border on KDE */
}
/*DesktopNotification*/
DesktopNotification
{
background: transparent;
}
DesktopNotification #frame
{
border: 2px solid darkblue;
border-radius: 20px;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e4ecf1, stop:1 #d3e5f1);
}
DesktopNotification #heading
{
font: bold;
font-size: 13pt;
}
/*BrowsingLibrary*/
BrowsingLibrary #tabs
{
qproperty-bgPixmap: url(images/library-bg.png);
}
BrowsingLibrary #frame
{
background: url(images/library-bg.png);
}
/*Downloads*/
DownloadItem #fileName
{
font-size: 13pt;
}
DownloadManager #list
{
border: none;
}
/*JavaScript Dialogs*/
#jsFrame
{
background: url(images/semi-transp.png);
}
QFrame[js-frame="true"]
{
border: 1px solid black;
border-bottom: 0px;
background-color: white;
}
QFrame[js-frame2="true"]
{
border: 1px solid black;
border-top: 0px;
background-color: #f3f3f3;
}
diff --git a/themes/linux/main.css b/themes/linux/main.css
index 36d56336..5b64f288 100644
--- a/themes/linux/main.css
+++ b/themes/linux/main.css
@@ -1,273 +1,279 @@
/*************************************
* Linux Theme *
* Author: David Rosca *
* Using native widgets and icons *
*************************************/
*[html-link-look="true"]
{
color: palette(link);
text-decoration: underline;
}
/*MainWindow*/
#statusbar-ip-label
{
padding-right: 5px;
}
/*NavigationBar*/
#navigation-button-back
{
qproperty-themeIcon: "go-previous";
}
#navigation-button-next
{
qproperty-themeIcon: "go-next";
}
#navigation-button-stop
{
qproperty-themeIcon: "process-stop";
}
#navigation-button-reload
{
qproperty-themeIcon: "view-refresh";
}
#navigation-button-home
{
qproperty-themeIcon: "go-home";
}
#navigation-button-addtab
{
qproperty-themeIcon: "list-add";
}
#navigation-button-tools
{
qproperty-themeIcon: "arrow-right-double";
qproperty-fallbackIcon: url(images/tools.svg);
}
+#navigation-button-exitfullscreen
+{
+ qproperty-themeIcon: "view-restore";
+ qproperty-fallbackIcon: url(images/exit-fullscreen.svg);
+}
+
#navigation-button-supermenu
{
qproperty-themeIcon: "application-menu";
qproperty-fallbackIcon: url(images/menu.svg);
}
#navigation-toolbutton-badge
{
background: palette(dark);
color: palette(bright-text);
margin: 0px 1px;
}
/*TabWidget*/
#tabbar
{
qproperty-tabPadding: -1;
qproperty-baseColor: 0;
}
#tabbar-button-right
{
qproperty-themeIcon: "arrow-right";
qproperty-fallbackIcon: url(images/tab-right-arrow.svg);
qproperty-fixedsize: 15px 25px;
}
#tabbar-button-left
{
qproperty-themeIcon: "arrow-left";
qproperty-fallbackIcon: url(images/tab-left-arrow.svg);
qproperty-fixedsize: 15px 25px;
}
#tabwidget-button-opentabs
{
qproperty-themeIcon: "arrow-down";
qproperty-fallbackIcon: url(images/arrow-down.svg);
qproperty-fixedsize: 20px 25px;
}
#tabwidget-button-closedtabs
{
qproperty-themeIcon: "user-trash-full";
qproperty-fixedsize: 22px 25px;
}
#tabwidget-button-addtab
{
qproperty-themeIcon: "list-add";
qproperty-fixedsize: 22px 25px;
}
/*IconProvider*/
IconProvider
{
qproperty-bookmarkIcon: url(images/star-a.svg);
}
/*LocationBar*/
#locationbar
{
qproperty-leftMargin: 25;
}
#locationbar-bookmarkicon
{
qproperty-themeIcon: "rating-unrated";
qproperty-fallbackIcon: url(images/star.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-bookmarkicon[bookmarked="true"]
{
qproperty-themeIcon: "rating";
qproperty-fallbackIcon: url(images/star-a.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-siteicon
{
border-image: url(images/transp.png);
padding-left: 5px;
qproperty-fixedsize: 25px 16px;
}
#locationbar-goicon
{
qproperty-themeIcon: "go-jump-locationbar";
qproperty-fallbackIcon: url(images/goto.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-down-icon
{
qproperty-themeIcon: "arrow-down";
qproperty-fallbackIcon: url(images/arrow-down.svg);
qproperty-fixedsize: 12px 16px;
}
#locationbar-autofillicon
{
qproperty-themeIcon: "user-identity";
qproperty-fallbackIcon: url(images/user.svg);
qproperty-fixedsize: 16px 16px;
}
/*WebSearchBar*/
#websearchbar
{
qproperty-leftMargin: 25;
}
#websearchbar-searchbutton
{
qproperty-fixedsize: 22px 16px;
qproperty-themeIcon: "edit-find";
}
#websearchbar-searchprovider-comobobox
{
border-image: url(images/transp.png);
padding-left: 5px;
qproperty-fixedsize: 25px 16px;
}
/*BookmarksToolbar*/
#bookmarksbar QToolButton
{
border-image: url(images/transp.png);
border-width: 0px;
height: 15px;
}
/*SideBar*/
#sidebar
{
background: transparent;
}
/*SearchToolbar*/
SearchToolBar #lineEdit[notfound="true"]
{
background: #ff6666;
}
/*AboutDialog*/
AboutDialog #label
{
background: white;
}
AboutDialog #textBrowser
{
border: none;
margin-top: -2px; /* Workarounding rounded border on KDE */
}
/*DesktopNotification*/
DesktopNotification
{
background: transparent;
}
DesktopNotification #frame
{
border: 2px solid darkblue;
border-radius: 20px;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e4ecf1, stop:1 #d3e5f1);
}
DesktopNotification #heading
{
font: bold;
font-size: 13pt;
}
/*BrowsingLibrary*/
BrowsingLibrary #tabs
{
qproperty-bgPixmap: url(images/library-bg.png);
}
BrowsingLibrary #frame
{
background: url(images/library-bg.png);
}
/*Downloads*/
DownloadItem #fileName
{
font-size: 13pt;
}
DownloadManager #list
{
border: none;
}
/*JavaScript Dialogs*/
#jsFrame
{
background: url(images/semi-transp.png);
}
QFrame[js-frame="true"]
{
border: 1px solid black;
border-bottom: 0px;
background-color: white;
}
QFrame[js-frame2="true"]
{
border: 1px solid black;
border-top: 0px;
background-color: #f3f3f3;
}
diff --git a/themes/mac/main.css b/themes/mac/main.css
index b2d97520..401c0795 100644
--- a/themes/mac/main.css
+++ b/themes/mac/main.css
@@ -1,360 +1,365 @@
/*************************************
* Mac Theme *
* Author: nowrep *
* Based on: Firefox Mac OS X Theme *
*************************************/
*[html-link-look="true"]
{
color: palette(link);
text-decoration: underline;
}
/*MainWindow*/
#mainwindow
{
background-color: #a7a7a7;
}
#mainwindow-menubar
{
background-image:url(images/transp.png);
border:none;
}
#mainwindow-menubar:item
{
color: black;
spacing: 5px;
padding: 2px 6px;
background: transparent;
}
#mainwindow-menubar::item:pressed
{
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #a5a5a5, stop:1 #9a9a9a);
border: 1px solid #373737;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom: none;
}
#mainwindow-statusbar
{
background-color: #a7a7a7;
}
#statusbar-ip-label
{
padding-right: 5px;
}
/*NavigationBar*/
#navigationbar
{
qproperty-layoutMargin: 4;
qproperty-layoutSpacing: 3;
}
#navigationbar QSplitter::handle
{
height: 8px;
image: url(images/splitter.png);
}
#navigation-button-back
{
qproperty-multiIcon: url(images/navigation-back.png);
}
#navigation-button-next
{
qproperty-multiIcon: url(images/navigation-forward.png);
}
#navigation-button-stop
{
qproperty-multiIcon: url(images/navigation-stop.png);
}
#navigation-button-reload
{
qproperty-multiIcon: url(images/navigation-reload.png);
}
#navigation-button-home
{
qproperty-multiIcon: url(images/navigation-home.png);
}
#navigation-button-addtab
{
qproperty-multiIcon: url(images/navigation-addtab.png);
}
#navigation-button-tools
{
qproperty-icon: url(images/navigation-tools.png);
}
+#navigation-button-exitfullscreen
+{
+ qproperty-icon: url(images/navigation-exit-fullscreen.png);
+}
+
#navigation-button-supermenu
{
qproperty-multiIcon: url(images/navigation-supermenu.png);
}
#navigation-toolbutton-badge
{
background: palette(dark);
color: palette(bright-text);
margin: 0px 1px;
}
ToolButton[toolbar-look="true"]
{
qproperty-iconSize: 16px 16px;
qproperty-fixedsize: 36px 23px;
border-image: url(images/toolbutton.png);
}
ToolButton[toolbar-look="true"]:hover
{
border-image: url(images/toolbutton-h.png);
}
ToolButton[toolbar-look="true"]:pressed
{
border-image: url(images/toolbutton-a.png);
}
/*TabWidget*/
#tabbar
{
qproperty-tabPadding: -1;
qproperty-baseColor: 0;
}
#tabbar-button-right
{
qproperty-icon: url(images/tab-right-arrow.png);
qproperty-fixedsize: 15px 25px;
}
#tabbar-button-left
{
qproperty-icon: url(images/tab-left-arrow.png);
qproperty-fixedsize: 15px 25px;
}
#tabwidget-button-opentabs
{
qproperty-multiIcon: url(images/tabs-list-button.png);
}
#tabwidget-button-closedtabs
{
qproperty-multiIcon: url(images/tabs-closed-button.png);
}
#tabwidget-button-addtab
{
qproperty-multiIcon: url(images/tabbar-addtab.png);
}
/*IconProvider*/
IconProvider
{
qproperty-bookmarkIcon: url(images/star-a.png);
}
/*LocationBar*/
#locationbar
{
background: transparent;
border-image: url(images/lineedit-bg.png);
border-width: 4px;
color:black;
padding-right: -5px;
padding-left: -5px;
padding-top: -2px;
padding-bottom: -2px;
qproperty-fixedheight: 23;
qproperty-leftMargin: 40;
}
#locationbar-bookmarkicon
{
margin-left: 2px;
qproperty-pixmap: url(images/star.png);
}
#locationbar-bookmarkicon[bookmarked="true"]
{
qproperty-pixmap: url(images/star-a.png);
}
#locationbar-siteicon
{
border-image: url(images/siteicon-bg.png);
qproperty-fixedsize:42px 23px;
padding-left: -3px;
}
#locationbar-siteicon[secured="true"]
{
border-image: url(images/siteicon-secure-bg.png);
}
#locationbar-goicon
{
margin-top: 2px;
qproperty-pixmap: url(images/gotoaddress.png);
}
#locationbar-down-icon
{
margin-left: 3px;
margin-right: 2px;
qproperty-pixmap: url(images/navigation-dropdown.png);
}
#locationbar-autofillicon
{
margin-bottom: 1px;
qproperty-pixmap: url(images/key.png);
}
/*BookmarksToolbar*/
#bookmarksbar QToolButton
{
border-image: url(images/transp.png);
border-width: 0px;
height: 15px;
}
/*SideBar*/
#sidebar
{
background: transparent;
}
#sidebar-splitter::handle
{
background-color:transparent;
}
/*WebSearchBar*/
#websearchbar
{
background: transparent;
border-image: url(images/lineedit-bg.png);
border-width: 4px;
padding-right: -4px;
padding-top: -2px;
padding-bottom: -2px;
color:black;
qproperty-fixedheight: 23;
qproperty-leftMargin: 35;
}
#websearchbar-searchbutton
{
margin-bottom: -1px;
qproperty-pixmap: url(images/search-icon.png);
}
#websearchbar-searchprovider-comobobox
{
border-image: url(images/searchbar-provider-bg.png);
padding-left:-11px;
qproperty-fixedsize: 42px 23px;
}
/*SourceViewer*/
#sourceviewer-textedit
{
border:none;
}
/*SourceViewerSearch*/
SourceViewerSearch #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*SearchToolbar*/
SearchToolBar #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*AboutDialog*/
AboutDialog #label
{
background:white;
}
AboutDialog #textBrowser
{
border:none;
margin-top: -2px; /* Workarounding rounded border on KDE */
}
/*DesktopNotification*/
DesktopNotification
{
background: transparent;
}
DesktopNotification #frame
{
border: 2px solid darkblue;
border-radius: 20px;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e4ecf1, stop:1 #d3e5f1);
}
DesktopNotification #heading
{
font: bold;
font-size: 13pt;
}
/*BrowsingLibrary*/
BrowsingLibrary #tabs
{
qproperty-bgPixmap: url(images/library-bg.png);
}
BrowsingLibrary #frame
{
background: url(images/library-bg.png);
}
/*Downloads*/
DownloadItem #fileName
{
font-size: 13pt;
}
DownloadManager #list
{
border: none;
}
/*JavaScript Dialogs*/
#jsFrame
{
background: url(images/semi-transp.png);
}
QFrame[js-frame="true"]
{
border: 1px solid black;
border-bottom: 0px;
background-color: white;
}
QFrame[js-frame2="true"]
{
border: 1px solid black;
border-top: 0px;
background-color: #f3f3f3;
}
diff --git a/themes/windows/main.css b/themes/windows/main.css
index 06d687cd..81fd4c45 100644
--- a/themes/windows/main.css
+++ b/themes/windows/main.css
@@ -1,435 +1,441 @@
/*************************************
* Windows Theme *
* Author: nowrep *
* Based on: Firefox Strata Aero *
*************************************/
*[html-link-look="true"]
{
color: palette(link);
text-decoration: underline;
}
/*MainWindow*/
#mainwindow
{
background : #ffffff;
}
#statusbar-ip-label
{
padding-right: 5px;
}
/*NavigationBar*/
#navigationbar
{
qproperty-layoutMargin: 3;
qproperty-layoutSpacing: 3;
}
#navigationbar QSplitter::handle
{
background-color:transparent;
}
#navigationbar QSplitter
{
min-width: 8px;
}
#navigation-button-back
{
qproperty-themeIcon: "go-previous";
}
#navigation-button-next
{
qproperty-themeIcon: "go-next";
}
#navigation-button-stop
{
qproperty-themeIcon: "process-stop";
}
#navigation-button-reload
{
qproperty-themeIcon: "view-refresh";
}
#navigation-button-home
{
qproperty-themeIcon: "go-home";
}
#navigation-button-addtab
{
qproperty-themeIcon: "list-add";
}
#navigation-button-tools
{
qproperty-themeIcon: "arrow-right-double";
qproperty-fallbackIcon: url(images/tools.svg);
}
+#navigation-button-exitfullscreen
+{
+ qproperty-themeIcon: "view-restore";
+ qproperty-fallbackIcon: url(images/exit-fullscreen.svg);
+}
+
#navigation-button-supermenu
{
qproperty-themeIcon: "application-menu";
qproperty-fallbackIcon: url(images/menu.svg);
}
#navigation-toolbutton-badge
{
background: palette(dark);
color: palette(bright-text);
margin: 0px 1px;
}
/*TabWidget*/
#tabbar-button-right
{
qproperty-themeIcon: "arrow-right";
qproperty-fallbackIcon: url(images/tab-right-arrow.svg);
qproperty-fixedsize: 15px 25px;
}
#tabbar-button-left
{
qproperty-themeIcon: "arrow-left";
qproperty-fallbackIcon: url(images/tab-left-arrow.svg);
qproperty-fixedsize: 15px 25px;
}
#tabwidget-button-opentabs
{
qproperty-themeIcon: "go-down";
qproperty-fixedsize: 22px 29px;
}
#tabwidget-button-closedtabs
{
qproperty-themeIcon: "user-trash-full";
qproperty-fixedsize: 22px 29px;
}
#tabwidget-button-addtab[outside-tabbar="false"]
{
background : #dddddd;
border: 1px solid #b2b2b2;
border-bottom: none;
border-left: none;
qproperty-fixedsize: 29px 29px;
qproperty-themeIcon: "list-add";
}
#tabwidget-button-addtab[outside-tabbar="true"]
{
qproperty-themeIcon: "list-add";
qproperty-fixedsize: 22px 29px;
}
#tabbar
{
min-height: 30px;
max-height: 30px;
qproperty-tabPadding: 3;
qproperty-baseColor: transparent;
}
#tab-icon
{
padding-right: 3px;
padding-left: 3px;
min-width: 16px;
max-width: 16px;
}
#combotabbar_tabs_close_button
{
max-width: 11px;
max-height: 9px;
min-width: 11px;
min-height: 9px;
padding-right: 2px;
}
#tabbar::close-button
{
image: url(images/tab-close.svg);
}
#tabbar::close-button:hover
{
image: url(images/tab-close-h.svg);
}
#tabbar::close-button:pressed
{
image: url(images/tab-close-a.svg);
}
#tabbar::tab
{
height: 28px;
}
#tabbar::tab:selected
{
background : #ffffff;
border: 1px solid #b2b2b2;
border-bottom: none;
}
#tabbar::tab:!selected
{
background : #dddddd;
border: 1px solid #b2b2b2;
border-bottom: none;
}
#tabbar::tab:!selected:hover
{
background: #f3f3f3;
border: 1px solid #b2b2b2;
border-bottom: none;
}
#tabbar::tab:selected:!first
{
margin-left: -1px;
}
#tabbar::tab:!selected:!first
{
margin-left: -1px;
}
#tabbar::tab:!selected:!first:hover
{
margin-left: -1px;
}
#tabbar::tab:selected:first
{
margin-left: 0;
}
#tabbar::tab:!selected:first
{
margin-left: 0;
}
#tabbar::tab:selected:only-one
{
margin-left: 0;
}
#tabbar::tab:!selected:only-one
{
margin-left: 0;
}
#tabbar::tab:!selected:hover:only-one
{
margin-left: 0;
}
/*IconProvider*/
IconProvider
{
qproperty-bookmarkIcon: url(images/star-a.svg);
}
/*LocationBar*/
#locationbar
{
background: transparent;
border: 1px solid #b2b2b2;
min-height: 25px;
qproperty-leftMargin: 27;
}
#locationbar::focus
{
border-color: #0078d7;
}
#locationbar-bookmarkicon
{
qproperty-themeIcon: "rating-unrated";
qproperty-fallbackIcon: url(images/star.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-bookmarkicon[bookmarked="true"]
{
qproperty-themeIcon: "rating";
qproperty-fallbackIcon: url(images/star-a.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-siteicon
{
border-image: url(images/transp.png);
qproperty-fixedwidth: 30;
min-height: 25px;
padding-left: 0px;
}
#locationbar-goicon
{
qproperty-themeIcon: "go-jump-locationbar";
qproperty-fallbackIcon: url(images/goto.svg);
qproperty-fixedsize: 16px 16px;
}
#locationbar-down-icon
{
qproperty-themeIcon: "go-down";
qproperty-fixedsize: 12px 16px;
}
#locationbar-autofillicon
{
qproperty-themeIcon: "user-identity";
qproperty-fallbackIcon: url(images/user.svg);
qproperty-fixedsize: 16px 16px;
}
/*BookmarksToolbar*/
#bookmarksbar QToolButton
{
border-image: url(images/transp.png);
border-width: 0px;
height: 15px;
}
/*SideBar*/
#sidebar
{
background: transparent;
}
#sidebar-splitter::handle
{
background-color:transparent;
}
/*WebSearchBar*/
#websearchbar
{
background: transparent;
border: 1px solid #b2b2b2 solid;
qproperty-leftMargin: 27;
}
#websearchbar::focus
{
border-color: #0078d7;
}
#websearchbar-searchbutton
{
qproperty-fixedsize: 22px 16px;
qproperty-themeIcon: "edit-find";
}
#websearchbar-searchprovider-comobobox
{
border-image: url(images/transp.png);
qproperty-fixedwidth: 25;
min-height: 25px;
padding-left: 4px;
}
/*SourceViewer*/
#sourceviewer-textedit
{
border:none;
}
/*SourceViewerSearch*/
SourceViewerSearch #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*SearchToolbar*/
SearchToolBar #lineEdit[notfound="true"]
{
background:#ff6666;
}
/*AboutDialog*/
AboutDialog #label
{
background:white;
}
AboutDialog #textBrowser
{
border:none;
}
/*DesktopNotification*/
DesktopNotification
{
background: transparent;
}
DesktopNotification #frame
{
border: 2px solid darkblue;
border-radius: 20px;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e4ecf1, stop:1 #d3e5f1);
}
DesktopNotification #heading
{
font: bold;
font-size: 13pt;
}
/*BrowsingLibrary*/
BrowsingLibrary #tabs
{
qproperty-bgPixmap: url(images/library-bg.png);
}
BrowsingLibrary #frame
{
background: url(images/library-bg.png);
}
/*Downloads*/
DownloadItem #fileName
{
font-size: 13pt;
}
DownloadManager #list
{
border: none;
}
/*JavaScript Dialogs*/
#jsFrame
{
background: url(images/semi-transp.png);
}
QFrame[js-frame="true"]
{
border: 1px solid black;
border-bottom: 0px;
background-color: white;
}
QFrame[js-frame2="true"]
{
border: 1px solid black;
border-top: 0px;
background-color: #f3f3f3;
}