diff --git a/manualslop_layout.ini b/manualslop_layout.ini index 521a48a..64a82a6 100644 --- a/manualslop_layout.ini +++ b/manualslop_layout.ini @@ -74,8 +74,8 @@ Collapsed=0 DockId=0xAFC85805,2 [Window][Theme] -Pos=0,542 -Size=310,658 +Pos=0,495 +Size=547,737 Collapsed=0 DockId=0x00000002,2 @@ -91,8 +91,8 @@ Collapsed=0 DockId=0x00000010,2 [Window][Context Hub] -Pos=0,542 -Size=310,658 +Pos=0,495 +Size=547,737 Collapsed=0 DockId=0x00000002,1 @@ -103,26 +103,26 @@ Collapsed=0 DockId=0x0000000D,0 [Window][Discussion Hub] -Pos=649,24 -Size=449,1176 +Pos=886,24 +Size=449,1208 Collapsed=0 DockId=0x00000013,0 [Window][Operations Hub] -Pos=312,24 -Size=335,1176 +Pos=549,24 +Size=335,1208 Collapsed=0 DockId=0x00000005,0 [Window][Files & Media] -Pos=0,542 -Size=310,658 +Pos=0,495 +Size=547,737 Collapsed=0 DockId=0x00000002,0 [Window][AI Settings] Pos=0,24 -Size=310,516 +Size=547,469 Collapsed=0 DockId=0x00000001,0 @@ -132,14 +132,14 @@ Size=416,325 Collapsed=0 [Window][MMA Dashboard] -Pos=1100,24 -Size=580,1176 +Pos=1337,24 +Size=580,1208 Collapsed=0 DockId=0x00000010,0 [Window][Log Management] -Pos=1100,24 -Size=580,1176 +Pos=1337,24 +Size=580,1208 Collapsed=0 DockId=0x00000010,1 @@ -498,12 +498,12 @@ Column 1 Weight=1.0000 DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02 -DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,24 Size=1680,1176 Split=X +DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,24 Size=1917,1208 Split=X DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=1647,1183 Split=X DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2 DockNode ID=0x00000007 Parent=0x0000000B SizeRef=310,858 Split=Y Selected=0x8CA2375C - DockNode ID=0x00000001 Parent=0x00000007 SizeRef=824,624 CentralNode=1 Selected=0x7BD57D6A - DockNode ID=0x00000002 Parent=0x00000007 SizeRef=824,658 Selected=0xF4139CA2 + DockNode ID=0x00000001 Parent=0x00000007 SizeRef=824,525 CentralNode=1 Selected=0x7BD57D6A + DockNode ID=0x00000002 Parent=0x00000007 SizeRef=824,737 Selected=0x8CA2375C DockNode ID=0x0000000E Parent=0x0000000B SizeRef=786,858 Split=X Selected=0x418C7449 DockNode ID=0x00000012 Parent=0x0000000E SizeRef=335,402 Split=Y Selected=0x418C7449 DockNode ID=0x00000005 Parent=0x00000012 SizeRef=876,1749 Selected=0x418C7449 diff --git a/src/gui_2.py b/src/gui_2.py index 6d8bc9b..657068a 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -29,8 +29,12 @@ from src import mcp_client from src import markdown_helper from src import bg_shader import re -import win32gui -import win32con +if sys.platform == "win32": + import win32gui + import win32con +else: + win32gui = None + win32con = None from pydantic import BaseModel from imgui_bundle import imgui, hello_imgui, immapp, imgui_node_editor as ed @@ -368,58 +372,59 @@ class App: self.ai_status = f"error: {e}" imgui.end_menu() - # Draw right-aligned window controls directly in the menu bar - try: - import ctypes - ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p - ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] - hwnd_capsule = imgui.get_main_viewport().platform_handle_raw - hwnd = ctypes.pythonapi.PyCapsule_GetPointer(hwnd_capsule, b"nb_handle") - except Exception: - hwnd = 0 - - if hwnd: - btn_w = 40 - display_w = imgui.get_io().display_size.x - right_x = display_w - (btn_w * 3) - - # Drag area check using an explicit invisible button spanning the empty space - curr_x = imgui.get_cursor_pos_x() - drag_w = right_x - curr_x - if drag_w > 0: - # Use a small positive height to satisfy IM_ASSERT(size_arg.y != 0.0f) - # The menu bar naturally constrains the hit box height anyway. - imgui.invisible_button("##drag_area", (drag_w, 20.0)) - if imgui.is_item_active() and imgui.is_mouse_dragging(0): - # CRITICAL: We must reset ImGui's mouse_down state BEFORE passing control to Windows. - # Otherwise, the Windows modal drag loop swallows the WM_LBUTTONUP event, - # and ImGui thinks the mouse is permanently held down, causing "sticky" dragging. - imgui.get_io().mouse_down[0] = False - win32gui.ReleaseCapture() - win32gui.SendMessage(hwnd, win32con.WM_NCLBUTTONDOWN, win32con.HTCAPTION, 0) - - imgui.push_style_color(imgui.Col_.button, vec4(0, 0, 0, 0)) - + # Draw right-aligned window controls directly in the menu bar (Win32 only) + if sys.platform == "win32": try: - is_max = win32gui.GetWindowPlacement(hwnd)[1] == win32con.SW_SHOWMAXIMIZED + import ctypes + ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p + ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] + hwnd_capsule = imgui.get_main_viewport().platform_handle_raw + hwnd = ctypes.pythonapi.PyCapsule_GetPointer(hwnd_capsule, b"nb_handle") except Exception: - is_max = False - - imgui.set_cursor_pos_x(right_x) - if imgui.button("_", (btn_w, 0)): - win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE) + hwnd = 0 + + if hwnd: + btn_w = 40 + display_w = imgui.get_io().display_size.x + right_x = display_w - (btn_w * 3) - imgui.set_cursor_pos_x(right_x + btn_w) - if imgui.button("[=]" if is_max else "[]", (btn_w, 0)): - win32gui.ShowWindow(hwnd, win32con.SW_RESTORE if is_max else win32con.SW_MAXIMIZE) - - imgui.set_cursor_pos_x(right_x + btn_w * 2) - imgui.push_style_color(imgui.Col_.button_hovered, vec4(200, 50, 50, 255)) - if imgui.button("X", (btn_w, 0)): - win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0) - imgui.pop_style_color() - - imgui.pop_style_color() + # Drag area check using an explicit invisible button spanning the empty space + curr_x = imgui.get_cursor_pos_x() + drag_w = right_x - curr_x + if drag_w > 0: + # Use a small positive height to satisfy IM_ASSERT(size_arg.y != 0.0f) + # The menu bar naturally constrains the hit box height anyway. + imgui.invisible_button("##drag_area", (drag_w, 20.0)) + if imgui.is_item_active() and imgui.is_mouse_dragging(0): + # CRITICAL: We must reset ImGui's mouse_down state BEFORE passing control to Windows. + # Otherwise, the Windows modal drag loop swallows the WM_LBUTTONUP event, + # and ImGui thinks the mouse is permanently held down, causing "sticky" dragging. + imgui.get_io().mouse_down[0] = False + win32gui.ReleaseCapture() + win32gui.SendMessage(hwnd, win32con.WM_NCLBUTTONDOWN, win32con.HTCAPTION, 0) + + imgui.push_style_color(imgui.Col_.button, vec4(0, 0, 0, 0)) + + try: + is_max = win32gui.GetWindowPlacement(hwnd)[1] == win32con.SW_SHOWMAXIMIZED + except Exception: + is_max = False + + imgui.set_cursor_pos_x(right_x) + if imgui.button("_", (btn_w, 0)): + win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE) + + imgui.set_cursor_pos_x(right_x + btn_w) + if imgui.button("[=]" if is_max else "[]", (btn_w, 0)): + win32gui.ShowWindow(hwnd, win32con.SW_RESTORE if is_max else win32con.SW_MAXIMIZE) + + imgui.set_cursor_pos_x(right_x + btn_w * 2) + imgui.push_style_color(imgui.Col_.button_hovered, vec4(200, 50, 50, 255)) + if imgui.button("X", (btn_w, 0)): + win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0) + imgui.pop_style_color() + + imgui.pop_style_color() def _render_custom_title_bar(self) -> None: # Obsolete, removed since it renders behind the full screen dock space. @@ -4002,7 +4007,13 @@ def hello(): theme.load_from_config(self.config) self.runner_params = hello_imgui.RunnerParams() self.runner_params.app_window_params.window_title = "manual slop" - self.runner_params.app_window_params.borderless = True + + if sys.platform == "win32": + self.runner_params.app_window_params.borderless = True + self.runner_params.app_window_params.borderless_closable = False + self.runner_params.app_window_params.borderless_movable = False + self.runner_params.app_window_params.borderless_resizable = True + self.runner_params.app_window_params.window_geometry.size = (1680, 1200) self.runner_params.imgui_window_params.enable_viewports = getattr(self, "ui_multi_viewport", False) self.runner_params.imgui_window_params.remember_theme = True