Simplification and more of everything
Hello everyone, time for a new release!
This time, this is mostly about stabilization and simplification. It means that gtk-rs
is now
simpler to use and more complete than ever. Let’s take a tour of what’s new(er)!
Macro to make gtk-rs usage far simpler §
A big productivity killer when using gtk-rs
in the past was the requirement to pass cloned
references to objects, or even worse, weak references into signal handler closures. This is still
required but to make it more ergonomic, a new clone!
macro is provided as part of glib
.
See the documentation for various examples on how to use it. The big advantage of the macro is that you don’t have to manually declare new local variables with a different name that are then moved into the closure, but simply have to provide the name of the variable you want to make available in the closure and whether it should be passed as a strong or weak reference. Inside the closure it can then be used as-is and for example upgrading any weak references manually is not necessary. In case of failure of upgrading a weak reference, an optional default return value for the closure can be provided or the closure can be configured to panic.
The macro works on any glib::Object
as well as on any Arc
and Rc
.
As a side-note, it is important to know the difference between strong and weak references and not
simply clone (strong reference) everything. By using strong references everywhere, many GTK
applications (not only in Rust) currently create reference cycles and therefore have memory leaks.
If, for example, you want to pass a reference to your Window
into a Button
’s clicked
signal,
you would create a reference cycle between the window, button, signal handler and again the window.
This would lead to the whole cycle to be kept alive forever and leaked. The solution to this is to
make one of the references a weak reference, in this case the reference to the window that is
passed into the clicked
signal handler. See also the Rc
documentation about
reference cycles.
Subclass §
The “subclass” cargo feature was removed from all crates and is instead enabled by default with
this release. The GObject subclassing support matured a lot over the last months and is ready for
wider usage. A basic example for subclassing gtk::Application
and gtk::ApplicationWindow
can
be found here, another
example using custom glib::Object
subclasses as part of a gtk::ListBox
model can be found
here and various examples
for creating GStreamer elements here.
While there are still subclassing bindings missing for many types, various basic types in the gio
,
gtk
and gstreamer
crates are covered already. If something is missing for you, please let us
know with an issue or, even better, a pull request.
Thanks to subclassing being a first-class citizen of the bindings, there is also an adapter
available for making any std::io::Read
available as gio::InputStream
and any std::io::Write
as gio::OutputStream
: gio::ReadInputStream
and gio::WriteOutputStream
. Adapters in the other
direction are available as gio::InputStream::into_read()
and gio::OutputStream::into_write()
.
Futures §
The futures support was ported to std
Future
s and futures
0.3, and as async/await
is
stabilized now it was also enabled by default. The “futures” feature is not needed anymore.
With the futures support in gio
and other modules it is now possible to write applications making
use of asynchronous I/O with async/await
, which allows writing asynchronous code in a much simpler
way that looks close to the equivalent synchronous code. Check
async/await stable on the official
Rust blog for more details.
An example making use of this with gio
’s asynchronous file reading support can be found
here. While it is
not as streamlined as with native Rust crates like async-std or
tokio because of how the gio
API works, it nonetheless much more convenient
to work with than the previous (but still available) callback-based approach.
Another example that shows integration of gio
with generic Rust futures crates can be found
here . Each
gio::PollableInputStream
and gio::PollableOutputStream
can be converted into an AsyncRead
/
AsyncWrite
, and by this allows integration with the wider Rust async ecosystem. In this case a
gio
TCP connection is wrapped in a TLS connection provided by the async-tls
crate, which uses
rustls
as underlying TLS implementation.
GTK4 §
We have initial GTK4 bindings now, which are the result of @sfanxiang’s GSoC project this year. While not part of this release because GTK4 itself is still not API stable, you can also try it from git. The GTK4 bindings can be found here. Once there are release candidates of GTK4 we will also do alpha releases of the bindings.
Cairo improvements §
The cairo
bindings now consistently return Result
s for various functions instead of sometimes
Option
s, sometimes silently failing. Many cairo
operations return an actual Surface
in an
error state if something goes wrong, and this surface will then (usually silently) fail any future
operations on it. Instead of returning the surface, an Err
is returned now as it should.
GTK Builder improvements §
In gtk::Builder
UI description files it is possible to declare signal handlers for the widgets.
While it’s not possible to connect them automatically to functions in Rust in a safe way, it is now
possible for applications to implement the connection logic themselves based on the information from
the UI description. gtk::Builder::connect_signals_full()
allows to provide closures for each
signal handler name that is given in the UI description.
glib::Value::get
improvements §
glib::Value::get()
was changed to allow distinguishing between the value containing a None
and
trying to get a value of the wrong type out of it. This means that it now returns a Result
, and
also that for types that can’t possibly be None
(e.g. integer types), Value::get_some()
is
provided as a helper to not require unwrapping the returned Option
from the normal Value::get()
.
That’s it for biggest changes. A lot of other small ones are in as well. So enjoy!
Changes §
For the interested ones, here is the list of the merged pull requests:
sys:
- Update with eoan’s gir-files
- Add gtk4 files
- Remove graphene
- Update minimum rust version to 1.39
- Use tempfile in tests
glib:
- New version
- Zeroed
- Fix handling of GValues containing a floating GObject
- Implement FromGlib and ToGlib traits on Pid type
- Mark ByteArray::set_size() as unsafe
- Value::get: return a Result to account for type mismatch…
- Remove tests which panic in signals
- value::GetError: add a constructor and make fields public
- Improve docs.rs documentation
- Remove subclass feature
- Fully qualify inner macros for exported macros…
- Fix invalid cargo key for docs.rs
- Implement Value::transform()
- remove not needed anymore libffi fix
- Use MainContext::with_thread_default() instead of pushing/popping man…
- Update to futures 0.3
- Add clone macro
- Extend clone macro
- Support downgrade on references as well
- Don’t leak missing Safety doc clippy warnings (#538)
- Remove unneeded
allow(clippy::missing_safety_doc)
attributes (538) - Add renaming support
- API additions for connecting non-Send closures and thread-safety fixes to the main context channel and futures
- Remove Send bound from SourceFuture/SourceStream
- KeyFile::get_string() can return a string in error case that still ha…
- Remove glib_floating_reference_guard!() macro
- Manually implement FFI code for GObject instead of using glib_shared_wrapper!
- Fix warnings
- Reexport the Gradient type too.
- Replace mem::uninitialized calls
- Make winapi optional.
- cairo-sys: align win32-surface feature gates with those in cairo
- Improve docs.rs documentation
- Fix invalid cargo key for docs.rs
- Improve cairo library documentation
- Include crate features in docs
- Add lib.rs to ignore purge files
- Add cargo fmt check
- remove not needed anymore libffi fix
- (#251): Surface::create_similar() and friends should return a Result
- SvgSurface: make filename param optional
- Fix boxing in async func
- Improve docs.rs documentation
- better handling of dox feature
- Use IsA for property setters
- Generate builders
- Builder use implemented interfaces properties
- Fix invalid cargo key for docs.rs
- Use tempfile in tests
- Derive Default, Clone for builders
- Regen
atk:
- Improve docs.rs documentation
- Update for new
Value::get
signature - better handling of docs.rs features
- Use IsA for property setters
- Fix invalid cargo key for docs.rs
- remove not needed anymore libffi fix
- Update minimum required rust version
gio:
- Fix docs for manual functions [ci skip]
- New version
- Generate FileEnumerator
- Improve docs.rs documentation
- Update for new
Value::get
signature - settings: add SettingsExtManual Trait for get::<T>/set::<T> fn
- Fix boxing in async func
- Ignore AppInfo::launch_uris_async
- Add support for subclassing Input/OutputStream
- Remove subclass feature
- Use IsA for property setters
- Remove ignoring not generated property
- Fix invalid cargo key for docs.rs
- IsA<Cancellable> generic instead of concrete Option<&Cancellable>
- Fix/silence various clippy warnings and errors
- Change UnixMountPoint getters to not require &mut self
- remove not needed anymore libffi fix
- Don’t re-export glib types
- Regen and prelude fixes
- Update to stabilized futures
- More types
- Don’t reexport prelude content
- Fix use statements in the tests
- Some updates to the I/O streams
- Update GioFuture to not require fragile crate usage by all users anymore
- Derive Default, Clone for builders
- Remove usage of glib_floating_reference_guard!()
- Fix some clippy warnings by removing unused lifetime parameters
- Improve docs.rs documentation
- (#156): Manual implementations of PangoGravity functions
- Improve docs.rs handling
- Fix invalid cargo key for docs.rs
- Add pango-glyph interfaces
- remove not needed anymore libffi fix
- Add PangoAttrSize
- Update for new
Value::get
signature - Improve docs.rs documentation
- Improve docs.rs handling
- Fix invalid cargo key for docs.rs
- remove not needed anymore libffi fix
gdk:
- Fix docs for manual functions [ci skip]
- Fix build after #299
- Improve docs.rs documentation
- Update for new
Value::get
signature - Cairo interactions: auto load Pixbuf & Surface Exts
- Fix boxing in async func
- Fix up cairo interaction extension traits
- better handling of docs.rs features
- Time coord
- Improve get_device_history api
- Fix invalid cargo key for docs.rs
- remove not needed anymore libffi fix
- Generate Keymap bindings
- Don’t reexport prelude content
gtk:
- Fix docs for manual functions [ci skip]
- PadController is disguised so trait don’t needed
- Make PadController::set_action_entries() public so it can actually be…
- Implement Builder::connect_signals_full
- Generate GtkWindowExt::set_geometry_hints
- subclass: Get started on subclassing GtkWidget
- Add support for overriding Widget::draw() virtual method
- subclass: Add subclassing for GtkContainer
- subclass: Add ContainerImpl to prelude
- Add support for subclassing GtkBin and GtkEventBox
- subclass/widget: Add vfuncs between child_notify and draw
- Value get result
- Add support for subclassing GtkWindow and GtkApplicationWindow
- subclass: Add support for subclassing GtkBox
- subclass/application_window: Remove unused imports
- subclass: Add support for subclassing GtkHeaderBar
- subclass: Add support for subclassing GtkDialog
- Fix boxing in async func
- Fix tests for 32bit windows
- Improve docs.rs documentation
- ShortcutLabel
- Remove subclass feature
- Use IsA for property setters
- Builder use implemented interfaces properties
- Fix invalid cargo key for docs.rs
- Get rid of Uninitialized impl for TargetEntry
- subclass: Implement subclassing for GtkStack
- NativeDialog: have run return ResponseType
- Warn on macos when initializing from non_main_thread
- Fix format issue
- remove not needed anymore libffi fix
- subclass: Always allow to override the vfuns of classes
- Fix various imports to fix the build
- Make AccelGroup::connect() and ::connect_by_path() more usable
- Add renaming for WidgetExt::set_name and BuildableExt::set_name
- Derive Default for builders
- subclass/container: widget in set_focus_child should be Nullable
- subclass/widget: Implement default handling for parent events
- Fix docs for manual functions [ci skip]
- Improve docs.rs documentation
- Fix invalid cargo key for docs.rs
- remove not needed anymore libffi fix
- Fix build and reexports
- Make FontMap::set_default() a static function and allow passing None …
All this was possible thanks to the gtk-rs/gir project as well:
- Add overriding for function trait for manual implemented functions
- Don’t derive Copy, Clone for truncated in sys mode
- Parse “doc-deprecated” tag in alias
- Use new mem::uninitialized API
- Parse “doc-deprecated” tag in class and interface
- Prevent invalid function parameter order on async callback by not enforcing it
- Handle glib::Pid conversions specifically
- Handle doc generation for docs.rs
- Use dox instead of creating new feature
- Migrate property getters to new signature for
Value::get
- Refactor Imports
- Add flag to disable future generation
- Add link to gir reference
- Add link to schema for .gir files
- Fall back for “type-name” for objects
- Use IsA for property setters for non-final objects
- Correctly detect not generated builders
- Class builder includes properties of implemented interfaces
- Docs rs
- Use Box<dyn Error> instead of Box<Error>
- Remove some duplicate clone calls
- Fix merge conflict
- Allow nullable callbacks
- Add generic parameters to builder methods
- Fix invalid import add
- Remove dependencies
- Extend gpointer to void*
- Fix missing parenthesis on return types
- Add missing from_glib conversion for Pid
- Correctly generate glib::Error import
- Provide the full path to the Inhibit type for signals
- Ignore function-macro tag to prevent warnings
- Generate pinned box futures and use the stabilized futures
- Format
- Migrate to
tempfile
from deprecatedtemdir
- Rename
- Generate GIO futures code a bit more simple and without requiring all…
- Add deriving Default, Clone to builders
- Fix off-by-one line numbers in xmlparser::ErrorEmitter
- generate imports in the same order as rustfmt
Thanks to all of our contributors for their (awesome!) work on this release: