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
//! Puts a window in front of everything else on the desktop.
//!
//! A message-popup step is not a fault: it is the sequence asking an operator a
//! question. Killing the process to escape it throws away the answer and the
//! run. What a host actually needs is for the question to be *seen*, including
//! when an external front end, a kiosk shell, or a monitoring overlay is sitting
//! on top of it.
//!
//! Windows sorts windows into two bands, ordinary and always-on-top. Moving a
//! window into the always-on-top band puts it above every ordinary window
//! permanently, and re-asserting the request moves it to the front of that band
//! as well, so it also clears other always-on-top windows. A peer that
//! re-asserts just as often would keep contending; nothing in Win32 grants a
//! permanent win over one.
//!
//! Focus is a separate, weaker thing. Windows only lets a process steal the
//! foreground under conditions it decides (roughly, that the process already
//! owns the foreground or served the last input), so the request is made and
//! its refusal reported rather than papered over. Z-order is the guarantee;
//! focus is best effort.
use HWND;
use UI;
/// What raising a window actually achieved.
///
/// Reported rather than assumed, because the two halves have different
/// strengths: the Z-order move is a guarantee, and the focus change is a
/// request the system may refuse.
/// Moves `handle` to the front of the always-on-top band and asks for focus.
///
/// Both steps are attempted regardless of whether either succeeds, and the
/// outcome is measured afterwards.
pub
/// How long to wait for the posted reorder to be carried out before reporting
/// it as unconfirmed. Only spent on the first raise of a given window; once the
/// style is set, the first read succeeds.
const CONFIRM_ATTEMPTS: u8 = 10;
const CONFIRM_INTERVAL: Duration = from_millis;
/// Reads back whether the reorder took effect, allowing for it being posted.
///
/// The request is posted rather than sent, so it is carried out by the window's
/// own thread a moment later; reading immediately would report "not on top" for
/// a window that is about to be. Polling the style is safe from any thread
/// because it sends no message and cannot block.
/// Asks for the always-on-top band, without waiting for the answer.
///
/// Posted rather than sent (`SWP_ASYNCWINDOWPOS`). A synchronous
/// [`SetWindowPos`] would block on the window's own thread, and this runs on a
/// guard thread whose entire purpose is to stay responsive while another thread
/// is stuck. The position/size arguments are ignored because the window is only
/// being reordered.
/// Asks for keyboard focus. Returns whether the system agreed.
/// Whether the window currently sits in the always-on-top band.
///
/// Reads the window's extended style directly, which does not send a message,
/// so it cannot block on the owning thread.