Skip to content

Commit 82db0c9

Browse files
authored
Merge pull request #4 from deeleeramone/feature/expose-tauri-menu-tray
[Feature] Add Menus, Trays, and More Tauri Integrations For Native Window Modes
2 parents e6a4d34 + fbb384c commit 82db0c9

34 files changed

Lines changed: 5510 additions & 179 deletions
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Builder Options & Initialization Scripts
2+
3+
PyWry's `WindowConfig` controls **builder-level** settings that are applied when the native window is first created. These settings are passed to `WebviewWindowBuilder` in the pytauri subprocess.
4+
5+
## Builder Fields
6+
7+
These fields map 1:1 to Tauri's `WebviewWindowBuilder`:
8+
9+
| Field | Type | Default | Description |
10+
|:---|:---|:---|:---|
11+
| `resizable` | `bool` | `True` | User can resize the window |
12+
| `decorations` | `bool` | `True` | Show title bar and borders |
13+
| `always_on_top` | `bool` | `False` | Window stays above all others |
14+
| `always_on_bottom` | `bool` | `False` | Window stays below all others |
15+
| `transparent` | `bool` | `False` | Enable window transparency |
16+
| `fullscreen` | `bool` | `False` | Open in fullscreen mode |
17+
| `maximized` | `bool` | `False` | Open maximized |
18+
| `focused` | `bool` | `True` | Focus window on creation |
19+
| `visible` | `bool` | `True` | Show window immediately |
20+
| `shadow` | `bool` | `True` | Window has a drop shadow |
21+
| `skip_taskbar` | `bool` | `False` | Hide from taskbar/dock |
22+
| `content_protected` | `bool` | `False` | Prevent screenshots |
23+
| `user_agent` | `str` | `None` | `None` | Custom User-Agent string |
24+
| `incognito` | `bool` | `False` | Incognito/private mode |
25+
| `initialization_script` | `str` | `None` | `None` | JS injected before page load |
26+
| `drag_and_drop` | `bool` | `True` | Enable native drag & drop |
27+
28+
## Setting Builder Defaults
29+
30+
### At Construction
31+
32+
```python
33+
from pywry import PyWry, WindowConfig
34+
35+
config = WindowConfig(
36+
transparent=True,
37+
decorations=False,
38+
always_on_top=True,
39+
)
40+
app = PyWry(default_config=config)
41+
```
42+
43+
### After Construction
44+
45+
Modify the default config directly via the `default_config` property:
46+
47+
```python
48+
app = PyWry()
49+
app.default_config.resizable = False
50+
app.default_config.user_agent = "MyApp/1.0"
51+
```
52+
53+
### Per-Window Override
54+
55+
Builder fields on the default config flow to every `show()` call automatically. Non-default values are forwarded as `**kwargs` to `WebviewWindowBuilder`:
56+
57+
```python
58+
# All windows get the defaults...
59+
app.show("<h1>Default Settings</h1>")
60+
61+
# ...unless overridden via WindowConfig
62+
from pywry import WindowConfig
63+
custom = app.default_config.model_copy(update={"transparent": False})
64+
# (Pass custom config via content objects or direct config parameter)
65+
```
66+
67+
## How Fields Flow
68+
69+
```mermaid
70+
flowchart LR
71+
A[app.default_config] --> B[show<br/>model_copy]
72+
B --> C[WindowConfig<br/>instance]
73+
C --> D[builder_kwargs<br/>non-default only]
74+
D --> E[IPC: create_window]
75+
E --> F[WebviewWindowBuilder<br/>**kwargs]
76+
```
77+
78+
Only fields that differ from their defaults are sent over IPC. For a fresh `WindowConfig()`, `builder_kwargs()` returns an empty dict.
79+
80+
---
81+
82+
## Initialization Scripts
83+
84+
An initialization script is JavaScript that runs **before** the page loads and **persists across navigations**. It's injected by `WebviewWindowBuilder.initialization_script()` in the Tauri subprocess.
85+
86+
Common uses:
87+
88+
- Polyfills or shims
89+
- Global configuration objects
90+
- Analytics or telemetry setup
91+
- Custom `window.pywry` extensions
92+
93+
### Setting a Default Script
94+
95+
All new windows will have this script:
96+
97+
```python
98+
app = PyWry()
99+
app.set_initialization_script("""
100+
window.__APP_CONFIG__ = {
101+
version: "1.0",
102+
debug: true,
103+
};
104+
console.log("Init script loaded");
105+
""")
106+
107+
# Every show() call now includes this script
108+
app.show("<h1>Has init script</h1>")
109+
```
110+
111+
### Per-Window Script
112+
113+
Override or extend the default on individual `show()` calls:
114+
115+
```python
116+
app.show(
117+
"<h1>Custom Init</h1>",
118+
initialization_script="""
119+
window.__CUSTOM__ = true;
120+
console.log("Per-window init");
121+
""",
122+
)
123+
```
124+
125+
### Via default_config
126+
127+
You can also set it directly on the config:
128+
129+
```python
130+
app.default_config.initialization_script = "console.log('hello')"
131+
```
132+
133+
### Auto-Promotion
134+
135+
When `initialization_script` is set on `HtmlContent`, it's automatically promoted to the `WindowConfig.initialization_script` builder field:
136+
137+
```python
138+
from pywry import HtmlContent
139+
140+
content = HtmlContent(
141+
body="<h1>Content</h1>",
142+
initialization_script="window.__preload = true;",
143+
)
144+
# The script is auto-promoted to builder-level
145+
```
146+
147+
!!! warning "Builder-level only"
148+
Initialization scripts are set at window **creation** time. They cannot be changed after the window is created. To run JavaScript dynamically, use `handle.eval()` instead.
149+
150+
---
151+
152+
## WindowConfig.builder_kwargs()
153+
154+
The `builder_kwargs()` method returns a dict of only the non-default builder fields, ready to be unpacked as `**kwargs`:
155+
156+
```python
157+
from pywry.models import WindowConfig
158+
159+
config = WindowConfig(transparent=True, user_agent="test/1.0")
160+
print(config.builder_kwargs())
161+
# {'transparent': True, 'user_agent': 'test/1.0'}
162+
163+
config2 = WindowConfig() # all defaults
164+
print(config2.builder_kwargs())
165+
# {}
166+
```
167+
168+
This is used internally by the runtime to avoid sending unnecessary data over IPC.

0 commit comments

Comments
 (0)