Skip to content

Commit

Permalink
fix(#47): remove top, bottom, and right border of frameless window on…
Browse files Browse the repository at this point in the history
… Windows 10
  • Loading branch information
ffiirree committed Apr 6, 2024
1 parent 08c4498 commit ece6672
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 25 deletions.
2 changes: 1 addition & 1 deletion 3rdparty/probe
70 changes: 54 additions & 16 deletions src/widgets/framelesswindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,20 @@
#include <dwmapi.h>
#include <optional>
#include <probe/graphics.h>
#include <probe/system.h>
#include <windowsx.h>
#endif

// [microsoft/terminal](https://github.com/microsoft/terminal/blob/main/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp)
FramelessWindow::FramelessWindow(QWidget *parent, const Qt::WindowFlags flags)
: QWidget(parent, Qt::Window | Qt::WindowCloseButtonHint | flags)
: QWidget(parent, Qt::WindowCloseButtonHint | flags)
{
#ifdef Q_OS_WIN
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);

const auto hwnd = reinterpret_cast<HWND>(winId());

// shadow
constexpr DWMNCRENDERINGPOLICY ncrp = DWMNCRP_ENABLED;
::DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(DWMNCRENDERINGPOLICY));

constexpr MARGINS margins = { -1, -1, -1, -1 };
::DwmExtendFrameIntoClientArea(hwnd, &margins);

Expand Down Expand Up @@ -214,13 +211,15 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void *message, Q_
const LONG original_top = rect->top;
// apply the default frame for standard window frame (the resizable frame border and the frame
// shadow) including the left, bottom and right edges.
if (const LRESULT res = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wmsg->wParam, wmsg->lParam);
(res != HTERROR) && (res != HTNOWHERE)) {
*result = static_cast<long>(res);
return true;
if (probe::system::version() >= probe::WIN_11) {
if (const LRESULT res = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wmsg->wParam, wmsg->lParam);
(res != HTERROR) && (res != HTNOWHERE)) {
*result = static_cast<long>(res);
return true;
}
}
// re-apply the original top for removing the top frame entirely
rect->top = original_top;
rect->top = original_top;

//
const auto monitor = MonitorInfoFromWindow(hwnd);
Expand All @@ -230,6 +229,11 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void *message, Q_
// top frame
if (maximized && !fullscreen) {
rect->top += ResizeHandleHeight(hwnd);
if (probe::system::version() < probe::WIN_11) {
rect->left += ResizeHandleHeight(hwnd);
rect->right -= ResizeHandleHeight(hwnd);
rect->bottom -= ResizeHandleHeight(hwnd);
}
}

// autohide taskbar
Expand Down Expand Up @@ -265,12 +269,44 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void *message, Q_
}

case WM_NCHITTEST: {
LRESULT res = ::DefWindowProcW(hwnd, WM_NCHITTEST, 0, wmsg->lParam);
if (res == HTCLIENT) {
LRESULT res = HTCLIENT;
if (probe::system::version() >= probe::WIN_11) {
res = ::DefWindowProcW(hwnd, WM_NCHITTEST, 0, wmsg->lParam);
if (res == HTCLIENT) {
RECT rect{};
if (::GetWindowRect(hwnd, &rect) &&
GET_Y_LPARAM(wmsg->lParam) < rect.top + ResizeHandleHeight(hwnd)) {
res = HTTOP;
}
}
}
else {
const auto x = GET_X_LPARAM(wmsg->lParam), y = GET_Y_LPARAM(wmsg->lParam);
const auto thickness = ResizeHandleHeight(hwnd);

RECT rect{};
if (::GetWindowRect(hwnd, &rect) &&
GET_Y_LPARAM(wmsg->lParam) < rect.top + ResizeHandleHeight(hwnd)) {
res = HTTOP;
if (::GetWindowRect(hwnd, &rect)) {
const auto le = x > rect.left && x < (rect.left + thickness);
const auto re = x > (rect.right - thickness) && x < rect.right;
const auto te = y > rect.top && y < (rect.top + thickness);
const auto be = y > (rect.bottom - thickness) && y < rect.bottom;

if (le && te)
res = HTTOPLEFT;
else if (le && be)
res = HTBOTTOMLEFT;
else if (re && te)
res = HTTOPRIGHT;
else if (re && be)
res = HTBOTTOMRIGHT;
else if (re)
res = HTRIGHT;
else if (te)
res = HTTOP;
else if (le)
res = HTLEFT;
else if (be)
res = HTBOTTOM;
}
}

Expand All @@ -291,7 +327,8 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void *message, Q_
}

if (!fullscreen && res == HTCLIENT && titlebar_ && titlebar_->isVisible()) {
if (const auto pos = mapFromGlobal(QPoint{ GET_X_LPARAM(wmsg->lParam), GET_Y_LPARAM(wmsg->lParam) });
if (const auto pos =
mapFromGlobal(QPoint{ GET_X_LPARAM(wmsg->lParam), GET_Y_LPARAM(wmsg->lParam) });
titlebar_->geometry().contains(pos) && !titlebar_->isInSystemButtons(pos)) {
*result = HTCAPTION;
return true;
Expand All @@ -307,5 +344,6 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void *message, Q_

return QWidget::nativeEvent(eventType, message, result);
}

#endif

2 changes: 1 addition & 1 deletion src/widgets/framelesswindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FramelessWindow : public QWidget

[[nodiscard]] bool isSizeFixed() const;

TitleBar * titlebar();
TitleBar *titlebar();

public slots:
void toggleTransparentInput();
Expand Down
12 changes: 5 additions & 7 deletions src/widgets/platforms/window-effect-windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include <probe/library.h>
#include <probe/system.h>
#include <QWidget>
#include <Winuser.h>
#include <winuser.h>

#define DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 19

namespace windows::dwm
{
Expand Down Expand Up @@ -111,14 +113,10 @@ namespace windows::dwm
&mode, sizeof(mode));
}

// https://github.com/ysc3839/win32-darkmode/blob/master/win32-darkmode/DarkMode.h
HRESULT update_theme(HWND hwnd, BOOL dark)
{
const auto SetWindowCompositionAttribute =
static_cast<pfnSetWindowCompositionAttribute>(probe::library::address_of(
probe::library::load("user32.dll"), "SetWindowCompositionAttribute"));

WINDOWCOMPOSITIONATTRIBDATA wcad{ WCA_USEDARKMODECOLORS, &dark, sizeof(dark) };
SetWindowCompositionAttribute(hwnd, &wcad);
::DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &dark, sizeof(dark));

return ::DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark, sizeof(dark));
}
Expand Down

0 comments on commit ece6672

Please sign in to comment.