Skip to content

Commit 9595221

Browse files
Update blog post
1 parent d3c1c04 commit 9595221

File tree

1 file changed

+130
-13
lines changed

1 file changed

+130
-13
lines changed

_posts/2024-02-04-new-release.md

Lines changed: 130 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,133 @@ categories: [front, crates]
66
date: 2024-02-04 20:00:00 +0000
77
---
88

9-
* Write intro here *
9+
Although this release happened a few months ago, we finally had time to finish this release blog post!
10+
11+
This is a smaller release than usual, bringing some nice quality of life improvements.
12+
13+
Enjoy!
1014

1115
### gtk-rs-core
1216

13-
* Removal of glib channels
14-
* Removal of re-exported once_cell crate, use `std::cell::OnceCell` / `std::sync::OnceLock`
15-
* Re-organized traits in glib
16-
* Dynamic types support
17+
#### Removal of glib channels
18+
19+
In this release the `glib::MainContext::channel()` function was removed, together with the corresponding sender/receiver types. In many cases this API has led to overly complicated code in applications because people tried to develop state machines via callbacks, instead of simply making use of async Rust for that purpose.
20+
21+
Instead of using the main context channel, the new way of passing values between other threads and the main thread is by using any of the many async channel implementations. Examples for this are the [async-channel](https://docs.rs/async-channel) crate, the MPSC channels from tokio or async-std, the task/thread join handles of both, the [flume](https://docs.rs/flume) crate, ...
22+
23+
For example, the following code:
24+
25+
```rust
26+
let (sender, receiver) = glib::MainContext::channel(glib::Priority::DEFAULT);
27+
receiver.attach(Some(&glib::MainContext::default()), move |msg| do_things(msg));
28+
29+
sender.send(MyMessage);
30+
```
31+
32+
Could be rewritten like this with the `async-channel` crate:
33+
34+
```rust
35+
let (sender, receiver) = async_channel::unbounded();
36+
glib::MainContext::default().spawn_local(async move {
37+
while let Ok(msg) = receiver.recv().await {
38+
do_things(msg);
39+
}
40+
});
41+
42+
sender.send_blocking(MyMessage).expect("Channel closed");
43+
```
44+
45+
#### Removal of re-exported once_cell crate, use `std::cell::OnceCell` / `std::sync::OnceLock`
46+
47+
<!-- need to write something -->
48+
49+
#### Re-organized traits in glib
50+
51+
<!-- need to write something -->
52+
53+
#### Dynamic types support
54+
55+
Let's say you want to create a plugin to add some features or to customize some application. `object_class_dynamic`, `object_interface_dynamic `, `enum_dynamic ` and `flags_dynamic ` are macro helper attributes to make your types dynamic.
56+
57+
```Rust
58+
// My object types
59+
#[derive(Default)]
60+
pub struct MyType;
61+
62+
#[glib::object_subclass]
63+
#[object_subclass_dynamic]
64+
impl ObjectSubclass for MyType { ... }
65+
66+
// My interfaces
67+
pub struct MyInterface {
68+
parent: glib::gobject_ffi::GTypeInterface,
69+
}
70+
71+
#[glib::object_interface]
72+
#[object_interface_dynamic]
73+
unsafe impl ObjectInterface for MyInterface { ... }
74+
75+
// My enums
76+
#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
77+
#[enum_type(name = "MyModuleEnum")]
78+
#[enum_dynamic]
79+
enum MyModuleEnum { ... }
80+
81+
// My flags
82+
#[glib::flags(name = "MyFlags")]
83+
#[flags_dynamic]
84+
enum MyFlags { ... }
85+
```
86+
87+
Your plugin code has to implement the `TypePlugin` interface or to extend the `TypeModule` type in order to register or unregister your dynamic types when the module (or plugin) is loaded or unloaded.
88+
89+
```Rust
90+
#[derive(Default)]
91+
pub struct MyModule;
92+
93+
#[glib::object_subclass]
94+
impl ObjectSubclass for MyModule { ... }
95+
96+
impl ObjectImpl for MyModule {}
97+
98+
impl TypePluginImpl for MyModule {}
99+
100+
impl TypeModuleImpl for MyModule {
101+
fn load(&self) -> bool {
102+
// registers my plugin types as dynamic types.
103+
let my_module = self.obj();
104+
let type_module: &glib::TypeModule = my_module.upcast_ref();
105+
MyInterface::on_implementation_load(type_module)
106+
&& MyType::on_implementation_load(type_module)
107+
&& MyEnum::on_implementation_load(type_module)
108+
&& MyFlags::on_implementation_load(type_module)
109+
}
110+
111+
fn unload(&self) {
112+
// marks my plugin types as unregistered.
113+
let my_module = self.obj();
114+
let type_module: &glib::TypeModule = my_module.upcast_ref();
115+
MyFlags::on_implementation_unload(type_module);
116+
MyEnum::on_implementation_unload(type_module);
117+
MyType::on_implementation_unload(type_module);
118+
MyInterface::on_implementation_unload(type_module);
119+
}
120+
}
121+
```
122+
123+
By default dynamic types are registered when the system loads your plugin. In some cases, it could be useful to postpone the registration of a dynamic type on the first use. This can be done by setting `lazy_registration = true`:
124+
125+
```Rust
126+
// My object types
127+
#[derive(Default)]
128+
pub struct MyType;
129+
130+
#[glib::object_subclass]
131+
#[object_subclass_dynamic(lazy_registration = true)]
132+
impl ObjectSubclass for MyType { ... }
133+
```
134+
135+
For more complex cases, see the documentation [glib::object_subclass](https://docs.rs/glib/latest/glib/attr.object_subclass.html), [glib::object_interface](https://docs.rs/glib/latest/glib/attr.object_interface.html), [glib::Enum](https://docs.rs/glib/latest/glib/derive.Enum.html), [glib::flags](https://docs.rs/glib/latest/glib/attr.flags.html), [glib::subclass::type_module::TypeModuleImpl](https://docs.rs/glib/latest/glib/subclass/type_module/trait.TypeModuleImpl.html) and [glib::subclass::type_plugin::TypePluginImpl](https://docs.rs/glib/latest/glib/subclass/type_plugin/trait.TypePluginImpl.html).
17136

18137
### gtk4-rs
19138

@@ -22,7 +141,7 @@ date: 2024-02-04 20:00:00 +0000
22141

23142
[gtk4-rs](https://github.com/gtk-rs/gtk4-rs):
24143

25-
* [gtk: Don't propogate unused argument](https://github.com/gtk-rs/gtk4-rs/pull/1591)
144+
* [gtk: Don't propagate unused argument](https://github.com/gtk-rs/gtk4-rs/pull/1591)
26145
* [examples: Add example for About Dialog](https://github.com/gtk-rs/gtk4-rs/pull/1589)
27146
* [gtk::show\_about\_dialog: Set hide\_on\_close](https://github.com/gtk-rs/gtk4-rs/pull/1588)
28147
* [Regen with ffi workspacecs usage](https://github.com/gtk-rs/gtk4-rs/pull/1587)
@@ -74,7 +193,6 @@ date: 2024-02-04 20:00:00 +0000
74193
* [Add new Path APIs](https://github.com/gtk-rs/gtk4-rs/pull/1463)
75194
* [book: Extend memory management chapter](https://github.com/gtk-rs/gtk4-rs/pull/1459)
76195
* [Untangle docsrs attribute from features](https://github.com/gtk-rs/gtk4-rs/pull/1454)
77-
* [gtk4-macro: Bump quick-xml to 0.30](https://github.com/gtk-rs/gtk4-rs/pull/1453)
78196
* [Impl Write on text buffers](https://github.com/gtk-rs/gtk4-rs/pull/1452)
79197
* [gdk: Add missing Clipboard::set](https://github.com/gtk-rs/gtk4-rs/pull/1450)
80198
* [Use `derived_properties` macro](https://github.com/gtk-rs/gtk4-rs/pull/1434)
@@ -96,7 +214,7 @@ date: 2024-02-04 20:00:00 +0000
96214
* [gio: Don't wrongly cast DataInputStream byte arrays to a const pointer](https://github.com/gtk-rs/gtk-rs-core/pull/1238)
97215
* [Simplify pointer casts](https://github.com/gtk-rs/gtk-rs-core/pull/1233)
98216
* [glib: Remove deprecated paramspec constructors](https://github.com/gtk-rs/gtk-rs-core/pull/1230)
99-
* [Move from unmaintained winapi crate to windows-sys](https://github.com/gtk-rs/gtk-rs-core/pull/1226)
217+
* [Windows-specific API bindings that use Windows types were migrated from the unmaintained `winapi` crate to `window-sys`. This might need changes for users of these APIs and require them to migrate too.](https://github.com/gtk-rs/gtk-rs-core/pull/1226)
100218
* [Matchinfo lifetime](https://github.com/gtk-rs/gtk-rs-core/pull/1225)
101219
* [Add `Cargo.lock` to git tracking](https://github.com/gtk-rs/gtk-rs-core/pull/1221)
102220
* [Add support of enums as dynamic types](https://github.com/gtk-rs/gtk-rs-core/pull/1220)
@@ -106,8 +224,8 @@ date: 2024-02-04 20:00:00 +0000
106224
* [gio: Use weak reference to ActionMap when adding action entries](https://github.com/gtk-rs/gtk-rs-core/pull/1208)
107225
* [Add \_full and \_local\_full methods for idle and timeout callbacks that take priority](https://github.com/gtk-rs/gtk-rs-core/pull/1207)
108226
* [Implement ext trait on IsA&lt;T&gt;, don't generate overridden methods](https://github.com/gtk-rs/gtk-rs-core/pull/1204)
109-
* [glib: Implement object class methods via a trait instead of directly …](https://github.com/gtk-rs/gtk-rs-core/pull/1203)
110-
* [Add `spawn_future` and `spawn_future_local` convenience functions](https://github.com/gtk-rs/gtk-rs-core/pull/1201)
227+
* [glib: Implement object class methods via a trait](https://github.com/gtk-rs/gtk-rs-core/pull/1203)
228+
* [New `glib::spawn_future()` and `glib::spawn_future_local()` convenience functions that directly spawn a future on the current thread default's main context, without first having to retrieve it](https://github.com/gtk-rs/gtk-rs-core/pull/1201)
111229
* [glib-macros: Remove unused imports from Properties doc test](https://github.com/gtk-rs/gtk-rs-core/pull/1193)
112230
* [glib-macros: Mark property getters as #\[must\_use\]](https://github.com/gtk-rs/gtk-rs-core/pull/1192)
113231
* [fix glyph string analysis methods that don't need &mut](https://github.com/gtk-rs/gtk-rs-core/pull/1188)
@@ -118,15 +236,14 @@ date: 2024-02-04 20:00:00 +0000
118236
* [Use associated type in memory managers](https://github.com/gtk-rs/gtk-rs-core/pull/1171)
119237
* [add support of module types](https://github.com/gtk-rs/gtk-rs-core/pull/1169)
120238
* [image: Switch to latest fedora stable](https://github.com/gtk-rs/gtk-rs-core/pull/1163)
121-
* [gio: Fix panics if `PollableInputStream` / `PollableOutputStream` ret…](https://github.com/gtk-rs/gtk-rs-core/pull/1159)
239+
* [gio: Fix panics in `PollableInputStream` / `PollableOutputStream`](https://github.com/gtk-rs/gtk-rs-core/pull/1159)
122240
* [Added bindings for Gio.DBusObjectManager, Gio.DBusObjectManagerClientFlags](https://github.com/gtk-rs/gtk-rs-core/pull/1156)
123241
* [Disentangle docsrs and features](https://github.com/gtk-rs/gtk-rs-core/pull/1154)
124242
* [Add typos workflow](https://github.com/gtk-rs/gtk-rs-core/pull/1153)
125243
* [gio: Set missing annotations for new FileInfo apis](https://github.com/gtk-rs/gtk-rs-core/pull/1151)
126244
* [Add support for ext\_trait in properties macro](https://github.com/gtk-rs/gtk-rs-core/pull/1149)
127245
* [glib: Bind `g_unichar` APIs](https://github.com/gtk-rs/gtk-rs-core/pull/1146)
128246
* [Add object\_subclass example](https://github.com/gtk-rs/gtk-rs-core/pull/1145)
129-
* [glib: Re-introduce an event propagation specific type](https://github.com/gtk-rs/gtk-rs-core/pull/1144)
130247
* [Fix docs of `glib::derived_properties`](https://github.com/gtk-rs/gtk-rs-core/pull/1143)
131248
* [Fix panic in gio InputStream](https://github.com/gtk-rs/gtk-rs-core/pull/1140)
132249
* [Don't generate unit tuple in clone macro as default-return value](https://github.com/gtk-rs/gtk-rs-core/pull/1138)
@@ -152,7 +269,7 @@ All this was possible thanks to the [gtk-rs/gir](https://github.com/gtk-rs/gir)
152269
* [Add trait\_name to API docs](https://github.com/gtk-rs/gir/pull/1489)
153270
* [Fix docsrs](https://github.com/gtk-rs/gir/pull/1487)
154271
* [codegen: Replace ControlFlow with Propagation](https://github.com/gtk-rs/gir/pull/1485)
155-
* [codgen: generate doc\_alias for static\_type](https://github.com/gtk-rs/gir/pull/1143)
272+
* [codegen: generate doc\_alias for static\_type](https://github.com/gtk-rs/gir/pull/1143)
156273

157274
Thanks to all of our contributors for their (awesome!) work on this release:
158275

0 commit comments

Comments
 (0)