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; }