File indexing completed on 2024-05-12 05:49:31
0001 /***************************************************************************** 0002 * Copyright 2010 Craig Drummond <craig.p.drummond@gmail.com> * 0003 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU Lesser General Public License as * 0007 * published by the Free Software Foundation; either version 2.1 of the * 0008 * License, or (at your option) version 3, or any later version accepted * 0009 * by the membership of KDE e.V. (or its successor approved by the * 0010 * membership of KDE e.V.), which shall act as a proxy defined in * 0011 * Section 6 of version 3 of the license. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, * 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0016 * Lesser General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU Lesser General Public * 0019 * License along with this library. If not, * 0020 * see <http://www.gnu.org/licenses/>. * 0021 *****************************************************************************/ 0022 0023 ////////////////////////////////////////////////////////////////////////////// 0024 // qtcurvesizegrip.cpp 0025 // ------------------- 0026 // 0027 // Taken from Oxygen kwin decoration 0028 // ------------ 0029 // 0030 // Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0031 // 0032 // Permission is hereby granted, free of charge, to any person obtaining a copy 0033 // of this software and associated documentation files (the "Software"), to 0034 // deal in the Software without restriction, including without limitation the 0035 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 0036 // sell copies of the Software, and to permit persons to whom the Software is 0037 // furnished to do so, subject to the following conditions: 0038 // 0039 // The above copyright notice and this permission notice shall be included in 0040 // all copies or substantial portions of the Software. 0041 // 0042 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0043 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0044 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0045 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0046 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 0047 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 0048 // IN THE SOFTWARE. 0049 ////////////////////////////////////////////////////////////////////////////// 0050 0051 #include <qtcurve-utils/x11wrap.h> 0052 #include <qtcurve-utils/x11utils.h> 0053 0054 #include "qtcurvesizegrip.h" 0055 #include "qtcurvebutton.h" 0056 #include "qtcurveclient.h" 0057 0058 #include <cassert> 0059 #include <QPainter> 0060 #include <QPolygon> 0061 #include <QTimer> 0062 0063 namespace QtCurve { 0064 namespace KWin { 0065 0066 static inline bool 0067 similar(const QColor &a, const QColor &b) 0068 { 0069 static const int diff = 18; 0070 return (abs(a.red() - b.red()) < diff && 0071 abs(a.green() - b.green()) < diff && 0072 abs(a.blue() - b.blue()) < diff); 0073 } 0074 0075 QtCurveSizeGrip::QtCurveSizeGrip(QtCurveClient* client): 0076 QWidget(0), 0077 client_(client) 0078 { 0079 setAttribute(Qt::WA_NoSystemBackground ); 0080 setAutoFillBackground(false); 0081 0082 // cursor 0083 setCursor(Qt::SizeFDiagCursor); 0084 0085 // size 0086 setFixedSize(QSize(GRIP_SIZE, GRIP_SIZE)); 0087 0088 // mask 0089 QPolygon p; 0090 p << QPoint(0, GRIP_SIZE) 0091 << QPoint(GRIP_SIZE, 0) 0092 << QPoint(GRIP_SIZE, GRIP_SIZE) 0093 << QPoint(0, GRIP_SIZE); 0094 0095 setMask(QRegion(p)); 0096 0097 // embed 0098 embed(); 0099 updatePosition(); 0100 0101 // event filter 0102 client->widget()->installEventFilter(this); 0103 0104 // show 0105 show(); 0106 } 0107 0108 QtCurveSizeGrip::~QtCurveSizeGrip() 0109 { 0110 } 0111 0112 void 0113 QtCurveSizeGrip::activeChange() 0114 { 0115 qtcX11MapRaised(winId()); 0116 } 0117 0118 void 0119 QtCurveSizeGrip::embed() 0120 { 0121 WId window_id = client().windowId(); 0122 if (client().isPreview()) { 0123 setParent(client().widget()); 0124 } else if (window_id) { 0125 WId current = window_id; 0126 while (true) { 0127 auto reply = qtcX11QueryTree(current); 0128 if (reply && reply->parent && reply->parent != reply->root && 0129 reply->parent != current) { 0130 current = reply->parent; 0131 } else { 0132 free(reply); 0133 break; 0134 } 0135 free(reply); 0136 } 0137 qtcX11ReparentWindow(winId(), current, 0, 0); 0138 qtcX11Flush(); 0139 } else { 0140 hide(); 0141 } 0142 } 0143 0144 bool 0145 QtCurveSizeGrip::eventFilter(QObject *object, QEvent *event) 0146 { 0147 0148 if (object != client().widget()) 0149 return false; 0150 if (event->type() == QEvent::Resize) 0151 updatePosition(); 0152 return false; 0153 } 0154 0155 void 0156 QtCurveSizeGrip::paintEvent(QPaintEvent*) 0157 { 0158 // get relevant colors 0159 QColor base(KDecoration::options()->color(KDecoration::ColorTitleBar, 0160 client().isActive())); 0161 // QColor light(client().helper().calcDarkColor(base)); 0162 // QColor dark(client().helper().calcDarkColor(base.darker(150))); 0163 0164 if (similar(base, client().widget()->palette().color(backgroundRole()))) 0165 base = base.value() > 100 ? base.dark(120) : base.light(120); 0166 0167 // create and configure painter 0168 QPainter painter(this); 0169 // painter.setRenderHints(QPainter::Antialiasing); 0170 0171 painter.setPen(Qt::NoPen); 0172 painter.setBrush(base); 0173 0174 // polygon 0175 QPolygon p; 0176 p << QPoint(0, GRIP_SIZE) 0177 << QPoint(GRIP_SIZE, 0) 0178 << QPoint(GRIP_SIZE, GRIP_SIZE) 0179 << QPoint(0, GRIP_SIZE); 0180 painter.drawPolygon(p); 0181 0182 // // diagonal border 0183 // painter.setBrush(Qt::NoBrush); 0184 // painter.setPen(QPen(dark, 3)); 0185 // painter.drawLine(QPoint(0, GRIP_SIZE), QPoint(GRIP_SIZE, 0)); 0186 0187 // // side borders 0188 // painter.setPen(QPen(light, 1.5)); 0189 // painter.drawLine(QPoint(1, GRIP_SIZE), QPoint(GRIP_SIZE, GRIP_SIZE)); 0190 // painter.drawLine(QPoint(GRIP_SIZE, 1), QPoint(GRIP_SIZE, GRIP_SIZE)); 0191 // painter.end(); 0192 } 0193 0194 void 0195 QtCurveSizeGrip::mousePressEvent(QMouseEvent *event) 0196 { 0197 switch (event->button()) { 0198 case Qt::RightButton: 0199 hide(); 0200 QTimer::singleShot(5000, this, SLOT(show())); 0201 break; 0202 case Qt::MidButton: 0203 hide(); 0204 break; 0205 case Qt::LeftButton: 0206 if (rect().contains(event->pos())) { 0207 // check client window id 0208 if (!client().windowId()) 0209 break; 0210 client().widget()->setFocus(); 0211 if (client().decoration()) { 0212 client().decoration()->performWindowOperation( 0213 KDecorationDefines::ResizeOp); 0214 } 0215 } 0216 break; 0217 default: 0218 break; 0219 } 0220 return; 0221 } 0222 0223 void 0224 QtCurveSizeGrip::updatePosition() 0225 { 0226 QPoint position(client().width() - GRIP_SIZE - OFFSET, 0227 client().height() - GRIP_SIZE - OFFSET); 0228 if (client().isPreview()) { 0229 position -= QPoint( 0230 client().layoutMetric(QtCurveClient::LM_BorderRight) + 0231 client().layoutMetric(QtCurveClient::LM_OuterPaddingRight), 0232 client().layoutMetric(QtCurveClient::LM_OuterPaddingBottom) + 0233 client().layoutMetric(QtCurveClient::LM_BorderBottom)); 0234 } else { 0235 position -= QPoint( 0236 client().layoutMetric(QtCurveClient::LM_BorderRight), 0237 client().layoutMetric(QtCurveClient::LM_BorderBottom)); 0238 } 0239 move(position); 0240 } 0241 0242 } 0243 }