Skip to content

Commit 7b151fa

Browse files
committed
up
1 parent eb723cc commit 7b151fa

8 files changed

Lines changed: 171 additions & 47 deletions

File tree

src/app/BrowserWindow.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969

7070
namespace {
7171

72+
QEasingCurve responsiveEaseOut() {
73+
QEasingCurve curve(QEasingCurve::BezierSpline);
74+
curve.addCubicBezierSegment(QPointF(0.23, 1.0), QPointF(0.32, 1.0), QPointF(1.0, 1.0));
75+
return curve;
76+
}
77+
7278
void setButtonSymbolSmooth(QToolButton *button, const QString &symbol, double pointSize, const QColor &color) {
7379
if (!button) return;
7480
const QString previousSymbol = button->property("sfSymbolName").toString();
@@ -90,17 +96,17 @@ void setButtonSymbolSmooth(QToolButton *button, const QString &symbol, double po
9096
button->setGraphicsEffect(effect);
9197
}
9298
auto *out = new QPropertyAnimation(effect, "opacity", button);
93-
out->setDuration(45);
99+
out->setDuration(55);
94100
out->setStartValue(effect->opacity());
95101
out->setEndValue(0.35);
96-
out->setEasingCurve(QEasingCurve::OutCubic);
102+
out->setEasingCurve(responsiveEaseOut());
97103
QObject::connect(out, &QPropertyAnimation::finished, button, [button, effect, applyIcon] {
98104
applyIcon();
99105
auto *in = new QPropertyAnimation(effect, "opacity", button);
100-
in->setDuration(45);
106+
in->setDuration(70);
101107
in->setStartValue(effect->opacity());
102108
in->setEndValue(1.0);
103-
in->setEasingCurve(QEasingCurve::OutCubic);
109+
in->setEasingCurve(responsiveEaseOut());
104110
QObject::connect(in, &QPropertyAnimation::finished, in, &QObject::deleteLater);
105111
in->start();
106112
});
@@ -527,7 +533,11 @@ void BrowserWindow::splitTabs(WebView *first, WebView *second, const QPoint &glo
527533
};
528534
syncPaneNav();
529535
connect(view, &WebView::navigationStateChanged, toolbar.bar, syncPaneNav);
530-
connect(toolbar.sidebar, &QToolButton::clicked, this, [this] { if (m_sidebar && m_sidebarWidget) m_sidebar->setHidden(m_sidebarWidget->isVisible()); });
536+
connect(toolbar.sidebar, &QToolButton::clicked, this, [this] {
537+
if (!m_sidebar || !m_sidebarWidget) return;
538+
if (m_sidebarWidget->isVisible()) m_sidebar->setHidden(true);
539+
else m_sidebar->expandAnimated();
540+
});
531541
connect(toolbar.back, &QToolButton::clicked, view, [viewGuard] { if (viewGuard) viewGuard->back(); });
532542
connect(toolbar.forward, &QToolButton::clicked, view, [viewGuard] { if (viewGuard) viewGuard->forward(); });
533543
connect(toolbar.reload, &QToolButton::clicked, view, [viewGuard] { if (viewGuard) { if (viewGuard->isLoading()) viewGuard->stop(); else viewGuard->reload(); } });
@@ -865,7 +875,11 @@ QWidget *BrowserWindow::buildTopbar(QWidget *parent) {
865875
if (auto *v = currentView()) v->setFocus();
866876
});
867877

868-
connect(m_sidebarBtn, &QToolButton::clicked, this, [this] { if (m_sidebar && m_sidebarWidget) m_sidebar->setHidden(m_sidebarWidget->isVisible()); });
878+
connect(m_sidebarBtn, &QToolButton::clicked, this, [this] {
879+
if (!m_sidebar || !m_sidebarWidget) return;
880+
if (m_sidebarWidget->isVisible()) m_sidebar->setHidden(true);
881+
else m_sidebar->expandAnimated();
882+
});
869883
connect(m_backBtn, &QToolButton::clicked, this, [this] { if (auto *v = currentView()) v->back(); });
870884
connect(m_fwdBtn, &QToolButton::clicked, this, [this] { if (auto *v = currentView()) v->forward(); });
871885
connect(m_reloadBtn, &QToolButton::clicked, this, [this] { if (auto *v = currentView()) { if (v->isLoading()) v->stop(); else v->reload(); } });
@@ -1022,8 +1036,8 @@ void BrowserWindow::settleSidebarSwipe(bool commit) {
10221036
m_sidebarSwipeAnim = driver;
10231037
driver->setStartValue(startOffset);
10241038
driver->setEndValue(commit ? (direction > 0 ? -width : width) : 0);
1025-
driver->setDuration(commit ? 160 : 120);
1026-
driver->setEasingCurve(QEasingCurve::OutCubic);
1039+
driver->setDuration(commit ? 150 : 105);
1040+
driver->setEasingCurve(responsiveEaseOut());
10271041
m_sidebarSwipeSettling = true;
10281042
connect(driver, &QVariantAnimation::valueChanged, this, [this](const QVariant &value) {
10291043
setSidebarSwipeOffset(value.toInt());
@@ -1056,10 +1070,10 @@ void BrowserWindow::animateProfileSwitcher(int direction) {
10561070
QRect start = end.translated(direction > 0 ? 18 : -18, 0);
10571071
m_profileBtn->setGeometry(start);
10581072
m_profileAnim = new QPropertyAnimation(m_profileBtn, "geometry", this);
1059-
m_profileAnim->setDuration(180);
1073+
m_profileAnim->setDuration(155);
10601074
m_profileAnim->setStartValue(start);
10611075
m_profileAnim->setEndValue(end);
1062-
m_profileAnim->setEasingCurve(QEasingCurve::OutCubic);
1076+
m_profileAnim->setEasingCurve(responsiveEaseOut());
10631077
QPropertyAnimation *anim = m_profileAnim;
10641078
connect(anim, &QPropertyAnimation::finished, anim, &QObject::deleteLater);
10651079
connect(anim, &QObject::destroyed, this, [this, anim] { if (m_profileAnim == anim) m_profileAnim = nullptr; });
@@ -1580,14 +1594,10 @@ void BrowserWindow::setupActions() {
15801594
auto *side = m_splitter->widget(0);
15811595
if (!side) return;
15821596
const bool nowVisible = !side->isVisible();
1583-
m_sidebar->setHidden(!nowVisible);
15841597
if (nowVisible) {
1585-
QTimer::singleShot(0, this, [this, side] {
1586-
const int saved = QSettings().value("ui/sidebarWidth", ui::metrics::SidebarDefaultWidth).toInt();
1587-
const int target = qBound(side->minimumWidth(), saved, side->maximumWidth());
1588-
const int total = m_splitter->size().width();
1589-
m_splitter->setSizes({target, qMax(0, total - target - m_splitter->handleWidth())});
1590-
});
1598+
m_sidebar->expandAnimated();
1599+
} else {
1600+
m_sidebar->setHidden(true);
15911601
}
15921602
};
15931603

src/mac/MacIntegration.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <QIcon>
44
#include <QPoint>
5+
#include <QRect>
56
#include <QString>
67
#include <QStringList>
78
#include <QVector>
@@ -98,6 +99,12 @@ void sendStandardEditAction(const char *selector);
9899

99100
void performHapticFeedback();
100101

102+
void animateWindowFrame(QWidget *window,
103+
const QRect &from,
104+
const QRect &to,
105+
int durationMs,
106+
std::function<void()> completion = {});
107+
101108
bool showNativePageActionsMenu(QWidget *anchor,
102109
std::function<void()> copyUrl,
103110
std::function<void()> reload,

src/mac/MacInternal.mm

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "MacIntegration.hpp"
2121
#import <AppKit/AppKit.h>
2222
#import <AppKit/NSGlassEffectView.h>
23+
#import <QuartzCore/QuartzCore.h>
2324
#import <objc/message.h>
2425
#import <objc/runtime.h>
2526

@@ -241,6 +242,14 @@ static bool pocbShowGlassMenu(NSWindow *owner,
241242

242243
namespace mac {
243244

245+
static NSRect pocbNSWindowFrameFromQRect(const QRect &rect, NSScreen *preferredScreen) {
246+
NSScreen *screen = preferredScreen ?: NSScreen.mainScreen;
247+
if (!screen) return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
248+
const NSRect screenFrame = screen.frame;
249+
const CGFloat y = NSMaxY(screenFrame) - rect.y() - rect.height();
250+
return NSMakeRect(rect.x(), y, rect.width(), rect.height());
251+
}
252+
244253
void performHapticFeedback() {
245254
[[NSHapticFeedbackManager defaultPerformer] performFeedbackPattern:NSHapticFeedbackPatternGeneric performanceTime:NSHapticFeedbackPerformanceTimeDefault];
246255
}
@@ -251,6 +260,35 @@ void sendStandardEditAction(const char *selector) {
251260
[NSApp sendAction:sel to:nil from:nil];
252261
}
253262

263+
void animateWindowFrame(QWidget *window,
264+
const QRect &from,
265+
const QRect &to,
266+
int durationMs,
267+
std::function<void()> completion) {
268+
if (!window) {
269+
if (completion) completion();
270+
return;
271+
}
272+
NSWindow *nsWindow = mac::internal::nsWindowOf(window);
273+
if (!nsWindow) {
274+
window->setGeometry(to);
275+
if (completion) completion();
276+
return;
277+
}
278+
NSScreen *screen = nsWindow.screen ?: NSScreen.mainScreen;
279+
[nsWindow setFrame:pocbNSWindowFrameFromQRect(from, screen) display:YES];
280+
auto *completionCopy = new std::function<void()>(std::move(completion));
281+
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
282+
context.duration = qMax(0, durationMs) / 1000.0;
283+
context.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
284+
[[nsWindow animator] setFrame:pocbNSWindowFrameFromQRect(to, screen) display:YES];
285+
} completionHandler:^{
286+
window->setGeometry(to);
287+
if (*completionCopy) (*completionCopy)();
288+
delete completionCopy;
289+
}];
290+
}
291+
254292
bool showNativeContextMenu(QWidget *anchor,
255293
const QPoint &globalPos,
256294
const QStringList &titles,
@@ -366,6 +404,15 @@ bool showNativePageActionsMenu(QWidget *anchor,
366404

367405
namespace mac {
368406

407+
void animateWindowFrame(QWidget *window,
408+
const QRect &,
409+
const QRect &to,
410+
int,
411+
std::function<void()> completion) {
412+
if (window) window->setGeometry(to);
413+
if (completion) completion();
414+
}
415+
369416
bool showNativePageActionsMenu(QWidget *,
370417
std::function<void()>,
371418
std::function<void()>,

src/tabs/TabTree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ TabTree::TabTree(ProfileStore &profiles, FaviconService *favicons, QWidget *stac
308308
m_tabs->setAllColumnsShowFocus(false);
309309
m_tabs->setSelectionMode(QAbstractItemView::NoSelection);
310310
m_tabs->setFocusPolicy(Qt::NoFocus);
311-
m_tabs->setAnimated(true);
311+
m_tabs->setAnimated(false);
312312
m_tabs->setFrameShape(QFrame::NoFrame);
313313
m_tabs->setIconSize(QSize(14, 14));
314314
m_tabs->setExpandsOnDoubleClick(false);

src/ui/ChromeWidgets.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ QColor lerp(const QColor &a, const QColor &b, qreal t) {
1818
a.blueF() + (b.blueF() - a.blueF()) * t,
1919
a.alphaF() + (b.alphaF() - a.alphaF()) * t);
2020
}
21+
22+
QEasingCurve responsiveEaseOut() {
23+
QEasingCurve curve(QEasingCurve::BezierSpline);
24+
curve.addCubicBezierSegment(QPointF(0.23, 1.0), QPointF(0.32, 1.0), QPointF(1.0, 1.0));
25+
return curve;
26+
}
2127
} // namespace
2228

2329
// ---- ChromeBar ----------------------------------------------------------
@@ -27,8 +33,8 @@ ChromeBar::ChromeBar(QWidget *parent)
2733
setAttribute(Qt::WA_StyledBackground, false);
2834
setAutoFillBackground(false);
2935
m_anim = new QVariantAnimation(this);
30-
m_anim->setDuration(220);
31-
m_anim->setEasingCurve(QEasingCurve::OutCubic);
36+
m_anim->setDuration(180);
37+
m_anim->setEasingCurve(responsiveEaseOut());
3238
connect(m_anim, &QVariantAnimation::valueChanged, this, [this](const QVariant &v) {
3339
m_bg = v.value<QColor>();
3440
update();
@@ -74,15 +80,15 @@ AddrPill::AddrPill(QWidget *parent) : QWidget(parent) {
7480
setAttribute(Qt::WA_StyledBackground, false);
7581
setAutoFillBackground(false);
7682
m_anim = new QVariantAnimation(this);
77-
m_anim->setDuration(140);
78-
m_anim->setEasingCurve(QEasingCurve::OutCubic);
83+
m_anim->setDuration(125);
84+
m_anim->setEasingCurve(responsiveEaseOut());
7985
connect(m_anim, &QVariantAnimation::valueChanged, this, [this](const QVariant &v) {
8086
m_progress = v.toDouble();
8187
update();
8288
});
8389
m_loadAnim = new QVariantAnimation(this);
84-
m_loadAnim->setDuration(130);
85-
m_loadAnim->setEasingCurve(QEasingCurve::OutCubic);
90+
m_loadAnim->setDuration(115);
91+
m_loadAnim->setEasingCurve(responsiveEaseOut());
8692
connect(m_loadAnim, &QVariantAnimation::valueChanged, this, [this](const QVariant &v) {
8793
m_loadCurrent = v.toDouble();
8894
update();
@@ -124,13 +130,13 @@ void AddrPill::setLoadProgress(int percent) {
124130
}
125131
if (percent >= 100) {
126132
m_loadAnim->setEndValue(100.0);
127-
m_loadAnim->setDuration(115);
133+
m_loadAnim->setDuration(90);
128134
} else {
129135
if (m_loadPulseAnim->state() != QAbstractAnimation::Running) m_loadPulseAnim->start();
130136
const qreal visualTarget = qMax((qreal)percent, 96.0);
131137
m_loadAnim->setEndValue(visualTarget);
132138
const int delta = qAbs(qRound(visualTarget - m_loadCurrent));
133-
m_loadAnim->setDuration(qBound(70, 28 + delta * 3, 145));
139+
m_loadAnim->setDuration(qBound(60, 24 + delta * 2, 120));
134140
}
135141
m_loadAnim->start();
136142
}

src/ui/LayoutMetrics.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ inline constexpr int StackHostRightInset = 6;
2929
inline constexpr int StackHostBottomInset = 6;
3030
inline constexpr int FloatingSidebarSideGap = 8;
3131
inline constexpr int FloatingSidebarBottomGap = 8;
32-
inline constexpr int FloatingDismissDelayMs = 180;
33-
inline constexpr int FloatingSlideDurationMs = 160;
32+
inline constexpr int FloatingDismissDelayMs = 240;
33+
inline constexpr int FloatingSlideInDurationMs = 190;
34+
inline constexpr int FloatingSlideOutDurationMs = 135;
35+
inline constexpr int FloatingSlideTravelPx = 28;
3436
inline constexpr int DockedSidebarTopInset = UnifiedToolbarHeight;
3537
inline constexpr int DockedSidebarLeftInset = 10;
3638
inline constexpr int DockedSidebarRightInset = 0;

0 commit comments

Comments
 (0)