also looking at this
feat: add Linux and Windows named-window routing
#325
29 files
+2250
-200
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -793,6 +793,14 @@ pub fn createWindow(title: []const u8, width: u32, height: u32, html: []const u8 | ||
| 793 | 793 | } |
| 794 | 794 | |
| 795 | 795 | pub fn createWindowWithURL(title: []const u8, width: u32, height: u32, url: []const u8, style: WindowStyle) !*anyopaque { |
| 796 | return createStyledWindow(title, width, height, url, style, true); | |
| 797 | } | |
| 798 | ||
| 799 | pub fn createWindowWithHTML(title: []const u8, width: u32, height: u32, html: []const u8, style: WindowStyle) !*anyopaque { | |
| 800 | return createStyledWindow(title, width, height, html, style, false); | |
| 801 | } | |
| 802 | ||
| 803 | fn createStyledWindow(title: []const u8, width: u32, height: u32, content: []const u8, style: WindowStyle, comptime is_url: bool) !*anyopaque { | |
| 796 | 804 | var window = try Window.create(.{ |
| 797 | 805 | .title = title, |
| 798 | 806 | .width = width, |
| @@ -811,7 +819,8 @@ pub fn createWindowWithURL(title: []const u8, width: u32, height: u32, url: []co | ||
| 811 | 819 | .allow_notifications = style.allow_notifications, |
| 812 | 820 | .allow_clipboard = style.allow_clipboard, |
| 813 | 821 | }); |
| 814 | try window.loadURL(url); | |
| 822 | errdefer window.close(); | |
| 823 | if (is_url) try window.loadURL(content) else try window.loadHTML(content); | |
| 815 | 824 | window.show(); |
| 816 | 825 | return window.gtk_window; |
| 817 | 826 | } |
| @@ -170,6 +170,9 @@ pub const Window = struct { | ||
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | pub fn show(self: *Self) !void { |
| 173 | // Styled URL/HTML constructors already created and showed their native | |
| 174 | // window. Creating it again here would duplicate the first page. | |
| 175 | if (self.native_handle != null) return; | |
| 173 | 176 | switch (builtin.os.tag) { |
| 174 | 177 | .macos => try self.showMacOS(), |
| 175 | 178 | .linux => try self.showLinux(), |
| @@ -314,7 +317,7 @@ pub const App = struct { | ||
| 314 | 317 | try self.windows.append(self.allocator, window); |
| 315 | 318 | return window; |
| 316 | 319 | } else { |
| 317 | return error.UnsupportedPlatform; | |
| 320 | return self.createPortableWindow(title, width, height, html, style, false); | |
| 318 | 321 | } |
| 319 | 322 | } |
| 320 | 323 | |
| @@ -328,8 +331,60 @@ pub const App = struct { | ||
| 328 | 331 | try self.windows.append(self.allocator, window); |
| 329 | 332 | return window; |
| 330 | 333 | } else { |
| 331 | return error.UnsupportedPlatform; | |
| 334 | return self.createPortableWindow(title, width, height, url, style, true); | |
| 335 | } | |
| 336 | } | |
| 337 | ||
| 338 | fn createPortableWindow(self: *Self, title: []const u8, width: u32, height: u32, content: []const u8, style: WindowStyle, comptime is_url: bool) !*Window { | |
| 339 | if (builtin.os.tag == .linux) { | |
| 340 | const linux = ; | |
| 341 | const native_style: linux.WindowStyle = .{ | |
| 342 | .frameless = style.frameless, | |
| 343 | .transparent = style.transparent, | |
| 344 | .always_on_top = style.always_on_top, | |
| 345 | .resizable = style.resizable, | |
| 346 | .fullscreen = style.fullscreen, | |
| 347 | .x = style.x, | |
| 348 | .y = style.y, | |
| 349 | .dark_mode = style.dark_mode, | |
| 350 | .dev_tools = style.dev_tools, | |
| 351 | }; | |
| 352 | const native = if (is_url) | |
| 353 | try linux.createWindowWithURL(title, width, height, content, native_style) | |
| 354 | else | |
| 355 | try linux.createWindowWithHTML(title, width, height, content, native_style); | |
| 356 | errdefer linux.gtk_window_close(native); | |
| 357 | return self.rememberPortableWindow(title, width, height, if (is_url) "" else content, native); | |
| 358 | } else if (builtin.os.tag == .windows) { | |
| 359 | const windows = ; | |
| 360 | const native_style: windows.WindowStyle = .{ | |
| 361 | .frameless = style.frameless, | |
| 362 | .transparent = style.transparent, | |
| 363 | .always_on_top = style.always_on_top, | |
| 364 | .resizable = style.resizable, | |
| 365 | .fullscreen = style.fullscreen, | |
| 366 | .x = style.x, | |
| 367 | .y = style.y, | |
| 368 | .dark_mode = style.dark_mode, | |
| 369 | .dev_tools = style.dev_tools, | |
| 370 | }; | |
| 371 | const native = if (is_url) | |
| 372 | try windows.createWindowWithURL(title, width, height, content, native_style) | |
| 373 | else | |
| 374 | try windows.createWindowWithHTML(title, width, height, content, native_style); | |
| 375 | errdefer _ = windows.DestroyWindow(native); | |
| 376 | return self.rememberPortableWindow(title, width, height, if (is_url) "" else content, native); | |
| 332 | 377 | } |
| 378 | return error.UnsupportedPlatform; | |
| 379 | } | |
| 380 | ||
| 381 | fn rememberPortableWindow(self: *Self, title: []const u8, width: u32, height: u32, html: []const u8, native: *anyopaque) !*Window { | |
| 382 | const window = try self.allocator.create(Window); | |
| 383 | errdefer self.allocator.destroy(window); | |
| 384 | window.* = Window.init(title, width, height, html); | |
| 385 | window.native_handle = native; | |
| 386 | try self.windows.append(self.allocator, window); | |
| 387 | return window; | |
| 333 | 388 | } |
| 334 | 389 | |
| 335 | 390 | /// Create a window with a native macOS sidebar (Finder-style with vibrancy) - HTML mode |
| @@ -1549,6 +1549,14 @@ pub fn createWindow(title: []const u8, width: u32, height: u32, html: []const u8 | ||
| 1549 | 1549 | } |
| 1550 | 1550 | |
| 1551 | 1551 | pub fn createWindowWithURL(title: []const u8, width: u32, height: u32, url: []const u8, style: WindowStyle) !*anyopaque { |
| 1552 | return createStyledWindow(title, width, height, url, style, true); | |
| 1553 | } | |
| 1554 | ||
| 1555 | pub fn createWindowWithHTML(title: []const u8, width: u32, height: u32, html: []const u8, style: WindowStyle) !*anyopaque { | |
| 1556 | return createStyledWindow(title, width, height, html, style, false); | |
| 1557 | } | |
| 1558 | ||
| 1559 | fn createStyledWindow(title: []const u8, width: u32, height: u32, content: []const u8, style: WindowStyle, comptime is_url: bool) !*anyopaque { | |
| 1552 | 1560 | var window = try Window.create(.{ |
| 1553 | 1561 | .title = title, |
| 1554 | 1562 | .width = width, |
| @@ -1558,11 +1566,13 @@ pub fn createWindowWithURL(title: []const u8, width: u32, height: u32, url: []co | ||
| 1558 | 1566 | .resizable = style.resizable, |
| 1559 | 1567 | .frameless = style.frameless, |
| 1560 | 1568 | .transparent = style.transparent, |
| 1569 | .always_on_top = style.always_on_top, | |
| 1561 | 1570 | .fullscreen = style.fullscreen, |
| 1562 | 1571 | .dark_mode = style.dark_mode, |
| 1563 | 1572 | .dev_tools = style.dev_tools, |
| 1564 | 1573 | }); |
| 1565 | try window.loadURL(url); | |
| 1574 | errdefer window.close(); | |
| 1575 | if (is_url) try window.loadURL(content) else try window.loadHTML(content); | |
| 1566 | 1576 | window.show(); |
| 1567 | 1577 | return window.hwnd; |
| 1568 | 1578 | } |