From 3cd75d97f6ccfcef4c12c1f43940c6a19fe4af77 Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Mon, 24 Nov 2025 07:12:47 +0100 Subject: [PATCH] windows fixes --- icon.ico | Bin 0 -> 4286 bytes main.py | 178 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 103 insertions(+), 75 deletions(-) create mode 100644 icon.ico diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d7b6ba6df5aa3f89a35f2f82edb13271144c497f GIT binary patch literal 4286 zcmeHJYbfnm6yL{N%DeGs;$Re!VT^Y|n9MD!k z{N!>*U-peXWA8A={6Lsu@gSPlHmp6hCl5S%z+ey9f+H5>F6B&5PiOY__K{9bPM^zU zGC4?GHo+hUlm@aECynW6XJ=VdR8(zKQ`29*zP@9SVJVSgQ&v{?ysxj1J32acW@ctG zQ&Uq~_9-qdJ}WFNd}U%{l4fCHAz?9W$T??ud3ox~%S)b-k+BPIDT+9BcX$7^xw*;R z-Q9<1uTFnxe}Dh=-rgP$3=Djho11HxQps+T84?nrJ~}$$4Gj%?{W@Q}tJUh$jg1ZN z;^OjEO-+r+DK97}xX@@cJSi#ZTTGgX3x@Wj-`m?;O|~eN%KQ4|uv4?OwZ%O=Jd_Cu z38HxO?Ck9C&d<+ze0=R47*RtecsQBiRX)gMUpcXoDa&d$y_Z2#HD#-*|yYiq0K?(U9L ztj*2M@$vC-esOWZ5flI5?l-YDSb_`0YEZ-Z8DcAaeSQ75y}exka|#Ktva+I1J~=t5 zSzBA<)z#H6$HvC4XJ%$@dV6~>6B83#u8XHzp`)XN^nXl(92^`N z{4Ix%H6tS<98+HdYu*Ree2Cr${|N&h-4IvI+1XjKxVR{cj*bfOWh&vBX#dpIlxBK* znp<02D}lq0)^}fk4$oo-2M1rStgLWXSJzLFYx?`A{D*J2o12?5A|m2G`s>Jy>-G?I2ZV2aqMMc5E!J>RKNOLX?>LhXBS8Zj|e&qsgfCFPfX1Z_CTeg_f2U0k+=~{t?a% z3=G^M4_|e4bzK8{eyy#oJuN9I*+sqEQ79BUsCUn!qoXPJ?F_B^q#yZ~tWv3793LOw zo}8Qr`}_OC!oq?8ToWcHCJ0jn;Qil}3%k3!{NUh#pPrs-&qik?LQN7ZEiE&F4-d9o zve6uGs_@v@*wmDi6a{ihfwzqUb%pXi73WjHN4dzua=eEcgMxxoh(9&#R-@*Pq@|_( z;OFN@xEq4Il8Ak4LwX-kfEpD8Z|#&%ik>_G58$o%`lfPK@^(GNVGMd#*E94?3F5q6 X2J-wbed)<>m?=o6C(eI=t)71YEO-%{ literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 90de87a..0706187 100644 --- a/main.py +++ b/main.py @@ -518,13 +518,15 @@ class IRCPanel(wx.Panel): sizer = wx.BoxSizer(wx.VERTICAL) - # Use a better font for chat + # Use a better font for chat with white theme self.text_ctrl = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_AUTO_URL) - self.text_ctrl.SetBackgroundColour(wx.Colour(30, 30, 30)) - self.text_ctrl.SetForegroundColour(wx.Colour(220, 220, 220)) - # Load Fira Code font - self.font = self.load_fira_code_font() + # White theme colors + self.text_ctrl.SetBackgroundColour(wx.Colour(255, 255, 255)) # White background + self.text_ctrl.SetForegroundColour(wx.Colour(0, 0, 0)) # Black text + + # Load appropriate font + self.font = self.load_system_font() self.text_ctrl.SetFont(self.font) sizer.Add(self.text_ctrl, 1, wx.EXPAND | wx.ALL, 0) @@ -560,39 +562,46 @@ class IRCPanel(wx.Panel): self.SetAcceleratorTable(accel_tbl) self.Bind(wx.EVT_MENU, self.on_search, id=wx.ID_FIND) - def load_fira_code_font(self): - """Load Fira Code font from resources""" + def load_system_font(self): + """Load appropriate system font with high DPI support""" try: - # Try to use Fira Code if available - font_path = get_resource_path("FiraCode-Regular.ttf") + # Get system DPI scale factor + dc = wx.ClientDC(self) + dpi_scale = dc.GetPPI().GetWidth() / 96.0 # 96 is standard DPI - if os.path.exists(font_path): - # On wxPython 4.1+, we can try to add the font to the font manager - try: - font_collection = wx.private.FontCollection() - if font_collection.AddFont(font_path): - font = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, - False, "Fira Code") - if font.IsOk(): - logger.info("Successfully loaded Fira Code font") - return font - except Exception: - pass - - # Fallback: try to create font by name - font = wx.Font(wx.FontInfo(10).Family(wx.FONTFAMILY_TELETYPE).FaceName("Fira Code")) - if font.IsOk(): - logger.info("Using Fira Code font via FaceName") - return font + # Calculate base font size based on DPI + base_size = 10 + if dpi_scale > 1.5: + font_size = int(base_size * 1.5) # 150% scaling + elif dpi_scale > 1.25: + font_size = int(base_size * 1.25) # 125% scaling else: - logger.warning("FiraCode-Regular.ttf not found in resources") + font_size = base_size + + # Try system fonts in order of preference + font_families = [ + (wx.FONTFAMILY_TELETYPE, "Consolas"), + (wx.FONTFAMILY_TELETYPE, "Courier New"), + (wx.FONTFAMILY_TELETYPE, "Monaco"), + (wx.FONTFAMILY_TELETYPE, "DejaVu Sans Mono"), + (wx.FONTFAMILY_TELETYPE, "Liberation Mono"), + ] + + for family, face_name in font_families: + font = wx.Font(font_size, family, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, face_name) + if font.IsOk(): + logger.info(f"Using font: {face_name} at {font_size}pt") + return font + + # Fallback to default monospace + font = wx.Font(font_size, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) + logger.info("Using system monospace font as fallback") + return font + except Exception as e: - logger.error(f"Error loading Fira Code font: {e}") - - # Fall back to system monospace font - font = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) - logger.info("Using system monospace font as fallback") - return font + logger.error(f"Error loading system font: {e}") + # Ultimate fallback + return wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) def set_target(self, target): self.target = target @@ -635,7 +644,7 @@ class IRCPanel(wx.Panel): if message_color: attr.SetTextColour(message_color) else: - attr.SetTextColour(wx.Colour(220, 220, 220)) + attr.SetTextColour(wx.Colour(0, 0, 0)) # Black text for white theme attr.SetFont(self.font) self.text_ctrl.SetDefaultStyle(attr) @@ -658,10 +667,10 @@ class IRCPanel(wx.Panel): try: if is_action: message = f"{timestamp}* {username} {content}" - self.add_message(message, f"* {username}", username_color, wx.Colour(255, 150, 255), italic=True) + self.add_message(message, f"* {username}", username_color, wx.Colour(128, 0, 128), italic=True) # Dark purple for actions else: message = f"{timestamp}<{username}> {content}" - self.add_message(message, f"<{username}>", username_color, wx.Colour(220, 220, 220)) + self.add_message(message, f"<{username}>", username_color, wx.Colour(0, 0, 0)) # Black text except Exception as e: logger.error(f"Error adding formatted message: {e}") @@ -669,7 +678,7 @@ class IRCPanel(wx.Panel): """Add system message without username coloring""" try: if color is None: - color = wx.Colour(180, 180, 255) + color = wx.Colour(0, 0, 128) # Dark blue for system messages self.add_message(message, None, None, color, bold, False, False) except Exception as e: logger.error(f"Error adding system message: {e}") @@ -868,6 +877,9 @@ class IRCFrame(wx.Frame): def __init__(self): super().__init__(None, title="wxIRC", size=(1200, 700)) + # Apply white theme + self.apply_white_theme() + # Show privacy notice first self.show_privacy_notice() @@ -891,21 +903,21 @@ class IRCFrame(wx.Frame): self.away = False self.timestamps = True - # User color mapping + # User color mapping - darker colors for white theme self.user_colors = {} self.available_colors = [ - wx.Colour(255, 150, 150), # Light red - wx.Colour(150, 255, 150), # Light green - wx.Colour(150, 200, 255), # Light blue - wx.Colour(255, 255, 150), # Light yellow - wx.Colour(255, 150, 255), # Light magenta - wx.Colour(150, 255, 255), # Light cyan - wx.Colour(255, 200, 150), # Light orange - wx.Colour(200, 150, 255), # Light purple - wx.Colour(255, 200, 200), # Pink - wx.Colour(200, 255, 200), # Mint - wx.Colour(200, 200, 255), # Lavender - wx.Colour(255, 255, 200), # Cream + wx.Colour(178, 34, 34), # Firebrick red + wx.Colour(0, 100, 0), # Dark green + wx.Colour(0, 0, 139), # Dark blue + wx.Colour(139, 69, 19), # Saddle brown + wx.Colour(139, 0, 139), # Dark magenta + wx.Colour(0, 139, 139), # Dark cyan + wx.Colour(210, 105, 30), # Chocolate + wx.Colour(75, 0, 130), # Indigo + wx.Colour(178, 34, 34), # Firebrick + wx.Colour(0, 128, 128), # Teal + wx.Colour(72, 61, 139), # Dark slate blue + wx.Colour(139, 0, 0), # Dark red ] self.color_index = 0 @@ -939,6 +951,19 @@ class IRCFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.on_find_previous, id=1002) self.Bind(wx.EVT_MENU, self.on_quick_escape, id=1003) + def apply_white_theme(self): + """Apply white theme to the application""" + try: + # Set system colors for white theme + self.SetBackgroundColour(wx.Colour(255, 255, 255)) + self.SetForegroundColour(wx.Colour(0, 0, 0)) + + # Set system settings for light theme + sys_settings = wx.SystemSettings() + + except Exception as e: + logger.error(f"Error applying white theme: {e}") + def show_privacy_notice(self): """Show privacy notice dialog at startup""" dlg = PrivacyNoticeDialog(self) @@ -1002,13 +1027,14 @@ class IRCFrame(wx.Frame): return None def setup_ui(self): - """Setup UI components""" + """Setup UI components with white theme""" panel = wx.Panel(self) + panel.SetBackgroundColour(wx.Colour(255, 255, 255)) # White background main_sizer = wx.BoxSizer(wx.HORIZONTAL) - # Left sidebar + # Left sidebar - light gray for contrast left_panel = wx.Panel(panel) - left_panel.SetBackgroundColour(wx.Colour(45, 45, 45)) + left_panel.SetBackgroundColour(wx.Colour(240, 240, 240)) # Light gray left_sizer = wx.BoxSizer(wx.VERTICAL) conn_box = wx.StaticBox(left_panel, label="Connection") @@ -1068,6 +1094,7 @@ class IRCFrame(wx.Frame): # Center - Notebook self.notebook = wx.Notebook(panel) + self.notebook.SetBackgroundColour(wx.Colour(255, 255, 255)) # Server panel server_panel = IRCPanel(self.notebook, self) @@ -1075,9 +1102,9 @@ class IRCFrame(wx.Frame): self.notebook.AddPage(server_panel, "Server") self.channels["SERVER"] = server_panel - # Right sidebar - Users + # Right sidebar - Users - light gray for contrast right_panel = wx.Panel(panel) - right_panel.SetBackgroundColour(wx.Colour(45, 45, 45)) + right_panel.SetBackgroundColour(wx.Colour(240, 240, 240)) # Light gray right_sizer = wx.BoxSizer(wx.VERTICAL) users_box = wx.StaticBox(right_panel, label="Users") @@ -1232,7 +1259,7 @@ class IRCFrame(wx.Frame): if hasattr(event, 'arguments') and event.arguments: event_info += f" - {' '.join(event.arguments)}" - self.log_server(event_info, wx.Colour(180, 180, 255), italic=True) + self.log_server(event_info, wx.Colour(0, 0, 128), italic=True) # Dark blue for raw events except Exception as e: logger.error(f"Error in all_events handler: {e}") @@ -1259,19 +1286,19 @@ class IRCFrame(wx.Frame): try: self.port = int(self.port_ctrl.GetValue()) except ValueError: - self.safe_ui_update(self.log_server, "Invalid port number", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, "Invalid port number", wx.Colour(255, 0, 0)) self.is_connecting = False return self.nick = self.nick_ctrl.GetValue() if not self.server or not self.nick: - self.safe_ui_update(self.log_server, "Server and nick are required", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, "Server and nick are required", wx.Colour(255, 0, 0)) self.is_connecting = False return self.safe_ui_update(self.connect_btn.Enable, False) - self.safe_ui_update(self.log_server, f"Connecting to {self.server}:{self.port} as {self.nick}...", wx.Colour(150, 150, 255)) + self.safe_ui_update(self.log_server, f"Connecting to {self.server}:{self.port} as {self.nick}...", wx.Colour(0, 0, 128)) def connect_thread(): try: @@ -1320,7 +1347,7 @@ class IRCFrame(wx.Frame): self.reactor.process_forever() except Exception as e: logger.error(f"Reactor loop error: {e}") - self.safe_ui_update(self.log_server, f"Connection error: {e}", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, f"Connection error: {e}", wx.Colour(255, 0, 0)) self.safe_ui_update(self.on_disconnect_cleanup) def on_connect_success(self): @@ -1334,7 +1361,7 @@ class IRCFrame(wx.Frame): def on_connect_failed(self, error_msg): """Handle connection failure""" self.is_connecting = False - self.log_server(error_msg, wx.Colour(255, 100, 100)) + self.log_server(error_msg, wx.Colour(255, 0, 0)) self.connect_btn.Enable(True) self.SetStatusText("Connection failed") logger.error(f"Connection failed: {error_msg}") @@ -1376,7 +1403,7 @@ class IRCFrame(wx.Frame): self.safe_ui_update(self.connect_btn.SetLabel, "Connect") self.safe_ui_update(self.connect_btn.Enable, True) self.safe_ui_update(self.SetStatusText, "Disconnected") - self.safe_ui_update(self.log_server, "Disconnected from server", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, "Disconnected from server", wx.Colour(255, 0, 0)) def on_join_channel(self, event): try: @@ -1388,7 +1415,7 @@ class IRCFrame(wx.Frame): self.channel_input.Clear() except Exception as e: logger.error(f"Error joining channel: {e}") - self.safe_ui_update(self.log_server, f"Error joining channel: {e}", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, f"Error joining channel: {e}", wx.Colour(255, 0, 0)) def on_channel_select(self, event): try: @@ -1505,7 +1532,7 @@ class IRCFrame(wx.Frame): self.channels[target].add_formatted_message(timestamp, self.nick, message, user_color) except Exception as e: logger.error(f"Error sending message: {e}") - self.safe_ui_update(self.log_server, f"Error sending message: {e}", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, f"Error sending message: {e}", wx.Colour(255, 0, 0)) def handle_command(self, target, message): try: @@ -1528,7 +1555,7 @@ Available commands: /quit [message] - Disconnect from server /help - Show this help """ - self.log_server(help_text, wx.Colour(200, 255, 200)) + self.log_server(help_text, wx.Colour(0, 100, 0)) # Dark green for help elif cmd == "me": if self.is_connected(): self.connection.action(target, args) @@ -1568,10 +1595,10 @@ Available commands: self.away = bool(args) self.safe_ui_update(self.away_item.Check, self.away) else: - self.safe_ui_update(self.log_server, f"Unknown command: {cmd}. Use /help for available commands.", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, f"Unknown command: {cmd}. Use /help for available commands.", wx.Colour(255, 0, 0)) except Exception as e: logger.error(f"Error handling command: {e}") - self.safe_ui_update(self.log_server, f"Error executing command: {e}", wx.Colour(255, 100, 100)) + self.safe_ui_update(self.log_server, f"Error executing command: {e}", wx.Colour(255, 0, 0)) def part_channel(self, channel): try: @@ -1767,13 +1794,14 @@ COMMANDS (type /help in chat for full list): /nick newname - Change nickname /away [message] - Set away status """ - self.log_server(help_text, wx.Colour(200, 255, 200), bold=True) + self.log_server(help_text, wx.Colour(0, 100, 0), bold=True) # Dark green for help + # IRC Event Handlers - All use thread-safe UI updates def on_welcome(self, connection, event): try: - self.log_server("Connected to server!", wx.Colour(100, 255, 100), bold=True) - self.log_server(f"Welcome message: {' '.join(event.arguments)}", wx.Colour(150, 255, 150)) + self.log_server("Connected to server!", wx.Colour(0, 128, 0), bold=True) # Dark green + self.log_server(f"Welcome message: {' '.join(event.arguments)}", wx.Colour(0, 100, 0)) # Auto-join channels for channel in self.auto_join_channels: @@ -1792,7 +1820,7 @@ COMMANDS (type /help in chat for full list): if nick == self.nick: self.safe_ui_update(self.add_channel, channel) - self.log_server(f"Joined channel {channel}", wx.Colour(100, 255, 100)) + self.log_server(f"Joined channel {channel}", wx.Colour(0, 128, 0)) # Dark green self.log_channel_message(channel, nick, f"→ {nick} joined", is_system=True) @@ -1900,7 +1928,7 @@ COMMANDS (type /help in chat for full list): if old_nick == self.nick: self.nick = new_nick - self.log_server(f"You are now known as {new_nick}", wx.Colour(150, 200, 255), bold=True) + self.log_server(f"You are now known as {new_nick}", wx.Colour(0, 0, 128), bold=True) # Dark blue for channel in self.channel_users: if old_nick in self.channel_users[channel]: @@ -1928,13 +1956,13 @@ COMMANDS (type /help in chat for full list): nick = event.source.nick if hasattr(event.source, 'nick') else str(event.source) message = event.arguments[0] - self.log_server(f"-{nick}- {message}", wx.Colour(255, 150, 255), italic=True) + self.log_server(f"-{nick}- {message}", wx.Colour(128, 0, 128), italic=True) # Dark purple for notices except Exception as e: logger.error(f"Error in notice handler: {e}") def on_disconnect(self, connection, event): try: - self.log_server("Disconnected from server", wx.Colour(255, 100, 100), bold=True) + self.log_server("Disconnected from server", wx.Colour(255, 0, 0), bold=True) # Red for disconnect self.safe_ui_update(self.on_disconnect_cleanup) except Exception as e: logger.error(f"Error in disconnect handler: {e}")