/
VirtualMonitorManager.cpp
executable file
·116 lines (101 loc) · 3.11 KB
/
VirtualMonitorManager.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
#include "StableHeaders.hpp"
#include "VirtualMonitorManager.hpp"
#include "ScreenshotProducer.hpp"
VirtualMonitorManager::VirtualMonitorManager(
ScreenshotProducer* screenshot_producer,
Ogre::SceneManager* scene)
: mScreenshotProducer(screenshot_producer),
mScene(scene),
mStage(UpdateStage::UpdateLiveWindowsSet),
mLiveHwndIndex(0) {
}
VirtualMonitorManager::~VirtualMonitorManager() {
}
static bool IsAltTabWindow(WindowID hwnd) {
WindowID hwndWalk = ::GetAncestor(hwnd, GA_ROOTOWNER);
WindowID lastHwndTry = 0;
for (;;) {
WindowID hwndTry = ::GetLastActivePopup(hwndWalk);
if (hwndTry == lastHwndTry)
break;
lastHwndTry = hwndTry;
if (IsWindowVisible(hwndTry))
break;
hwndWalk = hwndTry;
}
return hwndWalk == hwnd;
}
void VirtualMonitorManager::Update(double frame_time) {
switch (mStage) {
case UpdateStage::UpdateLiveWindowsSet: {
// this shouldn't take much time so we just do this step to completion
mLiveHwnds.clear();
mLiveHwnds = mScreenshotProducer->GetVisibleWindows();
// only proceed with next stage if we have live windows
if (mLiveHwnds.size() > 0) {
mStage = UpdateStage::InitDeadWindowSet;
mLiveHwndIndex = 0;
}
break;
}
case UpdateStage::InitDeadWindowSet: {
mDeadMonitors.clear();
// populate from existing sets
for (auto& iter : mRootMonitors) {
mDeadMonitors.insert(iter.first);
}
for (auto& iter : mChildMonitors) {
mDeadMonitors.insert(iter.first);
}
mStage = UpdateStage::BlitWindows;
break;
}
case UpdateStage::BlitWindows: {
WindowID win = mLiveHwnds[mLiveHwndIndex];
mDeadMonitors.erase(win);
ScreenshotPtr screenshot = mScreenshotProducer->Get(win);
if (screenshot) {
bool is_root = IsAltTabWindow(win);
if (is_root) {
// make sure it exists
if (mRootMonitors.find(win) == mRootMonitors.end()) {
mRootMonitors[win] = std::make_shared<VirtualMonitor>(mScene, win);
}
auto monitor = mRootMonitors[win];
monitor->Blit(screenshot);
}
}
mLiveHwndIndex++;
if (mLiveHwndIndex >= mLiveHwnds.size()) {
mStage = UpdateStage::RemoveDeadWindows;
}
break;
}
case UpdateStage::RemoveDeadWindows: {
for (WindowID win : mDeadMonitors) {
mRootMonitors.erase(win);
mChildMonitors.erase(win);
}
mStage = UpdateStage::UpdateWindowSRT;
break;
}
case UpdateStage::UpdateWindowSRT: {
float num_root_monitors = static_cast<float>(mRootMonitors.size());
const float r = 0.5f;
int i = 0;
for (auto iter : mRootMonitors) {
auto monitor = iter.second;
monitor->UpdateScale();
float deg = 360.0f * (i / num_root_monitors);
float rad = deg * 3.14159f / 180.0f;
float x = r * cos(rad);
float y = r * sin(rad);
monitor->SetPosition(x, 0, -y);
monitor->FocusAtUser();
++i;
}
mStage = UpdateStage::UpdateLiveWindowsSet;
break;
}
}
}