wrap win32 usage in conditionals
This commit is contained in:
115
src/gui_2.py
115
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
|
||||
|
||||
Reference in New Issue
Block a user