File indexing completed on 2024-04-21 05:31:18
0001 /* 0002 SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "dialog.h" 0007 0008 // Qt 0009 #include <QScreen> 0010 #include <QWindow> 0011 0012 0013 namespace Latte { 0014 namespace Quick { 0015 0016 Dialog::Dialog(QQuickItem *parent) 0017 : PlasmaQuick::Dialog(parent) 0018 { 0019 connect(this, &PlasmaQuick::Dialog::visualParentChanged, this, &Dialog::onVisualParentChanged); 0020 } 0021 0022 bool Dialog::containsMouse() const 0023 { 0024 return m_containsMouse; 0025 } 0026 0027 void Dialog::setContainsMouse(bool contains) 0028 { 0029 if (m_containsMouse == contains) { 0030 return; 0031 } 0032 0033 m_containsMouse = contains; 0034 emit containsMouseChanged(); 0035 } 0036 0037 Plasma::Types::Location Dialog::edge() const 0038 { 0039 return m_edge; 0040 } 0041 0042 void Dialog::setEdge(const Plasma::Types::Location &edge) 0043 { 0044 if (m_edge == edge) { 0045 return; 0046 } 0047 0048 m_edge = edge; 0049 emit edgeChanged(); 0050 } 0051 0052 bool Dialog::isRespectingAppletsLayoutGeometry() const 0053 { 0054 //! As it appears plasma applets popups are defining their popups to Normal window. 0055 //! Dock type is needed from wayland scenario. In wayland after a while popups from Normal become Dock types 0056 return (type() == Dialog::Normal || type() == Dialog::PopupMenu || type() == Dialog::Tooltip || type() == Dialog::Dock); 0057 } 0058 0059 QRect Dialog::appletsLayoutGeometryFromContainment() const 0060 { 0061 QVariant geom = visualParent() && visualParent()->window() ? visualParent()->window()->property("_applets_layout_geometry") : QVariant(); 0062 return geom.isValid() ? geom.toRect() : QRect(); 0063 } 0064 0065 int Dialog::appletsPopUpMargin() const 0066 { 0067 QVariant margin = visualParent() && visualParent()->window() ? visualParent()->window()->property("_applets_popup_margin") : QVariant(); 0068 return margin.isValid() ? margin.toInt() : -1; 0069 } 0070 0071 void Dialog::onVisualParentChanged() 0072 { 0073 // clear mode 0074 for (auto &c : m_visualParentConnections) { 0075 disconnect(c); 0076 } 0077 0078 if (!visualParent() || !flags().testFlag(Qt::ToolTip) || !visualParent()->metaObject()) { 0079 return; 0080 } 0081 0082 bool hassignal = (visualParent()->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("anchoredTooltipPositionChanged()")) != -1); 0083 0084 if (hassignal) { 0085 m_visualParentConnections[0] = connect(visualParent(), SIGNAL(anchoredTooltipPositionChanged()) , this, SLOT(updateGeometry())); 0086 } 0087 } 0088 0089 void Dialog::updateGeometry() 0090 { 0091 if (visualParent()) { 0092 setPosition(popupPosition(visualParent(), size())); 0093 } 0094 } 0095 0096 void Dialog::updatePopUpEnabledBorders() 0097 { 0098 QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment(); 0099 int appletspopupmargin = appletsPopUpMargin(); 0100 0101 //! Plasma Scenario 0102 bool hideEdgeBorder = isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty() && appletspopupmargin==-1; 0103 0104 if (hideEdgeBorder) { 0105 setLocation(m_edge); 0106 } else { 0107 setLocation(Plasma::Types::Floating); 0108 } 0109 } 0110 0111 QPoint Dialog::popupPosition(QQuickItem *item, const QSize &size) 0112 { 0113 auto visualparent = item; 0114 0115 if (visualparent && visualparent->window() && visualparent->window()->screen()) { 0116 updatePopUpEnabledBorders(); 0117 0118 QPointF parenttopleftf = visualparent->mapToGlobal(QPointF(0, 0)); 0119 QPoint parenttopleft = parenttopleftf.toPoint(); 0120 QScreen *screen = visualparent->window()->screen(); 0121 QRect screengeometry = screen->geometry(); 0122 0123 int x = 0; 0124 int y = 0; 0125 0126 int popupmargin = qMax(0, appletsPopUpMargin()); 0127 0128 if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) { 0129 //! vertical scenario 0130 screengeometry -= QMargins(0, popupmargin, 0, popupmargin); 0131 y = parenttopleft.y() + (visualparent->height()/2) - (size.height()/2); 0132 } else { 0133 //! horizontal scenario 0134 screengeometry -= QMargins(popupmargin, 0, popupmargin, 0); 0135 x = parenttopleft.x() + (visualparent->width()/2) - (size.width()/2); 0136 } 0137 0138 if (m_edge == Plasma::Types::LeftEdge) { 0139 x = parenttopleft.x() + visualparent->width() + popupmargin; 0140 } else if (m_edge == Plasma::Types::RightEdge) { 0141 x = parenttopleft.x() - size.width() - popupmargin; 0142 } else if (m_edge == Plasma::Types::TopEdge) { 0143 y = parenttopleft.y() + visualparent->height() + popupmargin; 0144 } else { // bottom case 0145 y = parenttopleft.y() - size.height() - popupmargin; 0146 } 0147 0148 x = qBound(screengeometry.x(), x, screengeometry.right() - size.width() + 1); 0149 y = qBound(screengeometry.y(), y, screengeometry.bottom() - size.height() + 1); 0150 0151 QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment(); 0152 0153 0154 0155 if (isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty()) { 0156 QPoint appletsglobaltopleft = visualparent->window()->mapToGlobal(appletslayoutgeometry.topLeft()); 0157 0158 QRect appletsglobalgeometry(appletsglobaltopleft.x(), appletsglobaltopleft.y(), appletslayoutgeometry.width(), appletslayoutgeometry.height()); 0159 0160 if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) { 0161 int bottomy = appletsglobalgeometry.bottom()-size.height(); 0162 0163 if (appletsglobalgeometry.height() >= size.height()) { 0164 y = qBound(appletsglobalgeometry.y(), y, bottomy + 1); 0165 } 0166 } else { 0167 int rightx = appletsglobalgeometry.right()-size.width(); 0168 0169 if (appletsglobalgeometry.width() >= size.width()) { 0170 x = qBound(appletsglobalgeometry.x(), x, rightx + 1); 0171 } 0172 } 0173 } 0174 0175 return QPoint(x,y); 0176 } 0177 0178 return PlasmaQuick::Dialog::popupPosition(item, size); 0179 } 0180 0181 /* 0182 void Dialog::adjustGeometry(const QRect &geom) 0183 { 0184 auto visualparent = visualParent(); 0185 0186 if (visualparent && visualparent->window() && visualparent->window()->screen()) { 0187 updatePopUpEnabledBorders(); 0188 0189 QPointF parenttopleftf = visualparent->mapToGlobal(QPointF(0, 0)); 0190 QPoint parenttopleft = parenttopleftf.toPoint(); 0191 QScreen *screen = visualparent->window()->screen(); 0192 QRect screengeometry = screen->geometry(); 0193 0194 int x = 0; 0195 int y = 0; 0196 0197 if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) { 0198 y = parenttopleft.y() + (visualparent->height()/2) - (geom.height()/2); 0199 } else { 0200 x = parenttopleft.x() + (visualparent->width()/2) - (geom.width()/2); 0201 } 0202 0203 int popupmargin = qMax(0, appletsPopUpMargin()); 0204 0205 if (m_edge == Plasma::Types::LeftEdge) { 0206 x = parenttopleft.x() + visualparent->width() + popupmargin; 0207 } else if (m_edge == Plasma::Types::RightEdge) { 0208 x = parenttopleft.x() - geom.width() - popupmargin; 0209 } else if (m_edge == Plasma::Types::TopEdge) { 0210 y = parenttopleft.y() + visualparent->height() + popupmargin; 0211 } else { // bottom case 0212 y = parenttopleft.y() - geom.height() - popupmargin; 0213 } 0214 0215 x = qBound(screengeometry.x(), x, screengeometry.right()-1); 0216 y = qBound(screengeometry.y(), y, screengeometry.bottom()-1); 0217 0218 QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment(); 0219 0220 if (isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty()) { 0221 QPoint appletsglobaltopleft = visualparent->window()->mapToGlobal(appletslayoutgeometry.topLeft()); 0222 0223 QRect appletsglobalgeometry(appletsglobaltopleft.x(), appletsglobaltopleft.y(), appletslayoutgeometry.width(), appletslayoutgeometry.height()); 0224 0225 if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) { 0226 int bottomy = appletsglobalgeometry.bottom()-geom.height(); 0227 0228 if (appletsglobalgeometry.height() >= geom.height()) { 0229 y = qBound(appletsglobalgeometry.y(), y, bottomy + 1); 0230 } 0231 } else { 0232 int rightx = appletsglobalgeometry.right()-geom.width(); 0233 0234 if (appletsglobalgeometry.width() >= geom.width()) { 0235 x = qBound(appletsglobalgeometry.x(), x, rightx + 1); 0236 } 0237 } 0238 } 0239 0240 QRect repositionedrect(x, y, geom.width(), geom.height()); 0241 setGeometry(repositionedrect); 0242 return; 0243 } 0244 0245 PlasmaQuick::Dialog::adjustGeometry(geom); 0246 } 0247 */ 0248 0249 bool Dialog::event(QEvent *e) 0250 { 0251 if (e->type() == QEvent::Enter) { 0252 setContainsMouse(true); 0253 } else if (e->type() == QEvent::Leave 0254 || e->type() == QEvent::Hide) { 0255 setContainsMouse(false); 0256 } 0257 0258 return PlasmaQuick::Dialog::event(e); 0259 } 0260 0261 } 0262 }