diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-13 09:47:41 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-13 09:47:41 +0200 |
commit | 5d912fc85519e3d0f387a7183711bb5baf521e8a (patch) | |
tree | 1e460a5d735c9b28716ef16a87d174049ede2572 /src/win32.c | |
parent | 51a74dc9c66b76dff795a9da3874602f3f0f0285 (diff) |
Windows: Improved custom frame behavior
Windows-key shortcuts and cursor edge snapping.
Still missing: window shadow and saving the snap mode.
Diffstat (limited to 'src/win32.c')
-rw-r--r-- | src/win32.c | 91 |
1 files changed, 87 insertions, 4 deletions
diff --git a/src/win32.c b/src/win32.c index 585fdaaf..504cfe90 100644 --- a/src/win32.c +++ b/src/win32.c | |||
@@ -76,17 +76,86 @@ void setup_SDLWindow(SDL_Window *win) { | |||
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #if defined (LAGRANGE_CUSTOM_FRAME) | 78 | #if defined (LAGRANGE_CUSTOM_FRAME) |
79 | iInt2 cursor_Win32(void) { | ||
80 | POINT p; | ||
81 | GetPhysicalCursorPos(&p); | ||
82 | return init_I2(p.x, p.y); | ||
83 | } | ||
84 | |||
79 | void processNativeEvent_Win32(const struct SDL_SysWMmsg *msg, iWindow *window) { | 85 | void processNativeEvent_Win32(const struct SDL_SysWMmsg *msg, iWindow *window) { |
86 | static int winDown_[2] = { 0, 0 }; | ||
80 | HWND hwnd = msg->msg.win.hwnd; | 87 | HWND hwnd = msg->msg.win.hwnd; |
81 | // printf("[syswm] %x\n", msg->msg.win.msg); fflush(stdout); | 88 | printf("[syswm] %x\n", msg->msg.win.msg); fflush(stdout); |
89 | const WPARAM wp = msg->msg.win.wParam; | ||
82 | switch (msg->msg.win.msg) { | 90 | switch (msg->msg.win.msg) { |
91 | case WM_KEYDOWN: { | ||
92 | if (wp == VK_LWIN) { | ||
93 | printf("lwin down\n"); fflush(stdout); | ||
94 | winDown_[0] = iTrue; | ||
95 | } | ||
96 | else if (wp == VK_RWIN) { | ||
97 | //printf("rwin down\n"); fflush(stdout); | ||
98 | winDown_[1] = iTrue; | ||
99 | } | ||
100 | break; | ||
101 | } | ||
102 | case WM_KEYUP: { | ||
103 | if (winDown_[0] || winDown_[1]) { | ||
104 | /* Emulate the default window snapping behavior. */ | ||
105 | int snap = snap_Window(window); | ||
106 | if (wp == VK_LEFT) { | ||
107 | snap &= ~(topBit_WindowSnap | bottomBit_WindowSnap); | ||
108 | setSnap_Window(window, | ||
109 | snap == right_WindowSnap ? 0 : left_WindowSnap); | ||
110 | } | ||
111 | else if (wp == VK_RIGHT) { | ||
112 | snap &= ~(topBit_WindowSnap | bottomBit_WindowSnap); | ||
113 | setSnap_Window(window, | ||
114 | snap == left_WindowSnap ? 0 : right_WindowSnap); | ||
115 | } | ||
116 | else if (wp == VK_UP) { | ||
117 | if (~snap & topBit_WindowSnap) { | ||
118 | setSnap_Window(window, | ||
119 | snap & bottomBit_WindowSnap ? snap & ~bottomBit_WindowSnap | ||
120 | : snap == left_WindowSnap || snap == right_WindowSnap | ||
121 | ? snap | topBit_WindowSnap | ||
122 | : maximized_WindowSnap); | ||
123 | } | ||
124 | else { | ||
125 | postCommand_App("window.maximize"); | ||
126 | } | ||
127 | } | ||
128 | else if (wp == VK_DOWN) { | ||
129 | if (snap == 0 || snap & bottomBit_WindowSnap) { | ||
130 | postCommand_App("window.minimize"); | ||
131 | } | ||
132 | else { | ||
133 | setSnap_Window(window, | ||
134 | snap == maximized_WindowSnap ? 0 | ||
135 | : snap & topBit_WindowSnap ? snap & ~topBit_WindowSnap | ||
136 | : snap == left_WindowSnap || snap == right_WindowSnap | ||
137 | ? snap | bottomBit_WindowSnap | ||
138 | : 0); | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | if (wp == VK_LWIN) { | ||
143 | winDown_[0] = iFalse; | ||
144 | } | ||
145 | if (wp == VK_RWIN) { | ||
146 | winDown_[1] = iFalse; | ||
147 | } | ||
148 | break; | ||
149 | } | ||
83 | case WM_NCLBUTTONDBLCLK: { | 150 | case WM_NCLBUTTONDBLCLK: { |
84 | POINT point = { GET_X_LPARAM(msg->msg.win.lParam), GET_Y_LPARAM(msg->msg.win.lParam) }; | 151 | POINT point = { GET_X_LPARAM(msg->msg.win.lParam), |
152 | GET_Y_LPARAM(msg->msg.win.lParam) }; | ||
85 | ScreenToClient(hwnd, &point); | 153 | ScreenToClient(hwnd, &point); |
86 | iInt2 pos = init_I2(point.x, point.y); | 154 | iInt2 pos = init_I2(point.x, point.y); |
87 | switch (hitTest_Window(window, pos)) { | 155 | switch (hitTest_Window(window, pos)) { |
88 | case SDL_HITTEST_DRAGGABLE: | 156 | case SDL_HITTEST_DRAGGABLE: |
89 | postCommand_App("window.maximize toggle:1"); | 157 | postCommandf_App("window.%s", |
158 | snap_Window(window) ? "restore" : "maximize toggle:1"); | ||
90 | break; | 159 | break; |
91 | case SDL_HITTEST_RESIZE_TOP: | 160 | case SDL_HITTEST_RESIZE_TOP: |
92 | case SDL_HITTEST_RESIZE_BOTTOM: { | 161 | case SDL_HITTEST_RESIZE_BOTTOM: { |
@@ -98,11 +167,25 @@ void processNativeEvent_Win32(const struct SDL_SysWMmsg *msg, iWindow *window) { | |||
98 | break; | 167 | break; |
99 | } | 168 | } |
100 | #if 0 | 169 | #if 0 |
170 | case WM_NCLBUTTONUP: { | ||
171 | POINT point = { GET_X_LPARAM(msg->msg.win.lParam), | ||
172 | GET_Y_LPARAM(msg->msg.win.lParam) }; | ||
173 | printf("%d,%d\n", point.x, point.y); fflush(stdout); | ||
174 | ScreenToClient(hwnd, &point); | ||
175 | iInt2 pos = init_I2(point.x, point.y); | ||
176 | if (hitTest_Window(window, pos) == SDL_HITTEST_DRAGGABLE) { | ||
177 | printf("released draggable\n"); fflush(stdout); | ||
178 | } | ||
179 | break; | ||
180 | } | ||
181 | #endif | ||
182 | #if 0 | ||
101 | /* SDL does not use WS_SYSMENU on the window, so we can't display the system menu. | 183 | /* SDL does not use WS_SYSMENU on the window, so we can't display the system menu. |
102 | However, the only useful function in the menu would be moving-via-keyboard, | 184 | However, the only useful function in the menu would be moving-via-keyboard, |
103 | but that doesn't work with a custom frame. We could show a custom system menu? */ | 185 | but that doesn't work with a custom frame. We could show a custom system menu? */ |
104 | case WM_NCRBUTTONUP: { | 186 | case WM_NCRBUTTONUP: { |
105 | POINT point = { GET_X_LPARAM(msg->msg.win.lParam), GET_Y_LPARAM(msg->msg.win.lParam) }; | 187 | POINT point = { GET_X_LPARAM(msg->msg.win.lParam), |
188 | GET_Y_LPARAM(msg->msg.win.lParam) }; | ||
106 | HMENU menu = GetSystemMenu(hwnd, FALSE); | 189 | HMENU menu = GetSystemMenu(hwnd, FALSE); |
107 | printf("menu at %d,%d menu:%p\n", point.x, point.y, menu); fflush(stdout); | 190 | printf("menu at %d,%d menu:%p\n", point.x, point.y, menu); fflush(stdout); |
108 | TrackPopupMenu(menu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL); | 191 | TrackPopupMenu(menu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL); |