pake-cli 3.7.6 → 3.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"pake-capability":{"identifier":"pake-capability","description":"Capability for the pake app.","remote":{"urls":["https://*.*"]},"local":true,"webviews":["pake"],"permissions":["shell:allow-open","core:window:allow-theme","core:window:allow-start-dragging","core:window:allow-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-set-fullscreen","core:webview:allow-internal-toggle-devtools","notification:allow-is-permission-granted","notification:allow-notify","notification:allow-get-active","notification:allow-register-listener","notification:allow-register-action-types","notification:default","core:path:default"]}}
1
+ {"pake-capability":{"identifier":"pake-capability","description":"Capability for the pake app.","remote":{"urls":["https://*.*"]},"local":true,"webviews":["pake"],"permissions":["shell:allow-open","core:window:allow-theme","core:window:allow-start-dragging","core:window:allow-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-set-fullscreen","core:window:allow-set-resizable","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-close","core:webview:allow-internal-toggle-devtools","notification:allow-is-permission-granted","notification:allow-notify","notification:allow-get-active","notification:allow-register-listener","notification:allow-register-action-types","notification:default","core:path:default"]}}
@@ -140,10 +140,10 @@
140
140
  "identifier": {
141
141
  "anyOf": [
142
142
  {
143
- "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`",
143
+ "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`",
144
144
  "type": "string",
145
145
  "const": "http:default",
146
- "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`"
146
+ "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`"
147
147
  },
148
148
  {
149
149
  "description": "Enables the fetch command without any pre-configured scope.",
@@ -157,6 +157,12 @@
157
157
  "const": "http:allow-fetch-cancel",
158
158
  "markdownDescription": "Enables the fetch_cancel command without any pre-configured scope."
159
159
  },
160
+ {
161
+ "description": "Enables the fetch_cancel_body command without any pre-configured scope.",
162
+ "type": "string",
163
+ "const": "http:allow-fetch-cancel-body",
164
+ "markdownDescription": "Enables the fetch_cancel_body command without any pre-configured scope."
165
+ },
160
166
  {
161
167
  "description": "Enables the fetch_read_body command without any pre-configured scope.",
162
168
  "type": "string",
@@ -181,6 +187,12 @@
181
187
  "const": "http:deny-fetch-cancel",
182
188
  "markdownDescription": "Denies the fetch_cancel command without any pre-configured scope."
183
189
  },
190
+ {
191
+ "description": "Denies the fetch_cancel_body command without any pre-configured scope.",
192
+ "type": "string",
193
+ "const": "http:deny-fetch-cancel-body",
194
+ "markdownDescription": "Denies the fetch_cancel_body command without any pre-configured scope."
195
+ },
184
196
  {
185
197
  "description": "Denies the fetch_read_body command without any pre-configured scope.",
186
198
  "type": "string",
@@ -2715,10 +2727,10 @@
2715
2727
  "markdownDescription": "Denies the unregister_all command without any pre-configured scope."
2716
2728
  },
2717
2729
  {
2718
- "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`",
2730
+ "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`",
2719
2731
  "type": "string",
2720
2732
  "const": "http:default",
2721
- "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`"
2733
+ "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`"
2722
2734
  },
2723
2735
  {
2724
2736
  "description": "Enables the fetch command without any pre-configured scope.",
@@ -2732,6 +2744,12 @@
2732
2744
  "const": "http:allow-fetch-cancel",
2733
2745
  "markdownDescription": "Enables the fetch_cancel command without any pre-configured scope."
2734
2746
  },
2747
+ {
2748
+ "description": "Enables the fetch_cancel_body command without any pre-configured scope.",
2749
+ "type": "string",
2750
+ "const": "http:allow-fetch-cancel-body",
2751
+ "markdownDescription": "Enables the fetch_cancel_body command without any pre-configured scope."
2752
+ },
2735
2753
  {
2736
2754
  "description": "Enables the fetch_read_body command without any pre-configured scope.",
2737
2755
  "type": "string",
@@ -2756,6 +2774,12 @@
2756
2774
  "const": "http:deny-fetch-cancel",
2757
2775
  "markdownDescription": "Denies the fetch_cancel command without any pre-configured scope."
2758
2776
  },
2777
+ {
2778
+ "description": "Denies the fetch_cancel_body command without any pre-configured scope.",
2779
+ "type": "string",
2780
+ "const": "http:deny-fetch-cancel-body",
2781
+ "markdownDescription": "Denies the fetch_cancel_body command without any pre-configured scope."
2782
+ },
2759
2783
  {
2760
2784
  "description": "Denies the fetch_read_body command without any pre-configured scope.",
2761
2785
  "type": "string",
@@ -140,10 +140,10 @@
140
140
  "identifier": {
141
141
  "anyOf": [
142
142
  {
143
- "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`",
143
+ "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`",
144
144
  "type": "string",
145
145
  "const": "http:default",
146
- "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`"
146
+ "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`"
147
147
  },
148
148
  {
149
149
  "description": "Enables the fetch command without any pre-configured scope.",
@@ -157,6 +157,12 @@
157
157
  "const": "http:allow-fetch-cancel",
158
158
  "markdownDescription": "Enables the fetch_cancel command without any pre-configured scope."
159
159
  },
160
+ {
161
+ "description": "Enables the fetch_cancel_body command without any pre-configured scope.",
162
+ "type": "string",
163
+ "const": "http:allow-fetch-cancel-body",
164
+ "markdownDescription": "Enables the fetch_cancel_body command without any pre-configured scope."
165
+ },
160
166
  {
161
167
  "description": "Enables the fetch_read_body command without any pre-configured scope.",
162
168
  "type": "string",
@@ -181,6 +187,12 @@
181
187
  "const": "http:deny-fetch-cancel",
182
188
  "markdownDescription": "Denies the fetch_cancel command without any pre-configured scope."
183
189
  },
190
+ {
191
+ "description": "Denies the fetch_cancel_body command without any pre-configured scope.",
192
+ "type": "string",
193
+ "const": "http:deny-fetch-cancel-body",
194
+ "markdownDescription": "Denies the fetch_cancel_body command without any pre-configured scope."
195
+ },
184
196
  {
185
197
  "description": "Denies the fetch_read_body command without any pre-configured scope.",
186
198
  "type": "string",
@@ -2715,10 +2727,10 @@
2715
2727
  "markdownDescription": "Denies the unregister_all command without any pre-configured scope."
2716
2728
  },
2717
2729
  {
2718
- "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`",
2730
+ "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`",
2719
2731
  "type": "string",
2720
2732
  "const": "http:default",
2721
- "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`"
2733
+ "markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-send`\n- `allow-fetch-read-body`\n- `allow-fetch-cancel-body`"
2722
2734
  },
2723
2735
  {
2724
2736
  "description": "Enables the fetch command without any pre-configured scope.",
@@ -2732,6 +2744,12 @@
2732
2744
  "const": "http:allow-fetch-cancel",
2733
2745
  "markdownDescription": "Enables the fetch_cancel command without any pre-configured scope."
2734
2746
  },
2747
+ {
2748
+ "description": "Enables the fetch_cancel_body command without any pre-configured scope.",
2749
+ "type": "string",
2750
+ "const": "http:allow-fetch-cancel-body",
2751
+ "markdownDescription": "Enables the fetch_cancel_body command without any pre-configured scope."
2752
+ },
2735
2753
  {
2736
2754
  "description": "Enables the fetch_read_body command without any pre-configured scope.",
2737
2755
  "type": "string",
@@ -2756,6 +2774,12 @@
2756
2774
  "const": "http:deny-fetch-cancel",
2757
2775
  "markdownDescription": "Denies the fetch_cancel command without any pre-configured scope."
2758
2776
  },
2777
+ {
2778
+ "description": "Denies the fetch_cancel_body command without any pre-configured scope.",
2779
+ "type": "string",
2780
+ "const": "http:deny-fetch-cancel-body",
2781
+ "markdownDescription": "Denies the fetch_cancel_body command without any pre-configured scope."
2782
+ },
2759
2783
  {
2760
2784
  "description": "Denies the fetch_read_body command without any pre-configured scope.",
2761
2785
  "type": "string",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "windows": [
3
3
  {
4
- "url": "https://weekly.tw93.fun/",
4
+ "url": "https://weekly.tw93.fun/en",
5
5
  "url_type": "web",
6
6
  "hide_title_bar": true,
7
7
  "fullscreen": false,
@@ -104,7 +104,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
104
104
  #[cfg(target_os = "windows")]
105
105
  let mut windows_browser_args = String::from("--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection --disable-blink-features=AutomationControlled");
106
106
 
107
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
107
+ #[cfg(target_os = "linux")]
108
108
  let mut linux_browser_args = String::from("--disable-blink-features=AutomationControlled");
109
109
 
110
110
  if window_config.ignore_certificate_errors {
@@ -113,7 +113,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
113
113
  windows_browser_args.push_str(" --ignore-certificate-errors");
114
114
  }
115
115
 
116
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
116
+ #[cfg(target_os = "linux")]
117
117
  {
118
118
  linux_browser_args.push_str(" --ignore-certificate-errors");
119
119
  }
@@ -131,7 +131,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
131
131
  windows_browser_args.push_str(" --enable-unsafe-webgpu");
132
132
  }
133
133
 
134
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
134
+ #[cfg(target_os = "linux")]
135
135
  {
136
136
  linux_browser_args.push_str(" --enable-features=SharedArrayBuffer");
137
137
  linux_browser_args.push_str(" --enable-unsafe-webgpu");
@@ -189,7 +189,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
189
189
  window_builder = window_builder.additional_browser_args(&windows_browser_args);
190
190
  }
191
191
 
192
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
192
+ #[cfg(target_os = "linux")]
193
193
  {
194
194
  window_builder = window_builder.additional_browser_args(&linux_browser_args);
195
195
  }
@@ -19,3 +19,254 @@ document.addEventListener("DOMContentLoaded", () => {
19
19
 
20
20
  window.pakeToast = pakeToast;
21
21
  });
22
+
23
+ // Polyfill for HTML5 Fullscreen API in Tauri webview
24
+ // This bridges the HTML5 Fullscreen API to Tauri's native window fullscreen
25
+ // Works for all video sites (YouTube, Vimeo, Bilibili, etc.)
26
+ (function () {
27
+ function initFullscreenPolyfill() {
28
+ if (!window.__TAURI__ || !document.head) {
29
+ setTimeout(initFullscreenPolyfill, 100);
30
+ return;
31
+ }
32
+
33
+ const appWindow = window.__TAURI__.window.getCurrentWindow();
34
+ let fullscreenElement = null;
35
+ let actualFullscreenElement = null;
36
+ let originalStyles = null;
37
+ let originalParent = null;
38
+ let originalNextSibling = null;
39
+ let wasInBody = false;
40
+
41
+ // Inject fullscreen styles
42
+ const styleEl = document.createElement("style");
43
+ styleEl.id = "pake-fullscreen-style";
44
+ styleEl.textContent = `
45
+ body.pake-fullscreen-active {
46
+ overflow: hidden !important;
47
+ }
48
+ .pake-fullscreen-element {
49
+ position: fixed !important;
50
+ top: 0 !important;
51
+ left: 0 !important;
52
+ width: 100vw !important;
53
+ height: 100vh !important;
54
+ max-width: 100vw !important;
55
+ max-height: 100vh !important;
56
+ margin: 0 !important;
57
+ padding: 0 !important;
58
+ z-index: 2147483647 !important;
59
+ background: #000 !important;
60
+ object-fit: contain !important;
61
+ }
62
+ .pake-fullscreen-element video {
63
+ width: 100% !important;
64
+ height: 100% !important;
65
+ object-fit: contain !important;
66
+ }
67
+ `;
68
+ document.head.appendChild(styleEl);
69
+
70
+ // Find the actual video element
71
+ function findMediaElement() {
72
+ const videos = document.querySelectorAll("video");
73
+ if (videos.length > 0) {
74
+ let largestVideo = videos[0];
75
+ let maxArea = 0;
76
+ videos.forEach((video) => {
77
+ const rect = video.getBoundingClientRect();
78
+ const area = rect.width * rect.height;
79
+ if (area > maxArea || !video.paused) {
80
+ maxArea = area;
81
+ largestVideo = video;
82
+ }
83
+ });
84
+ return largestVideo;
85
+ }
86
+ return null;
87
+ }
88
+
89
+ // Enter fullscreen
90
+ function enterFullscreen(element) {
91
+ fullscreenElement = element;
92
+
93
+ // If html/body element, find the video instead
94
+ let targetElement = element;
95
+ if (element === document.documentElement || element === document.body) {
96
+ const mediaElement = findMediaElement();
97
+ if (mediaElement) {
98
+ targetElement = mediaElement;
99
+ actualFullscreenElement = mediaElement;
100
+ } else {
101
+ actualFullscreenElement = element;
102
+ }
103
+ } else {
104
+ actualFullscreenElement = element;
105
+ }
106
+
107
+ // Save original state
108
+ originalStyles = {
109
+ position: targetElement.style.position,
110
+ top: targetElement.style.top,
111
+ left: targetElement.style.left,
112
+ width: targetElement.style.width,
113
+ height: targetElement.style.height,
114
+ maxWidth: targetElement.style.maxWidth,
115
+ maxHeight: targetElement.style.maxHeight,
116
+ margin: targetElement.style.margin,
117
+ padding: targetElement.style.padding,
118
+ zIndex: targetElement.style.zIndex,
119
+ background: targetElement.style.background,
120
+ objectFit: targetElement.style.objectFit,
121
+ };
122
+
123
+ wasInBody = targetElement.parentNode === document.body;
124
+ if (!wasInBody) {
125
+ originalParent = targetElement.parentNode;
126
+ originalNextSibling = targetElement.nextSibling;
127
+ }
128
+
129
+ // Apply fullscreen
130
+ targetElement.classList.add("pake-fullscreen-element");
131
+ document.body.classList.add("pake-fullscreen-active");
132
+
133
+ if (!wasInBody) {
134
+ document.body.appendChild(targetElement);
135
+ }
136
+
137
+ // Fullscreen window
138
+ appWindow.setFullscreen(true).then(() => {
139
+ const event = new Event("fullscreenchange", { bubbles: true });
140
+ document.dispatchEvent(event);
141
+ element.dispatchEvent(event);
142
+
143
+ const webkitEvent = new Event("webkitfullscreenchange", {
144
+ bubbles: true,
145
+ });
146
+ document.dispatchEvent(webkitEvent);
147
+ element.dispatchEvent(webkitEvent);
148
+ });
149
+
150
+ return Promise.resolve();
151
+ }
152
+
153
+ // Exit fullscreen
154
+ function exitFullscreen() {
155
+ if (!fullscreenElement) {
156
+ return Promise.resolve();
157
+ }
158
+
159
+ const exitingElement = fullscreenElement;
160
+ const targetElement = actualFullscreenElement;
161
+
162
+ // Restore styles and position
163
+ targetElement.classList.remove("pake-fullscreen-element");
164
+ document.body.classList.remove("pake-fullscreen-active");
165
+
166
+ if (originalStyles) {
167
+ Object.keys(originalStyles).forEach((key) => {
168
+ targetElement.style[key] = originalStyles[key];
169
+ });
170
+ }
171
+
172
+ if (!wasInBody && originalParent) {
173
+ if (
174
+ originalNextSibling &&
175
+ originalNextSibling.parentNode === originalParent
176
+ ) {
177
+ originalParent.insertBefore(targetElement, originalNextSibling);
178
+ } else if (originalParent.isConnected) {
179
+ originalParent.appendChild(targetElement);
180
+ }
181
+ }
182
+
183
+ // Reset state
184
+ fullscreenElement = null;
185
+ actualFullscreenElement = null;
186
+ originalStyles = null;
187
+ originalParent = null;
188
+ originalNextSibling = null;
189
+ wasInBody = false;
190
+
191
+ // Exit window fullscreen
192
+ return appWindow.setFullscreen(false).then(() => {
193
+ const event = new Event("fullscreenchange", { bubbles: true });
194
+ document.dispatchEvent(event);
195
+ exitingElement.dispatchEvent(event);
196
+
197
+ const webkitEvent = new Event("webkitfullscreenchange", {
198
+ bubbles: true,
199
+ });
200
+ document.dispatchEvent(webkitEvent);
201
+ exitingElement.dispatchEvent(webkitEvent);
202
+ });
203
+ }
204
+
205
+ // Override fullscreenEnabled
206
+ Object.defineProperty(document, "fullscreenEnabled", {
207
+ get: () => true,
208
+ configurable: true,
209
+ });
210
+ Object.defineProperty(document, "webkitFullscreenEnabled", {
211
+ get: () => true,
212
+ configurable: true,
213
+ });
214
+
215
+ // Override fullscreenElement
216
+ Object.defineProperty(document, "fullscreenElement", {
217
+ get: () => fullscreenElement,
218
+ configurable: true,
219
+ });
220
+ Object.defineProperty(document, "webkitFullscreenElement", {
221
+ get: () => fullscreenElement,
222
+ configurable: true,
223
+ });
224
+ Object.defineProperty(document, "webkitCurrentFullScreenElement", {
225
+ get: () => fullscreenElement,
226
+ configurable: true,
227
+ });
228
+
229
+ // Override requestFullscreen
230
+ Element.prototype.requestFullscreen = function () {
231
+ return enterFullscreen(this);
232
+ };
233
+ Element.prototype.webkitRequestFullscreen = function () {
234
+ return enterFullscreen(this);
235
+ };
236
+ Element.prototype.webkitRequestFullScreen = function () {
237
+ return enterFullscreen(this);
238
+ };
239
+
240
+ // Override exitFullscreen
241
+ document.exitFullscreen = exitFullscreen;
242
+ document.webkitExitFullscreen = exitFullscreen;
243
+ document.webkitCancelFullScreen = exitFullscreen;
244
+
245
+ // Handle Escape key
246
+ document.addEventListener(
247
+ "keydown",
248
+ (e) => {
249
+ if (e.key === "Escape" && fullscreenElement) {
250
+ exitFullscreen();
251
+ }
252
+ },
253
+ true,
254
+ );
255
+
256
+ // Monitor window fullscreen changes
257
+ let lastFullscreenState = false;
258
+ setInterval(() => {
259
+ appWindow
260
+ .isFullscreen()
261
+ .then((isFullscreen) => {
262
+ if (lastFullscreenState && !isFullscreen && fullscreenElement) {
263
+ exitFullscreen();
264
+ }
265
+ lastFullscreenState = isFullscreen;
266
+ })
267
+ .catch(() => {});
268
+ }, 500);
269
+ }
270
+
271
+ initFullscreenPolyfill();
272
+ })();
@@ -22,6 +22,13 @@ use app::{
22
22
  use util::get_pake_config;
23
23
 
24
24
  pub fn run_app() {
25
+ #[cfg(target_os = "linux")]
26
+ {
27
+ if std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() {
28
+ std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
29
+ }
30
+ }
31
+
25
32
  let (pake_config, tauri_config) = get_pake_config();
26
33
  let tauri_app = tauri::Builder::default();
27
34
 
@@ -101,7 +108,7 @@ pub fn run_app() {
101
108
  window_clone.show().unwrap();
102
109
 
103
110
  // Fixed: Linux fullscreen issue with virtual keyboard
104
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
111
+ #[cfg(target_os = "linux")]
105
112
  {
106
113
  if init_fullscreen {
107
114
  window_clone.set_fullscreen(true).unwrap();
@@ -127,7 +134,7 @@ pub fn run_app() {
127
134
  tokio::time::sleep(Duration::from_millis(900)).await;
128
135
  }
129
136
  }
130
- #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
137
+ #[cfg(target_os = "linux")]
131
138
  {
132
139
  if window.is_fullscreen().unwrap_or(false) {
133
140
  window.set_fullscreen(false).unwrap();
@@ -135,6 +142,8 @@ pub fn run_app() {
135
142
  let _ = window.set_focus();
136
143
  }
137
144
  }
145
+ // On macOS, directly hide without minimize to avoid duplicate Dock icons
146
+ #[cfg(not(target_os = "macos"))]
138
147
  window.minimize().unwrap();
139
148
  window.hide().unwrap();
140
149
  });
@@ -145,8 +154,24 @@ pub fn run_app() {
145
154
  }
146
155
  }
147
156
  })
148
- .run(tauri::generate_context!())
149
- .expect("error while running tauri application");
157
+ .build(tauri::generate_context!())
158
+ .expect("error while building tauri application")
159
+ .run(|app, event| {
160
+ // Handle macOS dock icon click to reopen hidden window
161
+ #[cfg(target_os = "macos")]
162
+ if let tauri::RunEvent::Reopen {
163
+ has_visible_windows,
164
+ ..
165
+ } = event
166
+ {
167
+ if !has_visible_windows {
168
+ if let Some(window) = app.get_webview_window("pake") {
169
+ let _ = window.show();
170
+ let _ = window.set_focus();
171
+ }
172
+ }
173
+ }
174
+ });
150
175
  }
151
176
 
152
177
  pub fn run() {