Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
include(${CMAKE_SOURCE_DIR}/NEXTCLOUD.cmake)

set(QT_VERSION_MAJOR "6")
set(REQUIRED_QT_VERSION "6.8.0")
set(REQUIRED_QT_VERSION "6.10.0")

# CfAPI Shell Extensions
set( CFAPI_SHELL_EXTENSIONS_LIB_NAME CfApiShellExtensions )
Expand Down
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ IF( APPLE )
list(APPEND client_SRCS foregroundbackground_mac.mm)
list(APPEND client_SRCS foregroundbackground_cocoa.mm)

list(APPEND client_SRCS nativetitlebar_mac.h)
list(APPEND client_SRCS nativetitlebar_mac.mm)

if(SPARKLE_FOUND AND BUILD_UPDATER)
# Define this, we need to check in updater.cpp
add_definitions(-DHAVE_SPARKLE)
Expand Down
8 changes: 0 additions & 8 deletions src/gui/folderwatcher_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,6 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
}
}

#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
// The prefix is needed for native Windows functions before Windows 10, version 1607
const bool hasLongPathPrefix = longPath.startsWith(QStringLiteral("\\\\?\\"));
if (hasLongPathPrefix)
{
longfile.remove(0, 4);
}
#endif
longfile = QDir::cleanPath(longfile);

// Skip modifications of folders: One of these is triggered for changes
Expand Down
31 changes: 31 additions & 0 deletions src/gui/nativetitlebar_mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef NATIVETITLEBAR_MAC_H
#define NATIVETITLEBAR_MAC_H

class QWindow;

Check warning on line 9 in src/gui/nativetitlebar_mac.h

View workflow job for this annotation

GitHub Actions / build

src/gui/nativetitlebar_mac.h:9:7 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'QWindow' is non-const and globally accessible, consider making it const

Check failure on line 9 in src/gui/nativetitlebar_mac.h

View workflow job for this annotation

GitHub Actions / build

src/gui/nativetitlebar_mac.h:9:1 [clang-diagnostic-error]

unknown type name 'class'

namespace OCC {

Check failure on line 11 in src/gui/nativetitlebar_mac.h

View workflow job for this annotation

GitHub Actions / build

src/gui/nativetitlebar_mac.h:11:14 [clang-diagnostic-error]

expected ';' after top level declarator

Check warning on line 11 in src/gui/nativetitlebar_mac.h

View workflow job for this annotation

GitHub Actions / build

src/gui/nativetitlebar_mac.h:11:11 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'OCC' is non-const and globally accessible, consider making it const

Check failure on line 11 in src/gui/nativetitlebar_mac.h

View workflow job for this annotation

GitHub Actions / build

src/gui/nativetitlebar_mac.h:11:1 [clang-diagnostic-error]

unknown type name 'namespace'

/**
* @brief Style a window's native macOS title bar so it blends into the window content.
*
* Keeps the native (draggable) title bar but makes its background transparent and removes the
* separator hairline. For QQuickWindows the NSWindow background is matched to the window's colour
* (in the display's colour space) so the colour flows seamlessly through the title bar.
*
* Safe to call repeatedly — e.g. from a colorChanged signal or a changeEvent — so it survives macOS
* light/dark switches, which otherwise reset the styling.
*
* @param window the top-level window to style (a QQuickWindow, or a QWidget's windowHandle()).
* @param hideTitleText true to hide the title text (account wizard); false to keep it (settings).
* @ingroup gui
*/
void styleNativeTitleBar(QWindow *window, bool hideTitleText);

}

#endif
59 changes: 59 additions & 0 deletions src/gui/nativetitlebar_mac.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "nativetitlebar_mac.h"

#include <QColor>
#include <QQuickWindow>
#include <QWindow>

#import <AppKit/AppKit.h>

namespace OCC {

void styleNativeTitleBar(QWindow *window, bool hideTitleText)
{
if (!window) {
return;
}

const auto viewId = window->winId();
if (!viewId) {
return;
}

auto *const view = reinterpret_cast<NSView *>(viewId);
NSWindow *const nsWindow = view.window;
if (!nsWindow) {
return;
}

// Keep the native (draggable) title bar, but let it blend into the window: transparent
// background and no separator hairline. The content stays below the title bar (no full-size
// content view), so macOS keeps handling window dragging itself.
nsWindow.titlebarAppearsTransparent = YES;
nsWindow.titleVisibility = hideTitleText ? NSWindowTitleHidden : NSWindowTitleVisible;
nsWindow.titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone;

// Only a QQuickWindow exposes a flat fill colour we must mirror; widget windows already carry a
// matching NSWindow background. Interpret it in the display's colour space rather than sRGB:
// Qt composites the content without colour management, so an sRGB NSColor would be re-mapped
// through the display profile and drift from the body on wide-gamut screens.
if (auto *const quickWindow = qobject_cast<QQuickWindow *>(window)) {
const QColor color = quickWindow->color();
if (color.isValid()) {
NSColorSpace *const colorSpace = nsWindow.screen.colorSpace ?: NSColorSpace.sRGBColorSpace;
const CGFloat components[] = {
static_cast<CGFloat>(color.redF()),
static_cast<CGFloat>(color.greenF()),
static_cast<CGFloat>(color.blueF()),
static_cast<CGFloat>(color.alphaF()),
};
nsWindow.backgroundColor = [NSColor colorWithColorSpace:colorSpace components:components count:4];
}
}
}

}
17 changes: 12 additions & 5 deletions src/gui/owncloudsetupwizard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#ifdef Q_OS_MACOS
#include "foregroundbackground_interface.h"
#include "nativetitlebar_mac.h"
#endif

#include <QDialog>
Expand All @@ -38,9 +39,9 @@
}
}

static QPointer<OwncloudSetupWizard> owncloudSetupWizard = nullptr;

Check failure on line 42 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Global variables should be const.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_y&open=AZ7Kr502YFbcxnpqDP_y&pullRequest=10188

void OwncloudSetupWizard::runWizard(QObject *obj, const char *amember, QWidget *parent, bool forceRestart)

Check warning on line 44 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "obj" of type "class QObject *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_0&open=AZ7Kr502YFbcxnpqDP_0&pullRequest=10188

Check warning on line 44 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make the type of this parameter a pointer-to-const. The current type of "obj" is "class QObject *".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_z&open=AZ7Kr502YFbcxnpqDP_z&pullRequest=10188

Check warning on line 44 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "forceRestart" of type "_Bool" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_3&open=AZ7Kr502YFbcxnpqDP_3&pullRequest=10188

Check warning on line 44 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "parent" of type "class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_2&open=AZ7Kr502YFbcxnpqDP_2&pullRequest=10188

Check warning on line 44 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "amember" of type "const char *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_1&open=AZ7Kr502YFbcxnpqDP_1&pullRequest=10188
{
if (!owncloudSetupWizard.isNull()) {
if (forceRestart) {
Expand Down Expand Up @@ -90,7 +91,7 @@

bool OwncloudSetupWizard::startQmlWizard()
{
auto *engine = Systray::instance()->trayEngine();

Check warning on line 94 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "engine" of type "class QQmlApplicationEngine *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_4&open=AZ7Kr502YFbcxnpqDP_4&pullRequest=10188
if (!engine) {
qCWarning(lcWizard) << "Cannot start QML account wizard without a QML engine.";
return false;
Expand All @@ -100,7 +101,7 @@
QQmlComponent component(engine, QStringLiteral("qrc:/qml/src/gui/wizard/qml/AccountWizardWindow.qml"));
QVariantMap initialProperties;
initialProperties.insert(QStringLiteral("controller"), QVariant::fromValue<QObject *>(_qmlController));
auto *createdObject = component.createWithInitialProperties(initialProperties);

Check warning on line 104 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "createdObject" of type "class QObject *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_5&open=AZ7Kr502YFbcxnpqDP_5&pullRequest=10188

if (component.isError()) {
qCWarning(lcWizard) << "Failed to load QML account wizard:" << component.errors();
Expand All @@ -123,13 +124,8 @@
_qmlWizardWindow->installEventFilter(fgbg);
#endif

#if defined(Q_OS_MACOS) && QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
_qmlWizardWindow->setFlag(Qt::ExpandedClientAreaHint, true);
_qmlWizardWindow->setFlag(Qt::NoTitleBarBackgroundHint, true);
#endif

connect(_qmlController, &AccountWizardController::finished, this, &OwncloudSetupWizard::finish);
connect(_qmlWizardWindow, &QQuickWindow::visibleChanged, this, [this](bool visible) {

Check warning on line 128 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "visible" of type "_Bool" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_6&open=AZ7Kr502YFbcxnpqDP_6&pullRequest=10188
if (!visible) {
finish(QDialog::Rejected);
}
Expand All @@ -141,10 +137,21 @@
_qmlWizardWindow->show();
_qmlWizardWindow->raise();
_qmlWizardWindow->requestActivate();

#ifdef Q_OS_MACOS
styleNativeTitleBar(_qmlWizardWindow, /*hideTitleText=*/true);
// Re-apply when the window colour changes (e.g. the macOS light/dark switch) so the title bar
// keeps matching the body. Updating it in the same synchronous step lets the system appearance
// cross-fade animate the title bar together with the window content.
connect(_qmlWizardWindow, &QQuickWindow::colorChanged, this, [this] {
styleNativeTitleBar(_qmlWizardWindow, /*hideTitleText=*/true);
});
#endif

return true;
}

void OwncloudSetupWizard::finish(int result)

Check warning on line 154 in src/gui/owncloudsetupwizard.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "result" of type "int" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr502YFbcxnpqDP_7&open=AZ7Kr502YFbcxnpqDP_7&pullRequest=10188
{
if (_finished) {
return;
Expand Down
88 changes: 40 additions & 48 deletions src/gui/settingsdialog.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2013 ownCloud GmbH
Expand Down Expand Up @@ -33,6 +33,7 @@
#include <QPainter>
#include <QPainterPath>
#include <QPaintEvent>
#include <QShowEvent>
#include <QPalette>
#include <QQuickView>
#include <QActionGroup>
Expand All @@ -45,6 +46,12 @@
#include <QMouseEvent>
#include <QWindow>
#include <QtGlobal>
#include <QScreen>
#include <QGuiApplication>

#ifdef Q_OS_MACOS
#include "nativetitlebar_mac.h"
#endif

using namespace Qt::StringLiterals;

Expand All @@ -53,7 +60,7 @@
#define BACKGROUND_PALETTE "alternate-base"
#else
// ...and "alternate-base" looks too bright on macOS only. On Linux/Plasma either one looked fine ...
#define BACKGROUND_PALETTE "light"

Check failure on line 63 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this macro by "const", "constexpr" or an "enum".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_G&open=AZ7Kr5w_YFbcxnpqDP_G&pullRequest=10188
#endif

namespace {
Expand All @@ -64,7 +71,7 @@

[[nodiscard]] QSize sizeHint() const override
{
if (const auto *widget = currentWidget()) {

Check warning on line 74 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "widget" of type "const class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_K&open=AZ7Kr5w_YFbcxnpqDP_K&pullRequest=10188
return widget->sizeHint();
}
return QStackedWidget::sizeHint();
Expand All @@ -72,7 +79,7 @@

[[nodiscard]] QSize minimumSizeHint() const override
{
if (const auto *widget = currentWidget()) {

Check warning on line 82 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "widget" of type "const class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_L&open=AZ7Kr5w_YFbcxnpqDP_L&pullRequest=10188
return widget->minimumSizeHint();
}
return QStackedWidget::minimumSizeHint();
Expand All @@ -80,15 +87,15 @@

[[nodiscard]] bool hasHeightForWidth() const override
{
if (const auto *widget = currentWidget()) {

Check warning on line 90 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "widget" of type "const class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_M&open=AZ7Kr5w_YFbcxnpqDP_M&pullRequest=10188
return widget->hasHeightForWidth();
}
return QStackedWidget::hasHeightForWidth();
}

[[nodiscard]] int heightForWidth(int width) const override

Check warning on line 96 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "width" of type "int" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_N&open=AZ7Kr5w_YFbcxnpqDP_N&pullRequest=10188
{
if (const auto *widget = currentWidget()) {

Check warning on line 98 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "widget" of type "const class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_O&open=AZ7Kr5w_YFbcxnpqDP_O&pullRequest=10188
return widget->hasHeightForWidth() ? widget->heightForWidth(width) : widget->sizeHint().height();
}
return QStackedWidget::heightForWidth(width);
Expand All @@ -103,10 +110,10 @@
"QToolBar QToolButton:checked { background: palette(highlight); color: palette(highlighted-text); }"
);

const float buttonSizeRatio = 1.618f; // golden ratio

Check warning on line 113 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace constant with "std::numbers::phi_v<float>".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_P&open=AZ7Kr5w_YFbcxnpqDP_P&pullRequest=10188
constexpr auto settingsDialogDefaultWidth = 950;
constexpr auto settingsDialogDefaultHeight = 500;
const auto settingsNavigationIconTextSpacing = QLatin1String(" ");

Check warning on line 116 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_Q&open=AZ7Kr5w_YFbcxnpqDP_Q&pullRequest=10188

/** display name with two lines that is displayed in the settings
* If width is bigger than 0, the string will be ellided so it does not exceed that width
Expand All @@ -133,35 +140,10 @@

namespace OCC {

class WindowDragHandle : public QWidget
{
public:
using QWidget::QWidget;

protected:
void mousePressEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton) {
if (const auto *window = this->window(); window && window->windowHandle()) {
window->windowHandle()->startSystemMove();
event->accept();
return;
}
}

QWidget::mousePressEvent(event);
}
};

SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
: QDialog(parent)
, _gui(gui)
{
#if defined(Q_OS_MACOS) && QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
setWindowFlag(Qt::ExpandedClientAreaHint, true);
setWindowFlag(Qt::NoTitleBarBackgroundHint, true);
#endif

ConfigFile cfg;

setupUi();
Expand Down Expand Up @@ -194,7 +176,7 @@
accountAdded(account.data());
}

auto *accountSpacer = new QWidget(this);

Check warning on line 179 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "accountSpacer" of type "class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_T&open=AZ7Kr5w_YFbcxnpqDP_T&pullRequest=10188
accountSpacer->setFixedHeight(16);
_firstNonAccountAction = _toolBar->addWidget(accountSpacer);

Expand All @@ -218,12 +200,23 @@

customizeStyle();

setWindowFlag(Qt::WindowContextHelpButtonHint, false);
setWindowFlag(Qt::Window, true);
// Close + minimize, but no zoom/full-screen button (full screen makes no sense for Settings).
setWindowFlags(Qt::Window
| Qt::CustomizeWindowHint
| Qt::WindowTitleHint
| Qt::WindowSystemMenuHint
| Qt::WindowMinimizeButtonHint
| Qt::WindowCloseButtonHint);

// Open centered on screen by default; restoreGeometry() overrides this when a position was saved.
adjustSize();
if (const auto *const targetScreen = QGuiApplication::primaryScreen()) {
move(targetScreen->availableGeometry().center() - rect().center());
}
cfg.restoreGeometry(this);
}

SettingsDialog::~SettingsDialog()

Check failure on line 219 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use "=default" instead of the default implementation of this special member functions.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_U&open=AZ7Kr5w_YFbcxnpqDP_U&pullRequest=10188
{
}

Expand All @@ -232,19 +225,6 @@
return _stack->currentWidget();
}

// close event is not being called here
void SettingsDialog::resizeEvent(QResizeEvent *event)
{
QDialog::resizeEvent(event);

#if defined(Q_OS_MACOS) && QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
if (_windowDragHandle) {
_windowDragHandle->setGeometry(0, 0, width(), _windowDragHandle->height());
_windowDragHandle->raise();
}
#endif
}

void SettingsDialog::reject()
{
ConfigFile cfg;
Expand All @@ -259,6 +239,20 @@
QDialog::accept();
}

void SettingsDialog::showEvent(QShowEvent *event)

Check warning on line 242 in src/gui/settingsdialog.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/settingsdialog.cpp:242:22 [readability-convert-member-functions-to-static]

method 'showEvent' can be made static

Check warning on line 242 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this method "showEvent" to simply inherit it.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7NCRjgfjrFKK81vIKF&open=AZ7NCRjgfjrFKK81vIKF&pullRequest=10188
{
QDialog::showEvent(event);

Check warning on line 244 in src/gui/settingsdialog.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/settingsdialog.cpp:244:24 [cppcoreguidelines-init-variables]

variable 'event' is not initialized

#ifdef Q_OS_MACOS
// Style the title bar once the native window actually exists. Doing it earlier (e.g. from the
// constructor via winId()) doesn't stick, because Qt recreates the NSWindow when the dialog is
// shown, resetting the title-bar separator to its default.
if (auto *const handle = windowHandle()) {
styleNativeTitleBar(handle, /*hideTitleText=*/false);
}
#endif
}

void SettingsDialog::changeEvent(QEvent *e)
{
switch (e->type()) {
Expand All @@ -269,6 +263,12 @@

// Notify the other widgets (Dark-/Light-Mode switching)
emit styleChanged();
#ifdef Q_OS_MACOS
// macOS resets title-bar styling across appearance changes; re-apply it.
if (auto *const handle = windowHandle()) {
styleNativeTitleBar(handle, /*hideTitleText=*/false);
}
#endif
break;
case QEvent::ActivationChange:
if(isActiveWindow())
Expand All @@ -285,7 +285,7 @@
{
_stack->setCurrentWidget(_actionGroupWidgets.value(action));
_stack->updateGeometry();
if (auto *contentContainer = _stack->parentWidget()) {

Check warning on line 288 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "contentContainer" of type "class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_X&open=AZ7Kr5w_YFbcxnpqDP_X&pullRequest=10188
contentContainer->updateGeometry();
}
}
Expand All @@ -298,7 +298,7 @@
return;
}
const QList<QAction *> actions = _toolBar->actions();
for (auto *action : actions) {

Check warning on line 301 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "action" of type "class QAction *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_Y&open=AZ7Kr5w_YFbcxnpqDP_Y&pullRequest=10188
if (_actionGroupWidgets.contains(action)) {
action->trigger();
return;
Expand All @@ -306,14 +306,14 @@
}
}

void SettingsDialog::setInitialAccount(AccountState *account)

Check warning on line 309 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "account" of type "class OCC::AccountState *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_Z&open=AZ7Kr5w_YFbcxnpqDP_Z&pullRequest=10188
{
_initialAccount = account;
}

void SettingsDialog::showAccount(AccountState *account)

Check warning on line 314 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make the type of this parameter a pointer-to-const. The current type of "account" is "class OCC::AccountState *".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_b&open=AZ7Kr5w_YFbcxnpqDP_b&pullRequest=10188

Check warning on line 314 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function should be declared "const".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_a&open=AZ7Kr5w_YFbcxnpqDP_a&pullRequest=10188

Check warning on line 314 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "account" of type "class OCC::AccountState *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_c&open=AZ7Kr5w_YFbcxnpqDP_c&pullRequest=10188
{
auto *action = _actionForAccount.value(account->account().data());

Check warning on line 316 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "action" of type "class QAction *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_d&open=AZ7Kr5w_YFbcxnpqDP_d&pullRequest=10188
if (action) {
action->trigger();
}
Expand Down Expand Up @@ -450,9 +450,9 @@
}
}

void SettingsDialog::addSettingsPage(const QString &iconPath, const QString &title, QWidget *settingsPage, [[maybe_unused]] bool updateChannelAware)

Check warning on line 453 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "settingsPage" of type "class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_g&open=AZ7Kr5w_YFbcxnpqDP_g&pullRequest=10188

Check warning on line 453 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "updateChannelAware" of type "_Bool" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_h&open=AZ7Kr5w_YFbcxnpqDP_h&pullRequest=10188
{
auto *settingsAction = createColorAwareAction(iconPath, title);

Check warning on line 455 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "settingsAction" of type "class QAction *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_i&open=AZ7Kr5w_YFbcxnpqDP_i&pullRequest=10188
_actionGroup->addAction(settingsAction);
_toolBar->addAction(settingsAction);

Expand All @@ -461,11 +461,11 @@
settingsPage->setObjectName(objectName);
_stack->addWidget(settingsPage);

if (auto *generalSettingsPage = qobject_cast<GeneralSettings *>(settingsPage)) {

Check warning on line 464 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "generalSettingsPage" of type "class OCC::GeneralSettings *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_k&open=AZ7Kr5w_YFbcxnpqDP_k&pullRequest=10188
connect(this, &SettingsDialog::styleChanged, generalSettingsPage, &GeneralSettings::slotStyleChanged);
} else if (auto *advancedSettingsPage = qobject_cast<AdvancedSettings *>(settingsPage)) {

Check warning on line 466 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "advancedSettingsPage" of type "class OCC::AdvancedSettings *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_m&open=AZ7Kr5w_YFbcxnpqDP_m&pullRequest=10188

Check warning on line 466 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make the type of this variable a pointer-to-const. The current type of "advancedSettingsPage" is "class OCC::AdvancedSettings *".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_l&open=AZ7Kr5w_YFbcxnpqDP_l&pullRequest=10188
connect(this, &SettingsDialog::styleChanged, advancedSettingsPage, &AdvancedSettings::slotStyleChanged);
} else if (auto *infoSettingsPage = qobject_cast<InfoSettings *>(settingsPage)) {

Check warning on line 468 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make the type of this variable a pointer-to-const. The current type of "infoSettingsPage" is "class OCC::InfoSettings *".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_n&open=AZ7Kr5w_YFbcxnpqDP_n&pullRequest=10188

Check warning on line 468 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "infoSettingsPage" of type "class OCC::InfoSettings *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_o&open=AZ7Kr5w_YFbcxnpqDP_o&pullRequest=10188
connect(this, &SettingsDialog::styleChanged, infoSettingsPage, &InfoSettings::slotStyleChanged);

#if defined(BUILD_UPDATER)
Expand All @@ -486,7 +486,7 @@
return;
}

const QScopedValueRollback<bool> updatingStyle(_updatingStyle, true);

Check warning on line 489 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Avoid explicitly specifying the template arguments by relying on the class template argument deduction.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_p&open=AZ7Kr5w_YFbcxnpqDP_p&pullRequest=10188
_toolBar->setStyleSheet(TOOLBAR_CSS);

auto separatorColor = palette().color(QPalette::Mid);
Expand All @@ -500,14 +500,14 @@
setStyleSheet(QStringLiteral(
"#Settings { background: palette(window); border-radius: 0; }"

/* Navigation */

Check warning on line 503 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_H&open=AZ7Kr5w_YFbcxnpqDP_H&pullRequest=10188
"#settings_navigation_scroll { background: palette(" BACKGROUND_PALETTE "); border-radius: 12px; padding: 4px; }"
"#settings_navigation { background: transparent; border: none; padding: 0px; }"

/* Content area */

Check warning on line 507 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_I&open=AZ7Kr5w_YFbcxnpqDP_I&pullRequest=10188
"#settings_content, #settings_content_scroll { background: palette(window); border-radius: 12px; }"

/* Panels */

Check warning on line 510 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_J&open=AZ7Kr5w_YFbcxnpqDP_J&pullRequest=10188
"#generalGroupBox, #notificationsGroupBox, #advancedGroupBox, #syncBehaviorGroupBox,"
"#advancedActionsGroupBox, #aboutAndUpdatesGroupBox, #updatesGroupBox {"
" background: palette(" BACKGROUND_PALETTE ");"
Expand Down Expand Up @@ -581,7 +581,7 @@
using QToolButton::QToolButton;

protected:
void paintEvent(QPaintEvent *event) override

Check warning on line 584 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "event" of type "class QPaintEvent *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_q&open=AZ7Kr5w_YFbcxnpqDP_q&pullRequest=10188
{
Q_UNUSED(event)

Expand All @@ -593,7 +593,7 @@
}

private:
void initStyleOption(QStyleOptionToolButton *option) const override

Check warning on line 596 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "option" of type "class QStyleOptionToolButton *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_r&open=AZ7Kr5w_YFbcxnpqDP_r&pullRequest=10188
{
QToolButton::initStyleOption(option);
if (!option->text.isEmpty()) {
Expand All @@ -603,7 +603,7 @@
}
};

auto *btn = new SettingsNavigationButton(parent);

Check warning on line 606 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "btn" of type "class SettingsNavigationButton *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_s&open=AZ7Kr5w_YFbcxnpqDP_s&pullRequest=10188
QString objectName = QLatin1String("settingsdialog_toolbutton_");
objectName += text();
btn->setObjectName(objectName);
Expand Down Expand Up @@ -638,7 +638,7 @@
setGeometry(0, 0, settingsDialogDefaultWidth, settingsDialogDefaultHeight);
setMinimumSize(settingsDialogDefaultWidth, settingsDialogDefaultHeight);

auto *mainLayout = new QHBoxLayout(this);

Check warning on line 641 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "mainLayout" of type "class QHBoxLayout *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_t&open=AZ7Kr5w_YFbcxnpqDP_t&pullRequest=10188
mainLayout->setContentsMargins(12, 12, 12, 12);
mainLayout->setSpacing(12);
setLayout(mainLayout);
Expand All @@ -651,17 +651,17 @@
_toolBar->setMinimumWidth(220);
_toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

auto *navigationContainer = new QWidget(this);

Check warning on line 654 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "navigationContainer" of type "class QWidget *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_u&open=AZ7Kr5w_YFbcxnpqDP_u&pullRequest=10188
navigationContainer->setObjectName("settings_navigation"_L1);
navigationContainer->setAttribute(Qt::WA_StyledBackground);

auto *navigationLayout = new QVBoxLayout(navigationContainer);

Check warning on line 658 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "navigationLayout" of type "class QVBoxLayout *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_v&open=AZ7Kr5w_YFbcxnpqDP_v&pullRequest=10188
navigationLayout->setContentsMargins(0, 0, 0, 0);
navigationLayout->setSpacing(0);
navigationLayout->addWidget(_toolBar);
navigationLayout->addStretch(1);

auto *navigationScroll = new QScrollArea(this);

Check warning on line 664 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "navigationScroll" of type "class QScrollArea *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_w&open=AZ7Kr5w_YFbcxnpqDP_w&pullRequest=10188
navigationScroll->setObjectName("settings_navigation_scroll"_L1);
navigationScroll->setWidgetResizable(true);
navigationScroll->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Expand All @@ -674,7 +674,7 @@
_stack = new CurrentPageSizeStackedWidget(this);
_stack->setObjectName(u"settings_content"_s);

auto *contentScroll = new QScrollArea(this);

Check warning on line 677 in src/gui/settingsdialog.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "contentScroll" of type "class QScrollArea *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr5w_YFbcxnpqDP_x&open=AZ7Kr5w_YFbcxnpqDP_x&pullRequest=10188
contentScroll->setObjectName("settings_content_scroll"_L1);
contentScroll->setWidgetResizable(true);
contentScroll->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Expand All @@ -688,14 +688,6 @@
mainLayout->addWidget(contentScroll);
mainLayout->setStretch(0, 0);
mainLayout->setStretch(1, 1);

#if defined(Q_OS_MACOS) && QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
_windowDragHandle = new WindowDragHandle(this);
_windowDragHandle->setObjectName(QLatin1String("settings_window_drag_handle"));
_windowDragHandle->setFixedHeight(28);
_windowDragHandle->setGeometry(0, 0, width(), _windowDragHandle->height());
_windowDragHandle->raise();
#endif
}

} // namespace OCC
6 changes: 1 addition & 5 deletions src/gui/settingsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H

#include <QDialog>

Check failure on line 10 in src/gui/settingsdialog.h

View workflow job for this annotation

GitHub Actions / build

src/gui/settingsdialog.h:10:10 [clang-diagnostic-error]

'QDialog' file not found
#include <QStyledItemDelegate>

#include "progressdispatcher.h"
Expand Down Expand Up @@ -61,7 +61,7 @@
void reject() override;
void accept() override;
void changeEvent(QEvent *) override;
void resizeEvent(QResizeEvent *event) override;
void showEvent(QShowEvent *event) override;

private slots:
void accountAdded(OCC::AccountState *);
Expand All @@ -88,10 +88,6 @@
QStackedWidget *_stack = nullptr;
QAction *_firstNonAccountAction = nullptr;

#if defined(Q_OS_MACOS) && QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
QWidget *_windowDragHandle = nullptr;
#endif

ownCloudGui *_gui;
bool _styleUpdatePending = false;
bool _updatingStyle = false;
Expand Down
8 changes: 6 additions & 2 deletions src/gui/wizard/qml/AccountWizardWindow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ ApplicationWindow {
LayoutMirroring.enabled: Application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true

width: 500
width: 600
height: compactHeight
minimumWidth: 480
minimumWidth: 600
minimumHeight: compactHeight
title: ""
// Explicit decoration set so macOS disables the green zoom/full-screen button (no maximize or
// full-screen hint) — full screen makes no sense for this window — while keeping a normal,
// draggable native title bar with close and minimize.
flags: Qt.Window
| Qt.CustomizeWindowHint
| Qt.WindowTitleHint
| Qt.WindowSystemMenuHint
| Qt.WindowMinimizeButtonHint
| Qt.WindowCloseButtonHint
color: Style.wizardWindowBackground
palette.window: Style.wizardWindowBackground
Expand Down
1 change: 0 additions & 1 deletion src/gui/wizard/qml/ServerPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ Item {

WizardButton {
primary: true
Layout.preferredWidth: 76
enabled: !root.controller.busy
text: qsTr("Log in")
onClicked: root.controller.submitServerUrl()
Expand Down
3 changes: 0 additions & 3 deletions src/libsync/accessmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
enableStrictTransportSecurityStore(true);
setStrictTransportSecurityEnabled(true);

connect(this, &QNetworkAccessManager::authenticationRequired, this, [](QNetworkReply *reply, QAuthenticator *authenticator) {

Check warning on line 36 in src/libsync/accessmanager.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "authenticator" of type "class QAuthenticator *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr51xYFbcxnpqDP_-&open=AZ7Kr51xYFbcxnpqDP_-&pullRequest=10188

Check warning on line 36 in src/libsync/accessmanager.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "reply" of type "class QNetworkReply *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ7Kr51xYFbcxnpqDP_9&open=AZ7Kr51xYFbcxnpqDP_9&pullRequest=10188
Q_UNUSED(reply)

if (authenticator->user().isEmpty()) {
Expand Down Expand Up @@ -72,15 +72,12 @@
qInfo(lcAccessManager) << op << verb << newRequest.url().toString() << "has X-Request-ID" << requestId;
newRequest.setRawHeader("X-Request-ID", requestId);

#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 4)
// only enable HTTP2 with Qt 5.9.4 because old Qt have too many bugs (e.g. QTBUG-64359 is fixed in >= Qt 5.9.4)
if (newRequest.url().scheme() == "https") { // Not for "http": QTBUG-61397
// http2 seems to cause issues, as with our recommended server setup we don't support http2, disable it by default for now
static const bool http2EnabledEnv = qEnvironmentVariableIntValue("OWNCLOUD_HTTP2_ENABLED") == 1;

newRequest.setAttribute(QNetworkRequest::Http2AllowedAttribute, http2EnabledEnv);
}
#endif

if (!newRequest.attribute(QNetworkRequest::RedirectPolicyAttribute).isValid()) {
// We handle redirects ourselves in AbstractNetworkJob::slotFinished
Expand Down
Loading