Browse Source

Updated formatting for c++.

pull/170/head
weisj 5 years ago
parent
commit
a6aa9fc6ac
  1. 28
      darklaf_cpp.eclipseformat.xml
  2. 367
      windows/src/main/cpp/Decorations.cpp
  3. 9
      windows/src/main/cpp/Decorations.h
  4. 116
      windows/src/main/cpp/ThemeInfo.cpp

28
darklaf_cpp.eclipseformat.xml

@ -45,7 +45,7 @@
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_linkage_declaration"
value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="34"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="18"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
@ -67,7 +67,7 @@
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_binary_expression" value="18"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
@ -78,16 +78,16 @@
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_pointer_in_declarator_list"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.comment.line_up_line_comment_in_blocks_on_first_column"
value="false"/>
@ -97,9 +97,9 @@
<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces" value="0"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_lambda_return" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="80"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters"
@ -110,7 +110,7 @@
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_colon_in_constructor_initializer_list"
value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
@ -135,7 +135,7 @@
<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="83"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="18"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
@ -167,7 +167,7 @@
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.format_block_comment" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters"
value="insert"/>
@ -205,10 +205,10 @@
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/>
@ -216,7 +216,7 @@
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_structured_binding_name_list"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_structured_binding_name_list"
value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
@ -259,7 +259,7 @@
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.alignment_for_assignment" value="18"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_linkage_declaration" value="next_line"/>
<setting id="org.eclipse.cdt.core.formatter.brace_position_for_linkage_declaration" value="end_of_line"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/>
<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments"

367
windows/src/main/cpp/Decorations.cpp

@ -34,21 +34,16 @@
std::map<HWND, WindowWrapper*> wrapper_map = std::map<HWND, WindowWrapper*>();
bool Maximized(HWND hwnd)
{
bool Maximized(HWND hwnd) {
WINDOWPLACEMENT placement;
if (!GetWindowPlacement(hwnd, &placement))
return false;
if (!GetWindowPlacement(hwnd, &placement)) return false;
return placement.showCmd == SW_MAXIMIZE;
}
LRESULT HandleHitTest(WindowWrapper *wrapper, int x, int y)
{
if (wrapper->popup_menu)
return HTCLIENT;
LRESULT HandleHitTest(WindowWrapper *wrapper, int x, int y) {
if (wrapper->popup_menu) return HTCLIENT;
POINT ptMouse = { x,
y };
POINT ptMouse = { x, y };
// Get the window rectangle.
RECT rcWindow;
@ -58,12 +53,13 @@ LRESULT HandleHitTest(WindowWrapper *wrapper, int x, int y)
USHORT uRow = 1;
USHORT uCol = 1;
if (!Maximized(wrapper->window))
{
/* The horizontal frame should be the same size as the vertical frame,
since the NONCLIENTMETRICS structure does not distinguish between them */
if (!Maximized(wrapper->window)) {
/*
* The horizontal frame should be the same size as the vertical frame,
* since the NONCLIENTMETRICS structure does not distinguish between them
*/
int frame_size = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
/* The diagonal size handles are wider than the frame */
// The diagonal size handles are wider than the frame
int diagonal_width = frame_size * 2 + GetSystemMetrics(SM_CXBORDER);
bool top = ptMouse.y >= rcWindow.top && ptMouse.y < rcWindow.top + frame_size;
@ -78,105 +74,82 @@ LRESULT HandleHitTest(WindowWrapper *wrapper, int x, int y)
bool diag_left = ptMouse.x >= rcWindow.left && ptMouse.x < rcWindow.left + frame_size;
bool diag_right = !diag_left && (ptMouse.x < rcWindow.right && ptMouse.x >= rcWindow.right - diagonal_width);
if (top)
uRow = 0;
if (bottom)
uRow = 2;
if (top || bottom)
{
if (diag_left)
uCol = 0;
else if (diag_right)
uCol = 2;
}
else
{
if (left)
uCol = 0;
if (right)
uCol = 2;
if (left || right)
{
if (diag_top)
uRow = 0;
else if (diag_bottom)
uRow = 2;
if (top) uRow = 0;
if (bottom) uRow = 2;
if (top || bottom) {
if (diag_left) uCol = 0;
else if (diag_right) uCol = 2;
} else {
if (left) uCol = 0;
if (right) uCol = 2;
if (left || right) {
if (diag_top) uRow = 0;
else if (diag_bottom) uRow = 2;
}
}
}
// Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
LRESULT hitTests[3][3] = { { HTTOPLEFT,
HTTOP,
HTTOPRIGHT },
{ HTLEFT,
HTNOWHERE,
HTRIGHT },
{ HTBOTTOMLEFT,
HTBOTTOM,
HTBOTTOMRIGHT } };
// @formatter:off
LRESULT hitTests[3][3] = { { HTTOPLEFT, HTTOP, HTTOPRIGHT },
{ HTLEFT, HTNOWHERE, HTRIGHT },
{ HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT } };
LRESULT hit = hitTests[uRow][uCol];
if (hit == HTNOWHERE || !wrapper->resizable)
{
if (hit == HTNOWHERE || !wrapper->resizable) {
//Handle window drag.
if (ptMouse.y < rcWindow.top + wrapper->title_height && ptMouse.x >= rcWindow.left + wrapper->left
&& ptMouse.x <= rcWindow.right - wrapper->right)
{
if (ptMouse.y < rcWindow.top + wrapper->title_height
&& ptMouse.x >= rcWindow.left + wrapper->left
&& ptMouse.x <= rcWindow.right - wrapper->right) {
return HTCAPTION;
}
return HTCLIENT;
}
else
{
} else {
return hit;
}
// @formatter:on
}
void UpdateRegion(WindowWrapper *wrapper)
{
if (wrapper->popup_menu)
return;
void UpdateRegion(WindowWrapper *wrapper) {
if (wrapper->popup_menu) return;
RECT old_rgn = wrapper->rgn;
if (Maximized(wrapper->window))
{
if (Maximized(wrapper->window)) {
WINDOWINFO wi;
wi.cbSize = sizeof(WINDOWINFO);
GetWindowInfo(wrapper->window, &wi);
/* For maximized windows, a region is needed to cut off the non-client
borders that hang over the edge of the screen */
/*
* For maximized windows, a region is needed to cut off the non-client
* borders that hang over the edge of the screen
*/
wrapper->rgn.left = wi.rcClient.left - wi.rcWindow.left;
wrapper->rgn.top = wi.rcClient.top - wi.rcWindow.top;
wrapper->rgn.right = wi.rcClient.right - wi.rcWindow.left;
wrapper->rgn.bottom = wi.rcClient.bottom - wi.rcWindow.top;
}
else
{
/* Don't mess with the region when composition is enabled and the
window is not maximized, otherwise it will lose its shadow */
} else {
/*
* Don't mess with the region when composition is enabled and the
* window is not maximized, otherwise it will lose its shadow
*/
wrapper->rgn.left = 0;
wrapper->rgn.top = 0;
wrapper->rgn.right = 0;
wrapper->rgn.bottom = 0;
}
/* Avoid unnecessarily updating the region to avoid unnecessary redraws */
if (EqualRect(&wrapper->rgn, &old_rgn))
return;
/* Treat empty regions as NULL regions */
// Avoid unnecessarily updating the region to avoid unnecessary redraws
if (EqualRect(&wrapper->rgn, &old_rgn)) return;
// Treat empty regions as NULL regions
RECT empty = { 0 };
if (EqualRect(&wrapper->rgn, &empty))
SetWindowRgn(wrapper->window, NULL, TRUE);
else
SetWindowRgn(wrapper->window, CreateRectRgnIndirect(&wrapper->rgn), TRUE);
if (EqualRect(&wrapper->rgn, &empty)) SetWindowRgn(wrapper->window, NULL, TRUE);
else SetWindowRgn(wrapper->window, CreateRectRgnIndirect(&wrapper->rgn), TRUE);
}
bool AutoHideTaskbar(UINT edge, RECT mon)
{
bool AutoHideTaskbar(UINT edge, RECT mon) {
APPBARDATA data;
data.cbSize = sizeof(APPBARDATA);
data.uEdge = edge;
@ -184,47 +157,47 @@ bool AutoHideTaskbar(UINT edge, RECT mon)
return SHAppBarMessage(ABM_GETAUTOHIDEBAREX, &data);
}
void AdjustMaximizedClientArea(HWND window, RECT &rect)
{
if (!Maximized(window))
return;
void AdjustMaximizedClientArea(HWND window, RECT &rect) {
if (!Maximized(window)) return;
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
if (!monitor)
return;
if (!monitor) return;
MONITORINFO monitor_info {};
monitor_info.cbSize = sizeof(MONITORINFO);
if (!GetMonitorInfo(monitor, &monitor_info))
return;
if (!GetMonitorInfo(monitor, &monitor_info)) return;
rect = monitor_info.rcWork;
}
void HandleNCCalcSize(WindowWrapper *wrapper, WPARAM wparam, LPARAM lparam)
{
union
{
/**
* Adjust the maximized frame size to respect auto hiding taskbars.
*/
void HandleNCCalcSize(WindowWrapper *wrapper, WPARAM wparam, LPARAM lparam) {
union {
LPARAM lparam;
RECT *rect;
} params;
params.lparam = lparam;
/* DefWindowProc must be called in both the maximized and non-maximized
cases, otherwise tile/cascade windows won't work */
/*
* DefWindowProc must be called in both the maximized and non-maximized
* cases, otherwise tile/cascade windows won't work
*/
RECT nonclient = *params.rect;
DefWindowProc(wrapper->window, WM_NCCALCSIZE, wparam, lparam);
RECT client = *params.rect;
if (Maximized(wrapper->window))
{
if (Maximized(wrapper->window)) {
WINDOWINFO wi;
wi.cbSize = sizeof(wi);
GetWindowInfo(wrapper->window, &wi);
/* Maximized windows always have a non-client border that hangs over
the edge of the screen, so the size proposed by WM_NCCALCSIZE is
fine. Just adjust the top border to remove the window title. */
/*
* Maximized windows always have a non-client border that hangs over
* the edge of the screen, so the size proposed by WM_NCCALCSIZE is
* fine. Just adjust the top border to remove the window title.
*/
(*params.rect).left = client.left;
(*params.rect).top = nonclient.top + wi.cyWindowBorders;
(*params.rect).right = client.right;
@ -244,29 +217,23 @@ void HandleNCCalcSize(WindowWrapper *wrapper, WPARAM wparam, LPARAM lparam)
* of the monitor is likely to contain an auto-hide appbar, so the
* missing client area is covered by it.
*/
if (EqualRect(params.rect, &mi.rcMonitor))
{
if (AutoHideTaskbar(ABE_BOTTOM, mi.rcMonitor))
params.rect->bottom--;
else if (AutoHideTaskbar(ABE_LEFT, mi.rcMonitor))
params.rect->left++;
else if (AutoHideTaskbar(ABE_TOP, mi.rcMonitor))
params.rect->top++;
else if (AutoHideTaskbar(ABE_RIGHT, mi.rcMonitor))
params.rect->right--;
}
if (EqualRect(params.rect, &mi.rcMonitor)) {
if (AutoHideTaskbar(ABE_BOTTOM, mi.rcMonitor)) params.rect->bottom--;
else if (AutoHideTaskbar(ABE_LEFT, mi.rcMonitor)) params.rect->left++;
else if (AutoHideTaskbar(ABE_TOP, mi.rcMonitor)) params.rect->top++;
else if (AutoHideTaskbar(ABE_RIGHT, mi.rcMonitor)) params.rect->right--;
}
else
{
/* For the non-maximized case, set the output RECT to what it was
before WM_NCCALCSIZE modified it. This will make the client size the
same as the non-client size. */
} else {
/*
* For the non-maximized case, set the output RECT to what it was
* before WM_NCCALCSIZE modified it. This will make the client size the
* same as the non-client size.
*/
*params.rect = nonclient;
}
}
void HandleWindowPosChanged(WindowWrapper *wrapper, const WINDOWPOS *pos)
{
void HandleWindowPosChanged(WindowWrapper *wrapper, const WINDOWPOS *pos) {
RECT client;
GetClientRect(wrapper->window, &client);
LONG old_width = wrapper->width;
@ -275,37 +242,78 @@ void HandleWindowPosChanged(WindowWrapper *wrapper, const WINDOWPOS *pos)
wrapper->height = client.bottom;
bool client_changed = wrapper->width != old_width || wrapper->height != old_height;
if (client_changed || (pos->flags & SWP_FRAMECHANGED))
UpdateRegion(wrapper);
if (client_changed || (pos->flags & SWP_FRAMECHANGED)) UpdateRegion(wrapper);
}
void PaintBackground(HWND hwnd, WPARAM wParam, WindowWrapper *wrapper)
{
void PaintBackground(HWND hwnd, WPARAM wParam, WindowWrapper *wrapper) {
HDC hdc = reinterpret_cast<HDC>(wParam);
RECT clientRect;
GetClientRect(hwnd, &clientRect);
FillRect(hdc, &clientRect, wrapper->bgBrush);
}
LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
/**
* Extend the client area into the frame. Leaves a the margin at the top to make sure windows still recognizes the
* window to have a size frame. Otherwise no shadow is drawn.
*/
void ExtendClientFrame(HWND handle) {
MARGINS margins = { 0, 0, 1, 0 };
DwmExtendFrameIntoClientArea(handle, &margins);
}
/**
* Make sure windows recognizes the window to be resizable. Necessary for shadows and aero-snap.
*/
void SetupWindowStyle(HWND handle, bool is_popup) {
auto style = GetWindowLongPtr(handle, GWL_STYLE);
style |= WS_THICKFRAME;
SetWindowLongPtr(handle, GWL_STYLE, style);
}
bool InstallDecorations(HWND handle, bool is_popup) {
// Prevent multiple installations overriding the real window procedure.
auto it = wrapper_map.find(handle);
if (it != wrapper_map.end()) return false;
SetupWindowStyle(handle, is_popup);
ExtendClientFrame(handle);
WNDPROC proc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(handle, GWLP_WNDPROC));
WindowWrapper *wrapper = new WindowWrapper();
wrapper->window = handle;
wrapper->prev_proc = proc;
wrapper->popup_menu = is_popup;
wrapper_map[handle] = wrapper;
// Update the window procedure with our custom procedure.
SetWindowLongPtr(handle, GWLP_WNDPROC, (LONG_PTR) WindowWrapper::WindowProc);
UINT flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
SetWindowPos(handle, NULL, 0, 0, 0, 0, flags);
return true;
}
// @formatter:off
LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrapper = wrapper_map[handle];
switch(uMsg)
{
switch (uMsg) {
case WM_NCACTIVATE:
// Prevents window flickering when being blocked by dialogs or when activating.
return TRUE;
case WM_NCCALCSIZE:
if (wParam == TRUE)
{
// If wParam is TRUE return 0 to signify the whole frame is the client area.
if (wParam == TRUE) {
// Adjust the maximized frame size to respect auto hiding taskbars.
HandleNCCalcSize(wrapper, wParam, lParam);
UpdateRegion(wrapper);
// Cut off unnecessary part of the window region (e.g. in maximized state)
UpdateRegion wrapper);
return 0;
}
break;
case WM_NCHITTEST:
return HandleHitTest(wrapper, GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
return HandleHitTest(wrapper, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
case WM_MOVE:
wrapper->moving = wrapper->move_mode;
break;
@ -318,47 +326,44 @@ LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_
break;
case WM_ERASEBKGND:
case WM_PAINT:
if (!wrapper->bgBrush)
break;
if (!wrapper->moving || wrapper->popup_menu)
if (!wrapper->bgBrush) break;
if (!wrapper->moving || wrapper->popup_menu) {
// Don't paint the background if the window is moving to avoid teared graphics on the window edge.
PaintBackground(hwnd, wParam, wrapper);
if (uMsg == WM_ERASEBKGND)
return TRUE;
}
if (uMsg == WM_ERASEBKGND) return TRUE;
break;
case WM_NCUAHDRAWCAPTION:
case WM_NCUAHDRAWFRAME:
/* These undocumented messages are sent to draw themed window borders.
Block them to prevent drawing borders over the client area. */
/*
* These undocumented messages are sent to draw themed window borders.
* Block them to prevent drawing borders over the client area.
*/
return 0;
case WM_WINDOWPOSCHANGED:
HandleWindowPosChanged(wrapper, (WINDOWPOS*)lParam);
// Update window region if necessary.
HandleWindowPosChanged(wrapper, (WINDOWPOS*) lParam);
break;
default:
break;
}
return CallWindowProc(wrapper->prev_proc, hwnd, uMsg, wParam, lParam);
}
// @formatter:on
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_setResizable(JNIEnv *env, jclass obj, jlong hwnd, jboolean res)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_setResizable(JNIEnv *env, jclass obj, jlong hwnd, jboolean res) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle];
if (wrap)
{
if (wrap) {
wrap->resizable = res;
}
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_updateValues(JNIEnv *env, jclass obj, jlong hwnd,
jint l, jint r, jint h)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_updateValues(JNIEnv *env, jclass obj, jlong hwnd, jint l, jint r, jint h) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle];
if (wrap)
{
if (wrap) {
wrap->left = l;
wrap->right = r;
wrap->title_height = h;
@ -366,69 +371,25 @@ Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_updateValue
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_setBackground(JNIEnv *env, jclass obj, jlong hwnd, jint r, jint g, jint b)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_setBackground(JNIEnv *env, jclass obj, jlong hwnd, jint r, jint g, jint b) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle];
if (wrap)
{
if (wrap) {
wrap->bgBrush = CreateSolidBrush(RGB(r, g, b));
}
}
void ExtendClientFrame(HWND handle)
{
MARGINS margins = { 0,
0,
1,
0 };
DwmExtendFrameIntoClientArea(handle, &margins);
}
void SetupWindowStyle(HWND handle, bool is_popup)
{
auto style = GetWindowLongPtr(handle, GWL_STYLE);
style |= WS_THICKFRAME;
SetWindowLongPtr(handle, GWL_STYLE, style);
}
bool InstallDecorations(HWND handle, bool is_popup)
{
//Prevent multiple installations overriding the real window procedure.
auto it = wrapper_map.find(handle);
if (it != wrapper_map.end())
return false;
SetupWindowStyle(handle, is_popup);
ExtendClientFrame(handle);
WNDPROC proc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(handle, GWLP_WNDPROC));
WindowWrapper *wrapper = new WindowWrapper();
wrapper->window = handle;
wrapper->prev_proc = proc;
wrapper->popup_menu = is_popup;
wrapper_map[handle] = wrapper;
SetWindowLongPtr(handle, GWLP_WNDPROC, (LONG_PTR) WindowWrapper::WindowProc);
UINT flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
SetWindowPos(handle, NULL, 0, 0, 0, 0, flags);
return true;
}
JNIEXPORT jboolean JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installDecorations(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
return (jboolean) InstallDecorations(handle, false);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_uninstallDecorations(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_uninstallDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle];
if (wrap)
{
if (wrap) {
SetWindowLongPtr(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wrap->prev_proc));
wrapper_map.erase(handle);
delete (wrap);
@ -436,8 +397,7 @@ Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_uninstallDe
}
JNIEXPORT jboolean JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installPopupMenuDecorations(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installPopupMenuDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
return (jboolean) InstallDecorations(handle, true);
}
@ -445,22 +405,19 @@ Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installPopu
//Window functions.
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_minimize(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_minimize(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
ShowWindow(handle, SW_MINIMIZE);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_maximize(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_maximize(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
ShowWindow(handle, SW_MAXIMIZE);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_restore(JNIEnv *env, jclass obj, jlong hwnd)
{
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_restore(JNIEnv *env, jclass obj, jlong hwnd) {
HWND handle = reinterpret_cast<HWND>(hwnd);
ShowWindow(handle, SW_RESTORE);
}

9
windows/src/main/cpp/Decorations.h

@ -31,23 +31,28 @@
#include <shellapi.h>
#include <winuser.h>
class WindowWrapper
{
class WindowWrapper {
public:
bool resizable = true;
bool popup_menu = false;
bool moving = false;
bool move_mode = false;
bool maximized = false;
// The original window procedure.
WNDPROC prev_proc;
// The background brush.
HBRUSH bgBrush;
HWND window;
int width;
int height;
// The window region.
RECT rgn;
// The insets for the title bar area that is draggable.
int left = 0;
int right = 0;
int title_height = 0;

116
windows/src/main/cpp/ThemeInfo.cpp

@ -50,8 +50,7 @@
#define FONT_SCALE_DEFAULT_VALUE 100
#define ACCENT_COLOR_DEFAULT_VALUE 0
void ModifyFlags(DWORD &flags)
{
void ModifyFlags(DWORD &flags) {
#ifdef _WIN64
flags |= RRF_SUBKEY_WOW6464KEY;
#else
@ -59,105 +58,84 @@ void ModifyFlags(DWORD &flags)
#endif
}
DWORD RegGetDword(HKEY hKey, const LPCSTR subKey, const LPCSTR value)
{
DWORD RegGetDword(HKEY hKey, const LPCSTR subKey, const LPCSTR value) {
DWORD data {};
DWORD dataSize = sizeof(data);
DWORD flags = RRF_RT_REG_DWORD;
ModifyFlags(flags);
LONG retCode = ::RegGetValue(hKey, subKey, value, flags, nullptr, &data, &dataSize);
if (retCode != ERROR_SUCCESS)
throw retCode;
if (retCode != ERROR_SUCCESS) throw retCode;
return data;
}
std::string RegGetString(HKEY hKey, const LPCSTR subKey, const LPCSTR value)
{
std::string RegGetString(HKEY hKey, const LPCSTR subKey, const LPCSTR value) {
DWORD dataSize {};
DWORD flags = RRF_RT_REG_SZ;
ModifyFlags(flags);
LONG retCode = ::RegGetValue(hKey, subKey, value, flags, nullptr, nullptr, &dataSize);
if (retCode != ERROR_SUCCESS)
throw retCode;
if (retCode != ERROR_SUCCESS) throw retCode;
std::string data;
DWORD stringLengthInChars = dataSize / sizeof(char);
data.resize(stringLengthInChars);
retCode = ::RegGetValue(hKey, subKey, value, flags, nullptr, &data[0], &dataSize);
if (retCode != ERROR_SUCCESS)
throw retCode;
if (retCode != ERROR_SUCCESS) throw retCode;
return data;
}
bool IsHighContrastMode()
{
bool IsHighContrastMode() {
HIGHCONTRAST info = { 0 };
info.cbSize = sizeof(HIGHCONTRAST);
BOOL ok = SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &info, 0);
if (ok)
{
if (ok) {
return info.dwFlags & HCF_HIGHCONTRASTON;
}
return HIGH_CONTRAST_DEFAULT_VALUE;
}
bool IsDarkMode()
{
try
{
bool IsDarkMode() {
try {
bool appsUseDark = (0 == RegGetDword(HKEY_CURRENT_USER, DARK_MODE_PATH,
DARK_MODE_KEY));
bool isHighContrast = IsHighContrastMode();
if (!isHighContrast)
return appsUseDark;
if (!isHighContrast) return appsUseDark;
std::string themeValue = RegGetString(HKEY_CURRENT_USER,
HIGH_CONTRAST_PATH, HIGH_CONTRAST_THEME_KEY);
return (strcmp(themeValue.c_str(), HIGH_CONTRAST_LIGHT_THEME) != 0);
} catch (LONG e)
{
} catch (LONG e) {
return DARK_MODE_DEFAULT_VALUE;
}
}
unsigned int GetTextScaleFactor()
{
try
{
unsigned int GetTextScaleFactor() {
try {
return RegGetDword(HKEY_CURRENT_USER, FONT_SCALE_PATH, FONT_SCALE_KEY);
} catch (LONG e)
{
} catch (LONG e) {
return FONT_SCALE_DEFAULT_VALUE;
}
}
bool RegisterRegistryEvent(const LPCSTR subKey, HANDLE event)
{
bool RegisterRegistryEvent(const LPCSTR subKey, HANDLE event) {
HKEY hKey;
REGSAM flags = KEY_NOTIFY;
ModifyFlags(flags);
DWORD res = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, flags, &hKey);
if (res == ERROR_SUCCESS)
{
if (res == ERROR_SUCCESS) {
LSTATUS status = RegNotifyChangeKeyValue(hKey, FALSE, REG_NOTIFY_CHANGE_LAST_SET, event, TRUE);
return status == ERROR_SUCCESS;
}
else
{
} else {
return FALSE;
}
}
int GetAccentColor()
{
try
{
int GetAccentColor() {
try {
return RegGetDword(HKEY_CURRENT_USER, ACCENT_COLOR_PATH,
ACCENT_COLOR_KEY);
} catch (LONG e)
{
} catch (LONG e) {
return ACCENT_COLOR_DEFAULT_VALUE;
}
}
@ -186,8 +164,7 @@ Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_getAccentColo
return (jint) GetAccentColor();
}
struct EventHandler
{
struct EventHandler {
JavaVM *jvm;
JNIEnv *env;
jobject callback;
@ -195,48 +172,33 @@ struct EventHandler
std::thread notificationLoop;
std::atomic<bool> running = FALSE;
void runCallBack()
{
void runCallBack() {
jclass runnableClass = env->GetObjectClass(callback);
jmethodID runMethodId = env->GetMethodID(runnableClass, "run", "()V");
if (runMethodId)
{
if (runMethodId) {
env->CallVoidMethod(callback, runMethodId);
}
}
bool awaitPreferenceChange()
{
if (!RegisterRegistryEvent(FONT_SCALE_PATH, eventHandle))
return FALSE;
if (!RegisterRegistryEvent(DARK_MODE_PATH, eventHandle))
return FALSE;
if (!RegisterRegistryEvent(HIGH_CONTRAST_PATH, eventHandle))
return FALSE;
if (!RegisterRegistryEvent(ACCENT_COLOR_PATH, eventHandle))
return FALSE;
bool awaitPreferenceChange() {
if (!RegisterRegistryEvent(FONT_SCALE_PATH, eventHandle)) return FALSE;
if (!RegisterRegistryEvent(DARK_MODE_PATH, eventHandle)) return FALSE;
if (!RegisterRegistryEvent(HIGH_CONTRAST_PATH, eventHandle)) return FALSE;
if (!RegisterRegistryEvent(ACCENT_COLOR_PATH, eventHandle)) return FALSE;
return WaitForSingleObject(eventHandle, INFINITE) != WAIT_FAILED;
}
void run()
{
void run() {
int getEnvStat = jvm->GetEnv((void**) &env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED)
{
if (jvm->AttachCurrentThread((void**) &env, NULL) != 0)
if (getEnvStat == JNI_EDETACHED) {
if (jvm->AttachCurrentThread((void**) &env, NULL) != 0) return;
} else if (getEnvStat == JNI_EVERSION) {
return;
}
else if (getEnvStat == JNI_EVERSION)
{
return;
}
while (running && awaitPreferenceChange())
{
if (running)
{
while (running && awaitPreferenceChange()) {
if (running) {
runCallBack();
if (env->ExceptionCheck())
{
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
break;
}
@ -245,15 +207,13 @@ struct EventHandler
jvm->DetachCurrentThread();
}
void stop()
{
void stop() {
running = FALSE;
SetEvent(eventHandle);
notificationLoop.join();
}
EventHandler(JavaVM *jvm_, jobject callback_, HANDLE eventHandle_)
{
EventHandler(JavaVM *jvm_, jobject callback_, HANDLE eventHandle_) {
jvm = jvm_;
callback = callback_;
eventHandle = eventHandle_;

Loading…
Cancel
Save