plyght's own C++ browser for macOS
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix swipe gesture

plyght d101094f a5c96e74

+60 -30
+13 -8
src/app/BrowserWindow.cpp
··· 448 448 void BrowserWindow::setSidebarSwipeOffset(int offset) { 449 449 if (!m_sidebarPage || !m_sidebarViewport) return; 450 450 const int width = qMax(1, m_sidebarViewport->width()); 451 - const QRect bounds = m_sidebarViewport->rect(); 451 + const QRect bounds(QPoint(0, 0), m_sidebarViewport->size()); 452 + if (m_sidebarStrip) m_sidebarStrip->setGeometry(bounds); 453 + m_sidebarViewport->setMask(QRegion(bounds)); 452 454 m_sidebarSwipeOffset = qBound(-width, offset, width); 453 455 m_sidebarPage->setGeometry(bounds.translated(m_sidebarSwipeOffset, 0)); 454 456 if (m_sidebarPreviewPage) { ··· 662 664 m_sidebarViewport = new QWidget(sidebar); 663 665 m_sidebarViewport->setObjectName("SidebarViewport"); 664 666 m_sidebarViewport->setAttribute(Qt::WA_TranslucentBackground); 665 - m_sidebarViewport->setAttribute(Qt::WA_NativeWindow, false); 666 667 m_sidebarViewport->setStyleSheet("QWidget#SidebarViewport { background: transparent; }"); 667 668 m_sidebarViewport->installEventFilter(this); 669 + m_sidebarStrip = new QWidget(m_sidebarViewport); 670 + m_sidebarStrip->setObjectName("SidebarStrip"); 671 + m_sidebarStrip->setAttribute(Qt::WA_TranslucentBackground); 672 + m_sidebarStrip->setStyleSheet("QWidget#SidebarStrip { background: transparent; }"); 668 673 669 - m_sidebarPage = new QWidget(m_sidebarViewport); 674 + m_sidebarPage = new QWidget(m_sidebarStrip); 670 675 m_sidebarPage->setObjectName("SidebarPage"); 671 676 m_sidebarPage->setAttribute(Qt::WA_TranslucentBackground); 672 677 m_sidebarPage->setStyleSheet("QWidget#SidebarPage { background: transparent; }"); ··· 682 687 m_profileSwitcher = buildProfileSwitcher(m_sidebarPage); 683 688 pageLayout->addWidget(m_profileSwitcher, 0, Qt::AlignLeft | Qt::AlignBottom); 684 689 sideLayout->addWidget(m_sidebarViewport, 1); 685 - m_sidebarPreviewPage = new QWidget(m_sidebarViewport); 690 + m_sidebarPreviewPage = new QWidget(m_sidebarStrip); 686 691 m_sidebarPreviewPage->setObjectName("SidebarPreviewPage"); 687 692 m_sidebarPreviewPage->setAttribute(Qt::WA_TranslucentBackground); 688 693 m_sidebarPreviewPage->setStyleSheet("QWidget#SidebarPreviewPage { background: transparent; }"); ··· 715 720 m_sidebarPreviewIcon->setStyleSheet("QToolButton { background: transparent; border: none; }"); 716 721 previewLayout->addWidget(m_sidebarPreviewIcon, 0, Qt::AlignLeft | Qt::AlignBottom); 717 722 m_sidebarPreviewPage->hide(); 718 - m_sidebarPage->setGeometry(m_sidebarViewport->rect()); 719 - m_sidebarPreviewPage->setGeometry(m_sidebarViewport->rect().translated(m_sidebarViewport->width(), 0)); 723 + m_sidebarPage->setGeometry(QRect(QPoint(0, 0), m_sidebarViewport->size())); 724 + m_sidebarPreviewPage->setGeometry(QRect(QPoint(m_sidebarViewport->width(), 0), m_sidebarViewport->size())); 720 725 721 726 hostLayout->addWidget(m_webContainer, 1); 722 727 m_splitter->addWidget(sidebar); ··· 739 744 m_sidebar->setSidebarContent(m_sidebarViewport, sideLayout); 740 745 m_sidebarSwipeSettleTimer = new QTimer(this); 741 746 m_sidebarSwipeSettleTimer->setSingleShot(true); 742 - m_sidebarSwipeSettleTimer->setInterval(260); 747 + m_sidebarSwipeSettleTimer->setInterval(420); 743 748 connect(m_sidebarSwipeSettleTimer, &QTimer::timeout, this, [this] { 744 749 if (!m_sidebarSwipeActive) return; 745 750 settleSidebarSwipe(qAbs(m_profileSwipeRemainder) >= qMax(160, m_sidebarWidget ? m_sidebarWidget->width() : 240) / 3); ··· 1168 1173 } else if (wheel->phase() == Qt::ScrollEnd) { 1169 1174 settleSidebarSwipe(magnitude >= width / 4); 1170 1175 } else if (wheel->phase() == Qt::NoScrollPhase && m_sidebarSwipeSettleTimer) { 1171 - m_sidebarSwipeSettleTimer->start(); 1176 + m_sidebarSwipeSettleTimer->start(qAbs(horizontal) >= 18 ? 520 : 420); 1172 1177 } 1173 1178 return true; 1174 1179 }
+1
src/app/BrowserWindow.hpp
··· 113 113 QWidget *m_addrWrap = nullptr; 114 114 QWidget *m_sidebarWidget = nullptr; 115 115 QWidget *m_sidebarViewport = nullptr; 116 + QWidget *m_sidebarStrip = nullptr; 116 117 QWidget *m_sidebarPage = nullptr; 117 118 QWidget *m_sidebarPreviewPage = nullptr; 118 119 QTreeWidget *m_sidebarPreviewTabs = nullptr;
+46 -22
src/mac/NativeProfilePopover.mm
··· 27 27 return nil; 28 28 } 29 29 30 + constexpr CGFloat kIconButtonSize = 30.0; 31 + 30 32 NSButton *symbolButton(NSString *name, BOOL selected) { 31 33 NSButton *button = [NSButton buttonWithImage:symbolImage(name) target:nil action:nil]; 32 34 button.translatesAutoresizingMaskIntoConstraints = NO; 33 - button.bezelStyle = selected ? NSBezelStyleRegularSquare : NSBezelStyleInline; 35 + button.bezelStyle = NSBezelStyleInline; 36 + button.bordered = NO; 34 37 button.imagePosition = NSImageOnly; 35 - button.controlSize = NSControlSizeLarge; 38 + button.imageScaling = NSImageScaleProportionallyDown; 39 + button.controlSize = NSControlSizeRegular; 40 + button.contentTintColor = selected ? [NSColor controlAccentColor] : [NSColor labelColor]; 36 41 button.toolTip = name; 37 42 button.wantsLayer = YES; 38 - button.layer.cornerRadius = 9.0; 39 - [button.widthAnchor constraintEqualToConstant:34.0].active = YES; 40 - [button.heightAnchor constraintEqualToConstant:34.0].active = YES; 43 + button.layer.cornerRadius = 8.0; 44 + button.layer.backgroundColor = selected ? [[NSColor controlAccentColor] colorWithAlphaComponent:0.16].CGColor : NSColor.clearColor.CGColor; 45 + [button.widthAnchor constraintEqualToConstant:kIconButtonSize].active = YES; 46 + [button.heightAnchor constraintEqualToConstant:kIconButtonSize].active = YES; 47 + return button; 48 + } 49 + 50 + NSButton *footerButton(NSString *title, id target, SEL action) { 51 + NSButton *button = [NSButton buttonWithTitle:title target:target action:action]; 52 + button.translatesAutoresizingMaskIntoConstraints = NO; 53 + button.bezelStyle = NSBezelStyleRegularSquare; 54 + button.controlSize = NSControlSizeSmall; 55 + [button.heightAnchor constraintEqualToConstant:26.0].active = YES; 56 + [button.widthAnchor constraintGreaterThanOrEqualToConstant:58.0].active = YES; 57 + return button; 58 + } 59 + 60 + NSButton *footerIconButton(NSString *name, id target, SEL action) { 61 + NSButton *button = [NSButton buttonWithImage:symbolImage(name) target:target action:action]; 62 + button.translatesAutoresizingMaskIntoConstraints = NO; 63 + button.bezelStyle = NSBezelStyleRegularSquare; 64 + button.imagePosition = NSImageOnly; 65 + button.imageScaling = NSImageScaleProportionallyDown; 66 + button.controlSize = NSControlSizeSmall; 67 + [button.widthAnchor constraintEqualToConstant:26.0].active = YES; 68 + [button.heightAnchor constraintEqualToConstant:26.0].active = YES; 41 69 return button; 42 70 } 43 71 ··· 92 120 NSGridView *grid = [[NSGridView alloc] init]; 93 121 grid.translatesAutoresizingMaskIntoConstraints = NO; 94 122 grid.rowSpacing = 8.0; 95 - grid.columnSpacing = 8.0; 123 + grid.columnSpacing = 9.0; 96 124 scroll.documentView = grid; 97 125 98 126 NSArray<NSString *> *icons = @[ ··· 109 137 ]; 110 138 self.selectedIcon = toNSString(self.profiles->iconName(self.profiles->currentName())); 111 139 self.iconButtons = [NSMutableArray array]; 112 - const NSInteger columns = 6; 140 + const NSInteger columns = 7; 113 141 const NSInteger rows = ((NSInteger)icons.count + columns - 1) / columns; 114 142 for (NSInteger row = 0; row < rows; ++row) { 115 143 NSMutableArray<NSView *> *views = [NSMutableArray array]; ··· 117 145 NSInteger index = row * columns + col; 118 146 if (index >= (NSInteger)icons.count) { 119 147 NSView *spacer = [[NSView alloc] init]; 120 - [spacer.widthAnchor constraintEqualToConstant:34.0].active = YES; 148 + [spacer.widthAnchor constraintEqualToConstant:kIconButtonSize].active = YES; 121 149 [views addObject:spacer]; 122 150 continue; 123 151 } ··· 131 159 } 132 160 [grid addRowWithViews:views]; 133 161 } 134 - [grid.widthAnchor constraintGreaterThanOrEqualToConstant:244.0].active = YES; 135 - 162 + [grid.widthAnchor constraintEqualToConstant:264.0].active = YES; 136 163 NSStackView *buttons = [[NSStackView alloc] init]; 137 164 buttons.orientation = NSUserInterfaceLayoutOrientationHorizontal; 138 165 buttons.spacing = 8.0; 139 166 buttons.alignment = NSLayoutAttributeCenterY; 140 167 buttons.translatesAutoresizingMaskIntoConstraints = NO; 141 - NSButton *add = [NSButton buttonWithImage:symbolImage(@"plus") target:self action:@selector(addProfile:)]; 142 - add.bezelStyle = NSBezelStyleRounded; 143 - add.controlSize = NSControlSizeLarge; 168 + NSButton *add = footerIconButton(@"plus", self, @selector(addProfile:)); 144 169 add.toolTip = @"New Profile"; 145 - [add.widthAnchor constraintEqualToConstant:32.0].active = YES; 146 - NSButton *cancel = [NSButton buttonWithTitle:@"Cancel" target:self action:@selector(cancel:)]; 147 - cancel.bezelStyle = NSBezelStyleRounded; 148 - cancel.controlSize = NSControlSizeLarge; 149 - NSButton *save = [NSButton buttonWithTitle:@"Save" target:self action:@selector(save:)]; 150 - save.bezelStyle = NSBezelStyleRounded; 151 - save.controlSize = NSControlSizeLarge; 170 + NSButton *cancel = footerButton(@"Cancel", self, @selector(cancel:)); 171 + NSButton *save = footerButton(@"Save", self, @selector(save:)); 152 172 save.keyEquivalent = @"\r"; 153 173 [buttons addArrangedSubview:add]; 154 174 [buttons addArrangedSubview:[[NSView alloc] init]]; ··· 163 183 - (void)iconPicked:(NSButton *)sender { 164 184 self.selectedIcon = sender.identifier; 165 185 for (NSButton *button in self.iconButtons) { 166 - button.bezelStyle = [button.identifier isEqualToString:self.selectedIcon] ? NSBezelStyleRegularSquare : NSBezelStyleInline; 186 + BOOL selected = [button.identifier isEqualToString:self.selectedIcon]; 187 + button.contentTintColor = selected ? [NSColor controlAccentColor] : [NSColor labelColor]; 188 + button.layer.backgroundColor = selected ? [[NSColor controlAccentColor] colorWithAlphaComponent:0.16].CGColor : NSColor.clearColor.CGColor; 167 189 } 168 190 } 169 191 ··· 177 199 self.nameField.placeholderString = @"New profile name"; 178 200 self.selectedIcon = @"person.crop.circle.fill"; 179 201 for (NSButton *button in self.iconButtons) { 180 - button.bezelStyle = [button.identifier isEqualToString:self.selectedIcon] ? NSBezelStyleRegularSquare : NSBezelStyleInline; 202 + BOOL selected = [button.identifier isEqualToString:self.selectedIcon]; 203 + button.contentTintColor = selected ? [NSColor controlAccentColor] : [NSColor labelColor]; 204 + button.layer.backgroundColor = selected ? [[NSColor controlAccentColor] colorWithAlphaComponent:0.16].CGColor : NSColor.clearColor.CGColor; 181 205 } 182 206 [self.view.window makeFirstResponder:self.nameField]; 183 207 }