Skip to content

Commit a0c5df1

Browse files
committed
update docs
1 parent 27508c1 commit a0c5df1

File tree

13 files changed

+507
-51
lines changed

13 files changed

+507
-51
lines changed

cli/data/gtk3/Bar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import App from "ags/gtk3/app"
1+
import app from "ags/gtk3/app"
22
import { Astal, Gtk, Gdk } from "ags/gtk3"
33
import { execAsync } from "ags/process"
44
import { Poll } from "ags/state"
@@ -14,7 +14,7 @@ export default function Bar(gdkmonitor: Gdk.Monitor) {
1414
gdkmonitor={gdkmonitor}
1515
exclusivity={Astal.Exclusivity.EXCLUSIVE}
1616
anchor={TOP | LEFT | RIGHT}
17-
application={App}
17+
application={app}
1818
>
1919
<centerbox>
2020
<button

cli/data/gtk3/app.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import App from "ags/gtk3/app"
1+
import app from "ags/gtk3/app"
22
import style from "./style.scss"
33
import Bar from "./widget/Bar"
44

5-
App.start({
5+
app.start({
66
css: style,
77
main() {
8-
App.get_monitors().map(Bar)
8+
app.get_monitors().map(Bar)
99
},
1010
})

cli/data/gtk4/Bar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import App from "ags/gtk4/app"
1+
import app from "ags/gtk4/app"
22
import { Astal, Gtk, Gdk } from "ags/gtk4"
33
import { execAsync } from "ags/process"
44
import { Poll } from "ags/state"
@@ -16,7 +16,7 @@ export default function Bar(gdkmonitor: Gdk.Monitor) {
1616
gdkmonitor={gdkmonitor}
1717
exclusivity={Astal.Exclusivity.EXCLUSIVE}
1818
anchor={TOP | LEFT | RIGHT}
19-
application={App}
19+
application={app}
2020
>
2121
<centerbox cssName="centerbox">
2222
<button

cli/data/gtk4/app.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import App from "ags/gtk4/app"
1+
import app from "ags/gtk4/app"
22
import style from "./style.scss"
33
import Bar from "./widget/Bar"
44

5-
App.start({
5+
app.start({
66
css: style,
77
main() {
8-
App.get_monitors().map(Bar)
8+
app.get_monitors().map(Bar)
99
},
1010
})

docs/guide/examples.md

+222
Original file line numberDiff line numberDiff line change
@@ -1 +1,223 @@
11
# Examples
2+
3+
You can find some full examples on the
4+
[repository](https://github.com/Aylur/ags/tree/main/examples).
5+
6+
## Monitor id does not match compositor
7+
8+
The monitor id property that windows expect is mapped by Gdk, which is not always
9+
the same as the compositor. Instead use the `gdkmonitor` property which expects
10+
a `Gdk.Monitor` object.
11+
12+
```tsx
13+
function Bar(gdkmonitor) {
14+
return <window gdkmonitor={gdkmonitor} />
15+
}
16+
17+
function main() {
18+
for (const monitor of app.get_monitors()) {
19+
if (monitor.model == "your-desired-model") {
20+
Bar(monitor)
21+
}
22+
}
23+
}
24+
```
25+
26+
## Environment variables
27+
28+
JavaScript is **not** bash or other shell environments.
29+
30+
```ts
31+
const HOME = exec("echo $HOME") // does not work
32+
```
33+
34+
`exec` and `execAsync` runs the passed program as is, its **not** run in a
35+
shell environment, so the above example just passes `$HOME` as a string literal
36+
to the `echo` program.
37+
38+
:::danger Please don't do this
39+
40+
```ts
41+
const HOME = exec("bash -c 'echo $HOME'")
42+
```
43+
44+
:::
45+
46+
You can read environment variables using
47+
[GLib.getenv](https://gjs-docs.gnome.org/glib20~2.0/glib.getenv).
48+
49+
```ts
50+
import GLib from "gi://GLib"
51+
52+
const HOME = GLib.getenv("HOME")
53+
```
54+
55+
## Custom SVG symbolic icons
56+
57+
Put the svgs in a directory, name them `<icon-name>-symbolic.svg`
58+
and use `app.add_icons()` or `icons` parameter in `app.start()`
59+
60+
:::code-group
61+
62+
```ts [app.ts]
63+
app.start({
64+
icons: `/path/to/icons`, // this dir should include custom-symbolic.svg
65+
main() {
66+
Widget.Icon({
67+
icon: "custom-symbolic", // custom-symbolic.svg
68+
css: "color: green;", // can be colored, like other named icons
69+
})
70+
},
71+
})
72+
```
73+
74+
:::
75+
76+
:::info
77+
If there is a name clash with an icon from your current icon pack
78+
the icon pack will take precedence
79+
:::
80+
81+
## Logging
82+
83+
The `console` API in GJS uses glib logging functions.
84+
If you just want to print some text as is to stdout
85+
use the globally available `print` function or `printerr` for stderr.
86+
87+
```ts
88+
print("print this line to stdout")
89+
printerr("print this line to stderr")
90+
```
91+
92+
## Auto create Window for each Monitor
93+
94+
To have Window widgets appear on a monitor when its plugged in,
95+
listen to `app.monitor-added`.
96+
97+
:::code-group
98+
99+
```tsx [Bar.tsx]
100+
export default function Bar(gdkmonitor: Gdk.Monitor) {
101+
return <window gdkmonitor={gdkmonitor} />
102+
}
103+
```
104+
105+
:::
106+
107+
:::code-group
108+
109+
```ts [app.ts]
110+
import Gtk from "gi://Gtk"
111+
import Gdk from "gi://Gdk"
112+
import Bar from "./Bar"
113+
114+
function main() {
115+
const bars = new Map<Gdk.Monitor, Gtk.Widget>()
116+
117+
// initialize
118+
for (const gdkmonitor of app.get_monitors()) {
119+
bars.set(gdkmonitor, Bar(gdkmonitor))
120+
}
121+
122+
app.connect("monitor-added", (_, gdkmonitor) => {
123+
bars.set(gdkmonitor, Bar(gdkmonitor))
124+
})
125+
126+
app.connect("monitor-removed", (_, gdkmonitor) => {
127+
bars.get(gdkmonitor)?.destroy()
128+
bars.delete(gdkmonitor)
129+
})
130+
}
131+
132+
app.start({ main })
133+
```
134+
135+
:::
136+
137+
## Error: Can't convert non-null pointer to JS value
138+
139+
These happen when accessing list type properties. Gjs fails to correctly bind
140+
`List` and other array like types of Vala as a property.
141+
142+
```ts
143+
import Notifd from "gi://AstalNotifd"
144+
const notifd = Notifd.get_default()
145+
146+
notifd.notifications // [!code --]
147+
notifd.get_notifications() // [!code ++]
148+
```
149+
150+
:::tip
151+
Open up an issue/PR to add a [workaround](https://github.com/Aylur/ags/blob/main/lib/src/overrides.ts).
152+
:::
153+
154+
## How to create regular floating windows
155+
156+
Use `Gtk.Window`.
157+
158+
By default `Gtk.Window` is destroyed on close.
159+
To prevent this add a handler for `delete-event`.
160+
161+
```tsx {4-7}
162+
return (
163+
<Gtk.Window
164+
$delete-event={(self) => {
165+
self.hide()
166+
return true
167+
}}
168+
>
169+
{child}
170+
</Gtk.Window>
171+
)
172+
```
173+
174+
## Is there a way to limit the width/height of a widget?
175+
176+
- Gtk3: Unfortunately not. You can set a minimum size with `min-width` and
177+
`min-heigth` css attributes, but you can not set max size.
178+
179+
- Gtk4: Yes, using custom layout managers. As a shortcut you can use
180+
[Adw.Clamp](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.7/class.Clamp.html)
181+
182+
## How do I register keybindings?
183+
184+
If you want global keybindings use your compositor.
185+
Only **focused** windows can capture events. To make a window
186+
focusable set its keymode.
187+
188+
::: code-group
189+
190+
```tsx [gtk3]
191+
<window
192+
keymode={Astal.Keymode.ON_DEMAND}
193+
$key-press-event={(self, event: Gdk.Event) => {
194+
if (event.get_keyval()[1] === Gdk.KEY_Escape) {
195+
self.hide()
196+
}
197+
}}
198+
/>
199+
```
200+
201+
```tsx [gtk4]
202+
<window keymode={Astal.Keymode.ON_DEMAND}>
203+
<Gtk.EventControllerKey
204+
$key-pressed={({ widget }, keyval: number) => {
205+
if (keyval === Gdk.KEY_Escape) {
206+
widget.hide()
207+
}
208+
}}
209+
/>
210+
</window>
211+
```
212+
213+
:::
214+
215+
## How to create a Popup
216+
217+
- Gtk4: simply use Gtk's builtin
218+
[Popover](https://docs.gtk.org/gtk4/class.Popover.html).
219+
220+
- Gtk3: you can create an
221+
[Astal.Window](https://aylur.github.io/libastal/astal3/class.Window.html)
222+
instance, position it and handle click events.
223+
Checkout [examples/gtk3/popover](https://github.com/Aylur/ags/tree/main/examples/gtk3/popover)

docs/guide/first-widgets.md

+4-23
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ Lowercase tags are builtin widgets, while capital letter is for custom widgets.
100100

101101
For a list of builtin widgets refer to the source code:
102102

103-
- [gtk3](https://github.com/Aylur/ags/blob/v3/lib/src/gtk3/jsx-runtime.ts)
104103
- [gtk4](https://github.com/Aylur/ags/blob/v3/lib/src/gtk4/jsx-runtime.ts)
104+
- [gtk3](https://github.com/Aylur/ags/blob/v3/lib/src/gtk3/jsx-runtime.ts)
105105

106106
## Displaying Data
107107

@@ -273,8 +273,6 @@ re-renders when that state changes.
273273
Use the `bind` function to create a `Binding` object from a `State` or a
274274
regular `GObject` and one of its properties.
275275

276-
Here is an example of a Counter widget that uses a `State` as its state:
277-
278276
:::code-group
279277

280278
```tsx [State example]
@@ -335,35 +333,20 @@ a string, so it needs to be turned to a string first.
335333
`State` has a shorthand for `bind(state).as(transform)`
336334

337335
```tsx
338-
const s = new State(0)
336+
const state = new State(0)
339337
const transform = (v: number) => v.toString()
340338

341339
return (
342340
<box>
343341
{/* these two are equivalent */}
344-
<label label={bind(v).as(transform)} />
345-
<label label={v(transform)} />
342+
<label label={bind(state).as(transform)} />
343+
<label label={state(transform)} />
346344
</box>
347345
)
348346
```
349347

350348
:::
351349

352-
Here is an example of a battery percent label that binds the `percentage`
353-
property of the Battery object from the
354-
[Battery Library](/guide/libraries/battery):
355-
356-
```tsx
357-
import AstalBattery from "gi://AstalBattery"
358-
import { bind } from "astal"
359-
360-
function BatteryPercentage() {
361-
const bat = AstalBattery.get_default()
362-
363-
return <label label={bind(bat, "percentage").as((p) => p * 100 + " %")} />
364-
}
365-
```
366-
367350
## Dynamic rendering
368351

369352
When you want to render based on a value, you can use the `<With>` component.
@@ -389,8 +372,6 @@ return (
389372
> In a lot of cases it is better to always render the component and set its
390373
> `visible` property instead
391374
392-
<!-- -->
393-
394375
> [!WARNING]
395376
> When the value changes and the widget is re-rendered the previous one is removed
396377
> from the parent component and the new one is **appended**. Order of widgets are

docs/guide/quick-start.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { Poll } from "ags/state"
2828
app.start({
2929
main() {
3030
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
31-
const clock = new Poll("", 1000, "data")
31+
const clock = new Poll("", 1000, "date")
3232

3333
return (
3434
<window visible anchor={TOP | LEFT | RIGHT}>

0 commit comments

Comments
 (0)