forked from feiyangqingyun/QWidgetDemo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqxtwindowsystem_mac.cpp
158 lines (124 loc) · 4.29 KB
/
qxtwindowsystem_mac.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef QXTWINDOWSYSTEM_MAC_CPP
#define QXTWINDOWSYSTEM_MAC_CPP
#include "qxtwindowsystem.h"
#include "qxtwindowsystem_mac.h"
// WId to return when error
#define WINDOW_NOT_FOUND (WId)(0)
WindowList qxt_getWindowsForPSN(ProcessSerialNumber *psn)
{
static CGSConnection connection = _CGSDefaultConnection();
WindowList wlist;
if (!psn) return wlist;
CGError err((CGError)noErr);
// get onnection for given process psn
CGSConnection procConnection;
err = CGSGetConnectionIDForPSN(connection, psn, &procConnection);
if (err != noErr) return wlist;
/* get number of windows open by given process
in Mac OS X an application may have multiple windows, which generally
represent documents. It is also possible that there is no window even
though there is an application, it can simply not have any documents open. */
int windowCount(0);
err = CGSGetOnScreenWindowCount(connection, procConnection, &windowCount);
// if there are no windows open by this application, skip
if (err != noErr || windowCount == 0) return wlist;
// get list of windows
int windowList[windowCount];
int outCount(0);
err = CGSGetOnScreenWindowList(connection, procConnection, windowCount, windowList, &outCount);
if (err != noErr || outCount == 0) return wlist;
for (int i=0; i<outCount; ++i)
{
wlist += windowList[i];
}
return wlist;
}
WindowList QxtWindowSystem::windows()
{
WindowList wlist;
ProcessSerialNumber psn = {0, kNoProcess};
// iterate over list of processes
OSErr err;
while ((err = ::GetNextProcess(&psn)) == noErr)
{
wlist += qxt_getWindowsForPSN(&psn);
}
return wlist;
}
WId QxtWindowSystem::activeWindow()
{
ProcessSerialNumber psn;
OSErr err(noErr);
err = ::GetFrontProcess(&psn);
if (err != noErr) return WINDOW_NOT_FOUND;
// in Mac OS X, first window for given PSN is always the active one
WindowList wlist = qxt_getWindowsForPSN(&psn);
if (wlist.count() > 0)
return wlist.at(0);
return WINDOW_NOT_FOUND;
}
QString QxtWindowSystem::windowTitle(WId window)
{
CGSValue windowTitle;
CGError err((CGError)noErr);
static CGSConnection connection = _CGSDefaultConnection();
// This code is so dirty I had to wash my hands after writing it.
// most of CoreGraphics private definitions ask for CGSValue as key but since
// converting strings to/from CGSValue was dropped in 10.5, I use CFString, which
// apparently also works.
// FIXME: Not public API function. Can't compile with OS X 10.8
// err = CGSGetWindowProperty(connection, window, (CGSValue)CFSTR("kCGSWindowTitle"), &windowTitle);
if (err != noErr) return QString();
// this is UTF8 encoded
return QCFString::toQString((CFStringRef)windowTitle);
}
QRect QxtWindowSystem::windowGeometry(WId window)
{
CGRect rect;
static CGSConnection connection = _CGSDefaultConnection();
CGError err = CGSGetWindowBounds(connection, window, &rect);
if (err != noErr) return QRect();
return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}
/* This method is the only one that is not a complete hack
from Quartz Event Services
http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
*/
uint QxtWindowSystem::idleTime()
{
// CGEventSourceSecondsSinceLastEventType returns time in seconds as a double
// also has extremely long name
double idle = 1000 * ::CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
return (uint)idle;
}
// these are copied from X11 implementation
WId QxtWindowSystem::findWindow(const QString& title)
{
WId result = 0;
WindowList list = windows();
foreach(const WId &wid, list)
{
if (windowTitle(wid) == title)
{
result = wid;
break;
}
}
return result;
}
WId QxtWindowSystem::windowAt(const QPoint& pos)
{
WId result = 0;
WindowList list = windows();
for (int i = list.size() - 1; i >= 0; --i)
{
WId wid = list.at(i);
if (windowGeometry(wid).contains(pos))
{
result = wid;
break;
}
}
return result;
}
#endif // QXTWINDOWSYSTEM_MAC_CPP