When I started using Qt as UI library, I found that Qt didn't provide a perfect borderless window solution to support the following functions, and I have to implement these functions by myself:
- Support to change the position and size of the window by dragging the mouse; ✅
- Support double-click the title bar to maximize/restore the window; ✅
- Support
Windows Areo Snap
feature; - Support system shadow;
- Support dragging across screens that have different DPI; ✅
- Automatically adapt to changes in resolution and DPI; ✅
- Automatically near to screen edge; ✅
There are two schemes for implementing borderless windows in Qt.
By overriding nativeEvent
function to hook windows message(such as 'WM_NCHITTEST`), the general steps are as follows:
-
Set the
WS_THICKFRAME | WS_CAPTION
property to restore the window border and title, so that the window can receive theWM_NCHITTEST
message. -
Then remove the border and title in the
WM_NCCALCSIZE
message processing. -
Set the mouse behavior (
HTLEFT
,HTRIGHT
, etc.) by judging the mouse position in theWM_NCHITTEST
message processing.
The advantage of this solution is that it can support the Windows Areo Snap
and System Shodow
feature, but it is very complicated for message processing and needs to be compatible with various versions of Qt. At present, I have not found a solution to achieve a perfect borderless through this solution.
As far as I know, the following open source projects are implemented in this way, but there are some problems, such as not supporting drag across screens that have different DPI screens, unable to adapt to resolution and DPI changes, and WM_NCHITTEST
sometimes not responding, etc. In addition, after setting the background transparency property (such as Qt :: WA_TranslucentBackground
), the system shadow feature will also disappear.
- qtdevs/FramelessHelper: https://github.com/qtdevs/FramelessHelper
- wangwenx190/framelesshelper: https://github.com/wangwenx190/framelesshelper
This solution not hook windows WM_NCHITTEST
,WM_NCCALCSIZE
messages, nor does it change the window style, and is implemented by pure Qt.
By setting MouseTracking for each Widget, make sure each Widget can respond to mouse events (mouseMoveEvent, mousePressEvent, mouseReleaseEvent, etc.), and then determine the mouse position in these events to set the shape and behavior of the mouse.
Although the logic for judging the position of the mouse is cumbersome in this way, the compatibility is better and pure, and it does not need to process various messages of Windows.
👉 This project is implemented in this way, and can support all the features of the borderless form except "Windows Areo Snap" and "System Shadow" features mentioned above.