KWindowSystem

platforms/osx/kwindowinfo.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2008 Marijn Kruisselbrink <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7 
8 #include "kwindowinfo.h"
9 #include "kwindowinfo_mac_p.h"
10 #include "kwindowsystem.h"
11 
12 #include <KXErrorHandler>
13 #include <QBitmap>
14 #include <QDebug>
15 #include <QDesktopWidget>
16 #include <QDialog>
17 #include <netwm.h>
18 
19 KWindowInfo::Private::Private()
20  : ref(0)
21  , win(0)
22  , isLocal(false)
23  , loadedData(false)
24  , m_axWin(0)
25  , parent()
26  , m_pid(-1)
27 {
28 }
29 
30 void KWindowInfo::Private::setAxElement(const AXUIElementRef &axWin)
31 {
32  m_axWin = axWin;
33  CFRetain(m_axWin);
34 }
35 
36 void KWindowInfo::Private::setProcessSerialNumber(const ProcessSerialNumber &psn)
37 {
38  m_psn = psn;
39  GetProcessPID(&psn, &m_pid);
40 }
41 
42 KWindowInfo::Private::~Private()
43 {
44  if (m_axWin) {
45  CFRelease(m_axWin);
46  }
47 }
48 
49 void KWindowInfo::Private::updateData()
50 {
51  ProcessInfoRec pinfo;
52  char processName[512];
53 #ifdef Q_OS_MAC32
54  FSSpec appSpec;
55 #else
56  FSRef ref;
57 #endif
58  pinfo.processInfoLength = sizeof pinfo;
59  pinfo.processName = (unsigned char *)processName;
60 #ifdef Q_OS_MAC32
61  pinfo.processAppSpec = &appSpec;
62 #else
63  pinfo.processAppRef = &ref;
64 #endif
65  GetProcessInformation(&m_psn, &pinfo);
66  name = QString::fromLatin1(processName + 1, processName[0]);
67 
68  if (m_axWin) {
69  CFStringRef title;
70  if (AXUIElementCopyAttributeValue(m_axWin, kAXTitleAttribute, (CFTypeRef *)&title) == noErr) {
71  CFStringGetCString(title, processName, sizeof processName, kCFStringEncodingUTF8);
72  name = QString::fromUtf8(processName);
73  }
74  }
75 
76 #ifdef Q_OS_MAC32
77  iconSpec = appSpec;
78 
79  FSRef ref;
80  FSpMakeFSRef(&appSpec, &ref);
81 #else
82  iconSpec = ref;
83 #endif
84  // check if it is in an application bundle (foo.app/Contents/MacOS/plasma)
85  HFSUniStr255 name;
86  FSRef parentRef;
87  FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
88  ref = parentRef;
89  FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
90  if (QString::fromUtf16(name.unicode, name.length) == "MacOS") {
91  ref = parentRef;
92  FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
93  if (QString::fromUtf16(name.unicode, name.length) == "Contents") {
94 #ifdef Q_OS_MAC32
95  FSSpec spec;
96  ref = parentRef;
97  FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, &spec, &parentRef);
98  iconSpec = spec;
99 #else
100  iconSpec = parentRef;
101 #endif
102  }
103  }
104 
105  loadedData = true;
106 }
107 
108 KWindowInfo::KWindowInfo(WId win, unsigned long, unsigned long)
109  : d(new Private)
110 {
111  d->ref = 1;
112  d->win = win;
113  d->isLocal = true;
114  if (!win) {
115  d->win = (WId)d;
116  d->isLocal = false;
117  }
118 }
119 
120 // this one is only to make QList<> or similar happy
122  : d(nullptr)
123 {
124 }
125 
126 KWindowInfo::~KWindowInfo()
127 {
128  if (d != nullptr) {
129  if (--d->ref == 0) {
130  delete d;
131  }
132  }
133 }
134 
136  : d(wininfo.d)
137 {
138  if (d != nullptr) {
139  ++d->ref;
140  }
141 }
142 
144 {
145  if (d != wininfo.d) {
146  if (d != nullptr)
147  if (--d->ref == 0) {
148  delete d;
149  }
150  d = wininfo.d;
151  if (d != nullptr) {
152  ++d->ref;
153  }
154  }
155  return *this;
156 }
157 
158 bool KWindowInfo::valid(bool withdrawn_is_valid) const
159 {
160  return d->pid() >= 0;
161 }
162 
163 WId KWindowInfo::win() const
164 {
165  return d->win;
166 }
167 
168 unsigned long KWindowInfo::state() const
169 {
170  return 0;
171 }
172 
173 bool KWindowInfo::hasState(unsigned long s) const
174 {
175  return false;
176 }
177 
178 bool KWindowInfo::isMinimized() const
179 {
180  if (d->axElement()) {
181  CFBooleanRef val;
182  if (AXUIElementCopyAttributeValue(d->axElement(), kAXMinimizedAttribute, (CFTypeRef *)&val) == noErr) {
183  return CFBooleanGetValue(val);
184  } else {
185  return false;
186  }
187  } else {
188  return false;
189  }
190 }
191 
193 {
194  return (NET::MappingState)0;
195 }
196 
198 {
199  NETExtendedStrut ext;
200  return ext;
201 }
202 
203 NET::WindowType KWindowInfo::windowType(int supported_types) const
204 {
205  return (NET::WindowType)0;
206 }
207 
209 {
210  QString s = visibleName();
211  if (isMinimized()) {
212  s.prepend(QLatin1Char('('));
213  s.append(QLatin1Char(')'));
214  }
215  return s;
216 }
217 
219 {
220  return name();
221 }
222 
224 {
225  if (!d->loadedData) {
226  d->updateData();
227  }
228  return d->name;
229 }
230 
232 {
233  QString s = visibleIconName();
234  if (isMinimized()) {
235  s.prepend(QLatin1Char('('));
236  s.append(QLatin1Char(')'));
237  }
238  return s;
239 }
240 
242 {
243  return visibleName();
244 }
245 
247 {
248  return name();
249 }
250 
252 {
254 }
255 
256 bool KWindowInfo::isOnDesktop(int _desktop) const
257 {
258  return true;
259 }
260 
261 bool KWindowInfo::onAllDesktops() const
262 {
263  return false;
264 }
265 
266 int KWindowInfo::desktop() const
267 {
268  return 0;
269 }
270 
272 {
273  return QRect();
274 }
275 
277 {
278  return QRect();
279 }
280 
281 bool KWindowInfo::actionSupported(NET::Action action) const
282 {
283  return true; // no idea if it's supported or not -> pretend it is
284 }
285 
286 #if 0
287 WId KWindowInfo::transientFor() const
288 {
289  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor) == 0, 176)
290  << "Pass NET::WM2TransientFor to KWindowInfo";
291  return d->info->transientFor();
292 }
293 
294 WId KWindowInfo::groupLeader() const
295 {
296  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader) == 0, 176)
297  << "Pass NET::WM2GroupLeader to KWindowInfo";
298  return d->info->groupLeader();
299 }
300 
302 {
303  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass) == 0, 176)
304  << "Pass NET::WM2WindowClass to KWindowInfo";
305  return d->info->windowClassClass();
306 }
307 
309 {
310  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass) == 0, 176)
311  << "Pass NET::WM2WindowClass to KWindowInfo";
312  return d->info->windowClassName();
313 }
314 
316 {
317  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole) == 0, 176)
318  << "Pass NET::WM2WindowRole to KWindowInfo";
319  return d->info->windowRole();
320 }
321 
323 {
324  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine) == 0, 176)
325  << "Pass NET::WM2ClientMachine to KWindowInfo";
326  return d->info->clientMachine();
327 }
328 
329 bool KWindowInfo::actionSupported(NET::Action action) const
330 {
331  kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions) == 0, 176)
332  << "Pass NET::WM2AllowedActions to KWindowInfo";
334  return d->info->allowedActions() & action;
335  } else {
336  return true; // no idea if it's supported or not -> pretend it is
337  }
338 }
339 
340 // see NETWM spec section 7.6
341 bool KWindowInfo::isMinimized() const
342 {
343  if (mappingState() != NET::Iconic) {
344  return false;
345  }
346  // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows
347  if ((state() & NET::Hidden) != 0
348  && (state() & NET::Shaded) == 0) { // shaded may have NET::Hidden too
349  return true;
350  }
351  // older WMs use WithdrawnState for other virtual desktops
352  // and IconicState only for minimized
353  return KWindowSystem::icccmCompliantMappingState() ? false : true;
354 }
355 #endif
QString & append(QChar ch)
QString iconName() const
Returns the name of the window that should be shown in taskbar.
QString visibleName() const
Returns the visible name of the window.
KWindowInfo & operator=(const KWindowInfo &)
Assignment operator.
QString visibleIconName() const
Returns the visible name of the window that should be shown in a taskbar.
QRect frameGeometry() const
Returns the frame geometry of the window, i.e.
QString & prepend(QChar ch)
indicates that the client window is not visible, but its icon is.
Definition: netwm_def.h:638
This class provides information about a given window in the platform specific windowing system...
Definition: kwindowinfo.h:62
Partial strut class for NET classes.
Definition: netwm_def.h:180
NET::States state() const
Returns the window&#39;s state flags.
NET::WindowType windowType(NET::WindowTypes supported_types) const
Returns the window type of this window.
void ref()
QString visibleNameWithState() const
Returns a visible name with state.
QByteArray clientMachine() const
Returns the client machine for the window.
bool isMinimized() const
Returns true if the window is minimized.
indicates that a window should not be visible on the screen (e.g.
Definition: netwm_def.h:550
bool onAllDesktops() const
Returns true if the window is on all desktops.
MappingState
Client window mapping state.
Definition: netwm_def.h:624
bool actionSupported(NET::Action action) const
Returns true if the given action is currently supported for the window.
NET::MappingState mappingState() const
Returns the mapping state of the window.
static int currentDesktop()
Returns the current virtual desktop.
QString fromUtf8(const char *str, int size)
NETExtendedStrut extendedStrut() const
Returns the window extended (partial) strut.
bool valid(bool withdrawn_is_valid=false) const
Returns false if this window info is not valid.
QString fromUtf16(const ushort *unicode, int size)
WindowType
Window type.
Definition: netwm_def.h:357
static bool icccmCompliantMappingState()
QByteArray windowRole() const
Returns the window role for the window.
WId groupLeader() const
Returns the leader window for the group the window is in, if any.
bool isOnDesktop(int desktop) const
Returns true if the window is on the given virtual desktop.
KWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2=NET::Properties2())
Reads all the info about the given window.
QRect geometry() const
Returns the position and size of the window contents.
WId win() const
Returns the window identifier.
bool hasState(NET::States s) const
Returns true if the window has the given state flag set.
indicates that the window is shaded (rolled-up).
Definition: netwm_def.h:526
static bool allowedActionsSupported()
Returns true if the WM announces which actions it allows for windows.
WId transientFor() const
Returns the window identifier of the main window this window belongs to.
QByteArray windowClassName() const
Returns the name component of the window class for the window.
QString fromLatin1(const char *str, int size)
QString name() const
Returns the name of the window, as specified by the application.
Action
Actions that can be done with a window (_NET_WM_ALLOWED_ACTIONS).
Definition: netwm_def.h:645
int desktop() const
Returns the virtual desktop this window is on.
bool isOnCurrentDesktop() const
Returns true if the window is on the currently active virtual desktop.
QByteArray windowClassClass() const
Returns the class component of the window class for the window.
QString visibleIconNameWithState() const
Returns a visible icon name with state.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Oct 15 2021 22:41:50 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.