summaryrefslogtreecommitdiff
path: root/src/win32.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-13 09:47:41 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-13 09:47:41 +0200
commit5d912fc85519e3d0f387a7183711bb5baf521e8a (patch)
tree1e460a5d735c9b28716ef16a87d174049ede2572 /src/win32.c
parent51a74dc9c66b76dff795a9da3874602f3f0f0285 (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.c91
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)
79iInt2 cursor_Win32(void) {
80 POINT p;
81 GetPhysicalCursorPos(&p);
82 return init_I2(p.x, p.y);
83}
84
79void processNativeEvent_Win32(const struct SDL_SysWMmsg *msg, iWindow *window) { 85void 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);