Open adamjs opened 4 years ago
This is how you can currently do it, in case anyone wants to rush ahead:
<div onmousedown="softwareDragMove(true)" onmouseup="softwareDragMove(false)">
Drag me!
</div>
void CMyApp::OnDragMove(const JSObject& obj, const JSArgs& args)
{
dragging = args[0];
}
void CMyApp::OnDOMReady(View* caller, uint64_t frame_id, bool is_main_frame, const String& url)
{
Ref<JSContext> locked_context = caller->LockJSContext();
SetJSContext(locked_context.get());
JSObject global = JSGlobalObject();
global["softwareDragMove"] = BindJSCallback(&CMyApp::OnDragMove);
}
void CMyApp::OnUpdate()
{
if (dragging) {
ReleaseCapture();
SendMessageA(hwnd_, WM_SYSCOMMAND, 0xf012, 0);
}
// JS onmouseup won't be fired while dragging the window for some reason
// ... so we check it one more time, manually and disable dragging
if (!GetAsyncKeyState(VK_LBUTTON & 0x8000)) {
dragging = false;
}
}
The solution above had issues with my app (hover/mouse up events not firing when dragging finished until u clicked inside ultralight window) so I came up with another solution.
POINT mouseStartPoint;
RECT windowStartPoint;
bool isEmpty(RECT rect) {
return rect.left == 0 && rect.bottom == 0 && rect.right == 0 && rect.top == 0;
}
void PvPHero::OnUpdate() {
if (!isEmpty(windowStartPoint)) {
if (!GetAsyncKeyState(VK_LBUTTON)) {
windowStartPoint = {};
} else {
POINT pt;
GetCursorPos(&pt);
SetWindowPos((HWND) window->native_handle(), 0, windowStartPoint.left + pt.x - mouseStartPoint.x,
windowStartPoint.top + pt.y - mouseStartPoint.y,
0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
}
}
}
void PvPHero::StartDrag(const JSObject &obj, const JSArgs &args) {
GetWindowRect((HWND) window->native_handle(), &windowStartPoint);
GetCursorPos(&mouseStartPoint);
}
Some users may want to draw their own titlebar and close/minimize/maximize buttons (similar to Spotify and Discord).
To accomplish this, we need to support borderless windows + custom window drag handles (basically, redefine a section of window coordinates as the drag handle for the window).
WinAPI supports this via the WM_NCHITTEST message (see https://stackoverflow.com/questions/35522488/moving-frameless-window-by-dragging-it-from-a-portion-of-client-area)