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

Configure Feed

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

up

plyght 730820ea 21a117f3

+79 -4
+10
src/mac/MacIntegration.hpp
··· 56 56 // material tint. 57 57 void makeTransparentFloatingPanel(QWidget *window, double cornerRadius); 58 58 59 + // Prevent a top-level utility/popup QWidget from becoming the key window. 60 + // Useful for suggestion popups that must not steal the insertion cursor from 61 + // the text field that spawned them. 62 + void preventWindowActivation(QWidget *window); 63 + 64 + // Ask AppKit to keep the mouse pointer visible after typing. This counters 65 + // macOS hiding the pointer while a non-activating suggestion popup is being 66 + // repositioned under a focused text field. 67 + void keepMouseCursorVisible(); 68 + 59 69 // Make the NSWindow's titlebar transparent and hide its title text, so the 60 70 // behind-window vibrancy reads through the titlebar area as well. The 61 71 // content view is expanded to full size so Qt widgets can paint into the
+22
src/mac/Vibrancy.mm
··· 94 94 #endif 95 95 } 96 96 97 + void preventWindowActivation(QWidget *window) { 98 + #ifdef __APPLE__ 99 + if (!window) return; 100 + window->winId(); 101 + NSWindow *nsw = internal::nsWindowOf(window); 102 + if (!nsw) return; 103 + nsw.hidesOnDeactivate = NO; 104 + nsw.level = NSFloatingWindowLevel; 105 + nsw.collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; 106 + nsw.ignoresMouseEvents = NO; 107 + #else 108 + (void)window; 109 + #endif 110 + } 111 + 112 + void keepMouseCursorVisible() { 113 + #ifdef __APPLE__ 114 + [NSCursor setHiddenUntilMouseMoves:NO]; 115 + #else 116 + #endif 117 + } 118 + 97 119 void makeTransparentFloatingPanel(QWidget *window, double cornerRadius) { 98 120 #ifdef __APPLE__ 99 121 if (!window) return;
+6 -1
src/ui/AddressBarController.cpp
··· 120 120 m_pendingQuery = t.trimmed(); 121 121 m_statusText.clear(); 122 122 if (m_pendingQuery.isEmpty()) { hidePopup(); return; } 123 - populatePopup({}); 123 + mac::keepMouseCursorVisible(); 124 124 m_debounce->start(); 125 125 }); 126 126 connect(m_bar, &QLineEdit::returnPressed, this, &AddressBarController::commit); ··· 455 455 m_popup->setParent(m_bar ? m_bar->window() : nullptr); 456 456 m_popup->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::WindowDoesNotAcceptFocus); 457 457 m_popup->setAttribute(Qt::WA_TranslucentBackground); 458 + m_popup->setAttribute(Qt::WA_ShowWithoutActivating); 458 459 m_popup->setAttribute(Qt::WA_NoSystemBackground); 459 460 m_popup->setAutoFillBackground(false); 460 461 m_popup->setFocusPolicy(Qt::NoFocus); ··· 564 565 565 566 void AddressBarController::showPopup() { 566 567 if (!m_popup) return; 568 + mac::keepMouseCursorVisible(); 567 569 positionPopup(); 568 570 if (m_bar && !m_bar->hasFocus()) m_bar->setFocus(Qt::OtherFocusReason); 569 571 if (!m_popup->isVisible()) m_popup->show(); 570 572 mac::makeFloatingVibrantPanel(m_popup, mac::VibrancyMaterial::Popover, 12.0); 573 + mac::preventWindowActivation(m_popup); 571 574 mac::roundWidgetCorners(m_popup, 12.0, false); 572 575 if (m_popupList) { 573 576 m_popupList->winId(); ··· 577 580 } 578 581 m_popup->raise(); 579 582 if (m_bar) { 583 + m_bar->activateWindow(); 580 584 m_bar->setFocus(Qt::OtherFocusReason); 581 585 m_bar->update(); 582 586 } 587 + mac::keepMouseCursorVisible(); 583 588 } 584 589 585 590 void AddressBarController::hidePopup() {
+41 -3
src/web/WebView.mm
··· 73 73 WKWebView *wk = nil; 74 74 PocbWKBridge *bridge = nil; 75 75 NSView *observedHost = nil; 76 + NSArray<NSLayoutConstraint *> *edgeConstraints = nil; 76 77 QColor cachedTopColor; 77 78 }; 78 79 ··· 184 185 // size, leaving a gray L-shape along the top/left until the next manual 185 186 // resize. Subscribing to NSViewFrameDidChangeNotification on the host 186 187 // closes that gap. 188 + if (host.inLiveResize) return; 187 189 for (NSView *sub in host.subviews) { 188 190 if ([sub isKindOfClass:[WKWebView class]]) { 189 - sub.frame = host.bounds; 191 + [host setNeedsLayout:YES]; 192 + [host layoutSubtreeIfNeeded]; 193 + if (!NSEqualRects(sub.frame, host.bounds)) sub.frame = host.bounds; 190 194 } 191 195 } 192 196 } ··· 248 252 [m_impl->bridge detachKVO:m_impl->wk]; 249 253 m_impl->wk.navigationDelegate = nil; 250 254 m_impl->wk.UIDelegate = nil; 255 + if (m_impl->edgeConstraints) { 256 + [NSLayoutConstraint deactivateConstraints:m_impl->edgeConstraints]; 257 + m_impl->edgeConstraints = nil; 258 + } 251 259 [m_impl->wk removeFromSuperview]; 252 260 m_impl->wk = nil; 253 261 } ··· 259 267 WKWebView *wk = (__bridge_transfer WKWebView *)wkWebViewPtr; 260 268 if (m_impl->wk) { 261 269 [m_impl->bridge detachKVO:m_impl->wk]; 270 + if (m_impl->edgeConstraints) { 271 + [NSLayoutConstraint deactivateConstraints:m_impl->edgeConstraints]; 272 + m_impl->edgeConstraints = nil; 273 + } 262 274 [m_impl->wk removeFromSuperview]; 263 275 } 264 276 disableWebKit60FpsCap(wk.configuration.preferences); ··· 279 291 host.autoresizesSubviews = YES; 280 292 wk.frame = host.bounds; 281 293 wk.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; 294 + wk.translatesAutoresizingMaskIntoConstraints = NO; 282 295 [host addSubview:wk]; 296 + m_impl->edgeConstraints = @[ 297 + [wk.leadingAnchor constraintEqualToAnchor:host.leadingAnchor], 298 + [wk.trailingAnchor constraintEqualToAnchor:host.trailingAnchor], 299 + [wk.topAnchor constraintEqualToAnchor:host.topAnchor], 300 + [wk.bottomAnchor constraintEqualToAnchor:host.bottomAnchor] 301 + ]; 302 + [NSLayoutConstraint activateConstraints:m_impl->edgeConstraints]; 303 + [host layoutSubtreeIfNeeded]; 283 304 284 305 if (m_impl->observedHost && m_impl->observedHost != host) { 285 306 [[NSNotificationCenter defaultCenter] removeObserver:m_impl->bridge ··· 399 420 QWidget::resizeEvent(e); 400 421 if (m_impl->wk) { 401 422 NSView *host = qtNSView(this); 402 - if (host) m_impl->wk.frame = host.bounds; 423 + if (host && !host.inLiveResize) { 424 + [host setNeedsLayout:YES]; 425 + [host layoutSubtreeIfNeeded]; 426 + } 403 427 } 404 428 } 405 429 ··· 410 434 if (host) { 411 435 host.autoresizesSubviews = YES; 412 436 if (m_impl->wk.superview != host) { 437 + if (m_impl->edgeConstraints) { 438 + [NSLayoutConstraint deactivateConstraints:m_impl->edgeConstraints]; 439 + m_impl->edgeConstraints = nil; 440 + } 413 441 m_impl->wk.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; 442 + m_impl->wk.translatesAutoresizingMaskIntoConstraints = NO; 414 443 [host addSubview:m_impl->wk]; 444 + m_impl->edgeConstraints = @[ 445 + [m_impl->wk.leadingAnchor constraintEqualToAnchor:host.leadingAnchor], 446 + [m_impl->wk.trailingAnchor constraintEqualToAnchor:host.trailingAnchor], 447 + [m_impl->wk.topAnchor constraintEqualToAnchor:host.topAnchor], 448 + [m_impl->wk.bottomAnchor constraintEqualToAnchor:host.bottomAnchor] 449 + ]; 450 + [NSLayoutConstraint activateConstraints:m_impl->edgeConstraints]; 415 451 } 416 452 // Always resync the frame on show: when a tab is first activated 417 453 // the host QWidget may have been resized while hidden, and the 418 454 // NSView autoresize chain doesn't always pick that up — leaving 419 455 // a gray strip along the top/left until the next resize. 420 - m_impl->wk.frame = host.bounds; 456 + [host setNeedsLayout:YES]; 457 + [host layoutSubtreeIfNeeded]; 458 + if (!NSEqualRects(m_impl->wk.frame, host.bounds)) m_impl->wk.frame = host.bounds; 421 459 [m_impl->wk setNeedsDisplay:YES]; 422 460 423 461 if (m_impl->observedHost != host) {