|
70 | 70 | #include <QTreeView> |
71 | 71 | #include <QWidgetAction> |
72 | 72 | #include <QWindow> |
| 73 | +#include <QQuickWidget> |
73 | 74 |
|
74 | 75 | #if DARKLY_HAVE_QTQUICK |
75 | 76 | #include <QQuickWindow> |
@@ -258,6 +259,86 @@ void Style::polish(QApplication *app) |
258 | 259 | ParentStyleClass::polish(app); |
259 | 260 | } |
260 | 261 |
|
| 262 | +//______________________________________________________________ |
| 263 | +class ParentResizeFilter : public QObject { |
| 264 | +public: |
| 265 | + explicit ParentResizeFilter(QWidget* overlay) |
| 266 | + : QObject(overlay), m_overlay(overlay) {} |
| 267 | + |
| 268 | +protected: |
| 269 | + bool eventFilter(QObject* watched, QEvent* event) override { |
| 270 | + if (event->type() == QEvent::Resize && m_overlay && m_overlay->parentWidget() == watched) { |
| 271 | + m_overlay->setGeometry(m_overlay->parentWidget()->rect()); |
| 272 | + m_overlay->update(); |
| 273 | + } |
| 274 | + // call base implementation |
| 275 | + return QObject::eventFilter(watched, event); |
| 276 | + } |
| 277 | + |
| 278 | +private: |
| 279 | + QWidget* m_overlay; |
| 280 | +}; |
| 281 | + |
| 282 | +class RoundedOuterOutlineOverlay : public QWidget { |
| 283 | +public: |
| 284 | + RoundedOuterOutlineOverlay( |
| 285 | + QWidget* parent, |
| 286 | + bool isDolphin, |
| 287 | + int radius = StyleConfigData::cornerRadius(), |
| 288 | + int thickness = StyleConfigData::cornerRadius() * 2) |
| 289 | + : QWidget(parent) |
| 290 | + , m_isDolphin(isDolphin) |
| 291 | + , m_radius(radius) |
| 292 | + , m_thickness(thickness) |
| 293 | + { |
| 294 | + setAttribute(Qt::WA_TransparentForMouseEvents); |
| 295 | + setAttribute(Qt::WA_TranslucentBackground); |
| 296 | + setAttribute(Qt::WA_NoSystemBackground); |
| 297 | + show(); |
| 298 | + } |
| 299 | + |
| 300 | +protected: |
| 301 | + void paintEvent(QPaintEvent*) override { |
| 302 | + if (!parentWidget()) return; |
| 303 | + |
| 304 | + QPainter painter(this); |
| 305 | + painter.setRenderHint(QPainter::Antialiasing); |
| 306 | + |
| 307 | + QPalette::ColorGroup group = |
| 308 | + parentWidget()->isActiveWindow() |
| 309 | + ? QPalette::Active |
| 310 | + : QPalette::Inactive; |
| 311 | + |
| 312 | + QColor outlineColor = |
| 313 | + parentWidget()->style()->standardPalette().color(group, QPalette::Window); |
| 314 | + |
| 315 | + painter.setPen(Qt::NoPen); |
| 316 | + painter.setBrush(outlineColor); |
| 317 | + |
| 318 | + QPainterPath path; |
| 319 | + path.addRect(rect()); |
| 320 | + |
| 321 | + QRectF innerRect = rect(); |
| 322 | + innerRect.adjust(1, 1, m_isDolphin ? -5 : -1, -2); |
| 323 | + |
| 324 | + path.addRoundedRect(innerRect, m_radius, m_radius); |
| 325 | + path.setFillRule(Qt::OddEvenFill); |
| 326 | + |
| 327 | + if (outlineColor.alpha() < 255) |
| 328 | + { |
| 329 | + painter.setCompositionMode(QPainter::CompositionMode_Clear); |
| 330 | + painter.drawPath(path); |
| 331 | + } |
| 332 | + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); |
| 333 | + painter.drawPath(path); |
| 334 | + } |
| 335 | + |
| 336 | +private: |
| 337 | + bool m_isDolphin; |
| 338 | + int m_radius; |
| 339 | + int m_thickness; |
| 340 | +}; |
| 341 | + |
261 | 342 | //______________________________________________________________ |
262 | 343 | void Style::polish(QWidget *widget) |
263 | 344 | { |
@@ -300,6 +381,26 @@ void Style::polish(QWidget *widget) |
300 | 381 | } |
301 | 382 | } |
302 | 383 |
|
| 384 | + if (qobject_cast<QLabel*>(widget)) { |
| 385 | + QWidget* parent = widget->parentWidget(); |
| 386 | + if (!parent) |
| 387 | + return; |
| 388 | + |
| 389 | + while (parent) { |
| 390 | + if (parent->inherits("KMessageWidget")) { |
| 391 | + if (!parent->property("_darklyRoundedOverlay").isValid()) |
| 392 | + { |
| 393 | + auto overlay = new RoundedOuterOutlineOverlay(parent, _isDolphin, StyleConfigData::cornerRadius(), StyleConfigData::cornerRadius() * 2); |
| 394 | + overlay->lower(); |
| 395 | + parent->installEventFilter(new ParentResizeFilter(overlay)); |
| 396 | + parent->setProperty("_darklyRoundedOverlay", QVariant::fromValue(static_cast<QObject*>(overlay))); |
| 397 | + } |
| 398 | + break; |
| 399 | + } |
| 400 | + parent = parent->parentWidget(); |
| 401 | + } |
| 402 | + } |
| 403 | + |
303 | 404 | // enforce translucency for drag and drop window |
304 | 405 | if (widget->testAttribute(Qt::WA_X11NetWmWindowTypeDND) && _helper->compositingActive()) { |
305 | 406 | widget->setAttribute(Qt::WA_TranslucentBackground); |
@@ -399,12 +500,36 @@ void Style::polish(QWidget *widget) |
399 | 500 | } |
400 | 501 |
|
401 | 502 | // hack Dolphin's view |
402 | | - if (_isDolphin && qobject_cast<QAbstractScrollArea *>(getParent(widget, 2)) |
403 | | - && !qobject_cast<QAbstractScrollArea *>(getParent(widget, 3))) { |
| 503 | + if ((_isDolphin && qobject_cast<QAbstractScrollArea *>(getParent(widget, 2)) |
| 504 | + && !qobject_cast<QAbstractScrollArea *>(getParent(widget, 3)))) |
| 505 | + { |
404 | 506 | if (widget->autoFillBackground()) |
405 | 507 | widget->setAutoFillBackground(false); |
406 | 508 | } |
407 | 509 |
|
| 510 | + if (widget->inherits("QQuickWidget")) { |
| 511 | + // Check if it is a child of FocusHackWidget |
| 512 | + QWidget* parent = widget->parentWidget(); |
| 513 | + bool isChildOfFocusHack = false; |
| 514 | + while (parent) { |
| 515 | + if (parent->inherits("FocusHackWidget")) { |
| 516 | + isChildOfFocusHack = true; |
| 517 | + break; |
| 518 | + } |
| 519 | + parent = parent->parentWidget(); |
| 520 | + } |
| 521 | + |
| 522 | + if (isChildOfFocusHack) { |
| 523 | + auto quickWidget = qobject_cast<QQuickWidget*>(widget); |
| 524 | + if (quickWidget) { |
| 525 | + quickWidget->setClearColor(Qt::transparent); |
| 526 | + } |
| 527 | + |
| 528 | + widget->setAttribute(Qt::WA_TranslucentBackground); |
| 529 | + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); |
| 530 | + } |
| 531 | + } |
| 532 | + |
408 | 533 | // scrollarea polishing is somewhat complex. It is moved to a dedicated method |
409 | 534 | polishScrollArea(qobject_cast<QAbstractScrollArea *>(widget)); |
410 | 535 |
|
|
0 commit comments