File indexing completed on 2024-04-28 05:47:26
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 // shadowhelper.h 0025 // handle shadow _pixmaps passed to window manager via X property 0026 // ------------------- 0027 // 0028 // Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org> 0029 // 0030 // Permission is hereby granted, free of charge, to any person obtaining a copy 0031 // of this software and associated documentation files (the "Software"), to 0032 // deal in the Software without restriction, including without limitation the 0033 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 0034 // sell copies of the Software, and to permit persons to whom the Software is 0035 // furnished to do so, subject to the following conditions: 0036 // 0037 // The above copyright notice and this permission notice shall be included in 0038 // all copies or substantial portions of the Software. 0039 // 0040 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0041 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0042 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0043 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0044 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 0045 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 0046 // IN THE SOFTWARE. 0047 ////////////////////////////////////////////////////////////////////////////// 0048 0049 #include "shadowhelper.h" 0050 #include "utils.h" 0051 0052 #include <QDockWidget> 0053 #include <QMenu> 0054 #include <QPainter> 0055 #include <QToolBar> 0056 #include <QEvent> 0057 0058 #include <qtcurve-utils/x11shadow.h> 0059 #include <qtcurve-utils/qtprops.h> 0060 0061 namespace QtCurve { 0062 const char *const ShadowHelper::netWMForceShadowPropertyName = 0063 "_KDE_NET_WM_FORCE_SHADOW"; 0064 const char *const ShadowHelper::netWMSkipShadowPropertyName = 0065 "_KDE_NET_WM_SKIP_SHADOW"; 0066 0067 bool 0068 ShadowHelper::registerWidget(QWidget *widget, bool force) 0069 { 0070 QtcQWidgetProps props(widget); 0071 // make sure widget is not already registered 0072 if (props->shadowRegistered) 0073 return false; 0074 // check if widget qualifies 0075 if (!(force || acceptWidget(widget))) 0076 return false; 0077 props->shadowRegistered = true; 0078 // WinIdChange Event, should not happen though 0079 widget->installEventFilter(this); 0080 installX11Shadows(widget); 0081 return true; 0082 } 0083 0084 void 0085 ShadowHelper::unregisterWidget(QWidget *widget) 0086 { 0087 QtcQWidgetProps props(widget); 0088 if (props->shadowRegistered) { 0089 uninstallX11Shadows(widget); 0090 props->shadowRegistered = false; 0091 } 0092 } 0093 0094 bool 0095 ShadowHelper::eventFilter(QObject *object, QEvent *event) 0096 { 0097 if (event->type() == QEvent::WinIdChange) 0098 installX11Shadows(static_cast<QWidget*>(object)); 0099 return false; 0100 } 0101 0102 bool 0103 ShadowHelper::acceptWidget(QWidget *widget) const 0104 { 0105 if (widget->property(netWMSkipShadowPropertyName).toBool()) 0106 return false; 0107 if (widget->property(netWMForceShadowPropertyName).toBool()) 0108 return true; 0109 0110 // menus 0111 if (qobject_cast<QMenu*>(widget)) 0112 return true; 0113 0114 // combobox dropdown lists 0115 if (widget->inherits("QComboBoxPrivateContainer")) 0116 return true; 0117 0118 // tooltips 0119 if ((widget->windowType() == Qt::ToolTip || 0120 widget->inherits("QTipLabel")) && !widget->inherits("Plasma::ToolTip")) 0121 return true; 0122 0123 // detached widgets 0124 if (qobject_cast<QToolBar*>(widget) || qobject_cast<QDockWidget*>(widget)) 0125 return true; 0126 0127 // reject 0128 return false; 0129 } 0130 0131 bool 0132 ShadowHelper::installX11Shadows(QWidget *widget) 0133 { 0134 // DO NOT condition compile on QTC_ENABLE_X11. 0135 // There's no direct linkage on X11 and the following code will just do 0136 // nothing if X11 is not enabled (either at compile time or at run time). 0137 QTC_RET_IF_FAIL(qtcX11Enabled(), false); 0138 if (WId wid = qtcGetWid(widget)) { 0139 if (widget->windowType() == Qt::ToolTip && 0140 widget->inherits("QBalloonTip")) { 0141 bool atTop = true; 0142 int margin = qtcGetBalloonMargin(widget, &atTop); 0143 int margins[4] = {0, 0, 0, 0}; 0144 // KWin's shadows margin order is top, right, bottom, left.. 0145 margins[atTop ? 0 : 2] = margin; 0146 qtcX11ShadowInstall(wid, margins); 0147 } else { 0148 qtcX11ShadowInstall(wid); 0149 } 0150 return true; 0151 } 0152 return false; 0153 } 0154 0155 void 0156 ShadowHelper::uninstallX11Shadows(QWidget *widget) const 0157 { 0158 // DO NOT condition compile on QTC_ENABLE_X11. 0159 // There's no direct linkage on X11 and the following code will just do 0160 // nothing if X11 is not enabled (either at compile time or at run time). 0161 QTC_RET_IF_FAIL(qtcX11Enabled()); 0162 if (WId wid = qtcGetWid(widget)) { 0163 qtcX11ShadowUninstall(wid); 0164 } 0165 } 0166 }