GLib bindings for Rust.
Alongside GLib bindings, this crate also includes the infrastructure to
subclass GObject
for extending libraries like GTK+. A code example can
be found in the documentation of this crate in the subclass
module.
MIT
DEPRECATED, use https://github.com/gtk-rs/gtk-rs-core repository instead!
Home Page: http://gtk-rs.org/
License: MIT License
GLib bindings for Rust.
Alongside GLib bindings, this crate also includes the infrastructure to
subclass GObject
for extending libraries like GTK+. A code example can
be found in the documentation of this crate in the subclass
module.
MIT
https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-get-property
There is an empty ObjectExt trait that should receive the appropriate methods.
When passing the result of a include_bytes! macro, which is &'static [u8; N]
, into Bytes::from_static(&'static u8)
it compiles fine but segfaults at runtime with error message:
GLib:ERROR:gvariant-serialiser.c:167:g_variant_serialised_check: assertion failed (alignment & (gsize) serialised.data == 0): (5 == 0)
When you explicitly specify Bytes::from_static(res_bytes.as_ref())
, where as_ref makes [u8, N]
into u8
it works fine.
I forked an example repo and replicated the bug here
git clone https://github.com/alatiera/gresource-gtkrs-example.git
cd gresource-gtkrs-example
cargo run
Crate versions I used:
gio = "0.2"
glib "0.2"
As I am running into issues with the current implementation of Connect
(cfr. gtk-rs/gtk#30), I am looking at the implementation to see if I can pin-point the origin of my issues. However, within that code you can find:
ffi::glue_signal_connect(
self.unwrap_gobject(),
signal_name.borrow_to_glib().0,
Some(trampoline),
user_data_ptr
);
Which can also be found among the FFI defintions:
pub fn glue_signal_connect(g_object: *mut C_GObject,
signal: *const c_char,
func: Option<extern "C" fn()>,
user_data: *const c_void);
What exactly is glue_signal_connect
? I'm asking because I can't seem to find this in Glib.
Furthermore, the (They are used to create the trampolines).Signal
trait seems to have a fetch_cb
method. What should this be used for? As I don't see it being used (directly) at the moment.
Two problems here:
upcast()
works exclusively on the IsA<_>
trait. That is, you can only upcast from A
to B
, if A: IsA<B>
. Upcasting is used (1) for going from a subclass to a parent class, or (2) for going from some class to an interface implemented by it.A: IsA<B>
if both types are represented in Rust.A
according to its signature, but actually returns an object of a subclass X
of A
and X
is not defined anywhere in Rust (might not even be in C headers or anywhere). This is the case for various things in GIO, and GStreamer elements.The same also happens if you have an object of type A
, stored in a variable of type B
(B
is the parent class of A
). A
implements interface C
(and this is statically known) but B
does not. You can't cast from B
to C
currently.
downcast()
currently only works if there is a IsA
relationship statically known between the types. Which fails in the same cases as above.I would suggest that we deprecate/remove these traits and instead just have
cast()
function that can cast between anything and checks at runtime (similar to downcast right now). This could be in ObjectExt
also. The distinction between upcast and downcast is not really relevant here as you always have to check at runtime anyway for interfaces at least, and it can always fail.static_upcast()
function (equivalent to the old upcast()
) which only looks at the IsA<_>
traits, and can because of that only support statically known upcasting (and never downcasting). This could be a free function, a new trait that is implemented for everything that implements IsA<_>
, ...static_downcast
(equivalent to the old downcast
) is not really relevant or useful. It would have to check at runtime anyway, like cast()
would, and it would only give very minor (and easily wrong, too restrictive) safety guards by the compiler.Opinions?
Currently glib_wrapper! only allows them for GObjects. Boxed types also have get_type() functions though, and they are important for using them in GValues.
Same for flags and enums.
Can't say exactly, but think it is error. For me this introduce memory leak.
Here call to container function
Line 1257 in d9961b3
but functin is from_glib_full_as_vec, so as i understand it must also transfer owning of items. so it must be from_glib_full_num ?
After fixing a bunch of configuration-related compiler errors, I was presented with this:
note: C:\users\austin\Rust\gdk\target\debug\deps\libglib-fcaf29643d8f5d21.rlib(glib-fcaf29643d8f5d21.o): In function `glib::permission::Permission::get_allowed':
C:\msys64\home\Austin\.cargo\git\checkouts\glib-27833b4b6d67ca46\master\src/permission.rs:27: undefined reference to `g_permission_get_allowed'
C:\users\austin\Rust\gdk\target\debug\deps\libglib-fcaf29643d8f5d21.rlib(glib-fcaf29643d8f5d21.o): In function `glib::permission::Permission::get_can_acquire':
C:\msys64\home\Austin\.cargo\git\checkouts\glib-27833b4b6d67ca46\master\src/permission.rs:34: undefined reference to `g_permission_get_can_acquire'
C:\users\austin\Rust\gdk\target\debug\deps\libglib-fcaf29643d8f5d21.rlib(glib-fcaf29643d8f5d21.o): In function `glib::permission::Permission::get_can_release':
C:\msys64\home\Austin\.cargo\git\checkouts\glib-27833b4b6d67ca46\master\src/permission.rs:41: undefined reference to `g_permission_get_can_release'
C:\users\austin\Rust\gdk\target\debug\deps\libglib-fcaf29643d8f5d21.rlib(glib-fcaf29643d8f5d21.o): In function `glib::permission::Permission::impl_update':
C:\msys64\home\Austin\.cargo\git\checkouts\glib-27833b4b6d67ca46\master\src/permission.rs:48: undefined reference to `g_permission_impl_update'
C:\users\austin\Rust\gdk\target\debug\deps\libglib-fcaf29643d8f5d21.rlib(glib-fcaf29643d8f5d21.o): In function `glib::value::Value::new':
C:\msys64\home\Austin\.cargo\git\checkouts\glib-27833b4b6d67ca46\master\src/value.rs:36: undefined reference to `create_gvalue'
The g_permission
functions are defined by the GIO library, a separate lib and link unit on Windows. And then create_gvalue()
is an internal function not exported in the GLib headers, at least for me.
This is with the latest Windows x64 release of GTK from here.
Possible solutions:
g_permission
functions to a gio-sys
crate that links to -lgio-2
g_value_init()
instead of create_gvalue()
Hello,
I am trying to compile rrun which uses this library.
When I run cargo build
, cargo throws the following errors:
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:69:18: 69:48 error: unresolved name `gobject_ffi::g_value_set_schar` [E0425]
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:69 unsafe { gobject_ffi::g_value_set_schar(&mut self.inner, v_char) }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:69:18: 69:48 help: run `rustc --explain E0425` to see a detailed explanation
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:74:18: 74:48 error: unresolved name `gobject_ffi::g_value_get_schar` [E0425]
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:74 unsafe { gobject_ffi::g_value_get_schar(&self.inner) }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/uniaika/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.0.4/src/value.rs:74:18: 74:48 help: run `rustc --explain E0425` to see a detailed explanation
Hi,
Is there any reference material for extending/implementing wrapped classes/interfaces using rust structs/impls?
It currently prints the pointer to the GError, but not the actual content of the error. While generally this is fine, for everything implementing std::error::Error this is suboptimal: when observing an error, the standard way of printing it is via the Debug trait (and not Display).
This would be useful for passing around arbitrary Rust objects via GValue and similar things. It's very easy to implement.
@GuillaumeGomez @EPashkin Would you like to have this in glib?
Hello.
I wonder if it is possible to do introspection (i.e. getting the type of the Object
) because I feel like this code could be written in a better way:
pub fn is_enabled(element: &DOMElement) -> bool {
let input_element: Result<DOMHTMLInputElement, _> = element.clone().downcast();
let select_element: Result<DOMHTMLSelectElement, _> = element.clone().downcast();
let textarea_element: Result<DOMHTMLTextAreaElement, _> = element.clone().downcast();
if let Ok(element) = input_element {
!element.get_disabled()
}
else if let Ok(element) = select_element {
!element.get_disabled()
}
else if let Ok(element) = textarea_element {
!element.get_disabled()
}
else {
true
}
}
Or is there a is_a()
method that could be used to avoid these multiple clone
s and downcast
s?
Thanks.
This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic
on IRC to discuss.
You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.
TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.
The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.
Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.
To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright, due to not being a "creative
work", e.g. a typo fix) and then add the following to your README:
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
and in your license headers, if you have them, use the following boilerplate
(based on that used in Rust):
// Copyright 2016 glib Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
It's commonly asked whether license headers are required. I'm not comfortable
making an official recommendation either way, but the Apache license
recommends it in their appendix on how to use the license.
Be sure to add the relevant LICENSE-{MIT,APACHE}
files. You can copy these
from the Rust repo for a plain-text
version.
And don't forget to update the license
metadata in your Cargo.toml
to:
license = "MIT OR Apache-2.0"
I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!
To agree to relicensing, comment with :
I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.
As @alexcrichton noticed yesterday, the IsA<>
trait must be unsafe. Otherwise you could safely implement it e.g. impl IsA<gtk::Button> for gtk::Label
or similarly silly things.
Making the ToGlibPtr
trait unsafe would also solve that, but that one generally seems fine. You can safely convert a gtk::Button
to a *mut gtk_ffi::GtkButton
, you just can't dereference that pointer safely (but you never could do that anyway).
Needed for a project I'm working on. Should be simple to implement I think, so I'm willing to do it as I did for signal_stop_emission*()
.
GKeyFile is missing from the bindings, so a bit hard to use with Rust.
Should these be auto generated or it supposed to be done by hand?
Without specifying the ffi types here, this fails compiling. Specifying them here should be unneeded and I'm not doing that anywhere else (also the [] should be unneeded). Compiler error is the following:
error[E0119]: conflicting implementations of trait `glib::translate::ToGlibPtr<'_, *mut gobject_ffi::GObject>` for type `source::RsSrcWrapper`:
--> gst-plugin/src/source.rs:406:1
|
406 | glib_wrapper! {
| _^
| |_|
| ||
407 | || pub struct RsSrcWrapper(Object<RsSrc>): [gst_base::BaseSrc,
408 | || gst::Element,
409 | || gst::Object,
... ||
415 | || }
416 | || }
| || ^
| ||_|
| |__first implementation here
| conflicting implementation for `source::RsSrcWrapper`
|
= note: this error originates in a macro outside of the current crate
error[E0119]: conflicting implementations of trait `glib::translate::ToGlibPtr<'_, *mut gobject_ffi::GObject>` for type `source::RsSrcWrapper`:
--> gst-plugin/src/source.rs:406:1
|
406 | glib_wrapper! {
| _^
| |_|
| ||
407 | || pub struct RsSrcWrapper(Object<RsSrc>): [gst_base::BaseSrc,
408 | || gst::Element,
409 | || gst::Object,
... ||
415 | || }
416 | || }
| || ^
| ||_|
| |__first implementation here
| conflicting implementation for `source::RsSrcWrapper`
|
= note: this error originates in a macro outside of the current crate
error[E0119]: conflicting implementations of trait `glib::translate::ToGlibPtr<'_, *mut gobject_ffi::GObject>` for type `source::RsSrcWrapper`:
--> gst-plugin/src/source.rs:406:1
|
406 | glib_wrapper! {
| _^
| |_|
| ||
407 | || pub struct RsSrcWrapper(Object<RsSrc>): [gst_base::BaseSrc,
408 | || gst::Element,
409 | || gst::Object,
... ||
415 | || }
416 | || }
| || ^
| ||_|
| |__first implementation here
| conflicting implementation for `source::RsSrcWrapper`
|
= note: this error originates in a macro outside of the current crate
error[E0119]: conflicting implementations of trait `glib::translate::ToGlibPtr<'_, *mut gobject_ffi::GObject>` for type `source::RsSrcWrapper`:
--> gst-plugin/src/source.rs:406:1
|
406 | glib_wrapper! {
| _^
| |_|
| ||
407 | || pub struct RsSrcWrapper(Object<RsSrc>): [gst_base::BaseSrc,
408 | || gst::Element,
409 | || gst::Object,
... ||
415 | || }
416 | || }
| || ^
| ||_|
| |__first implementation here
| conflicting implementation for `source::RsSrcWrapper`
|
= note: this error originates in a macro outside of the current crate
error: aborting due to 4 previous errors
Note that this error happens once for every class it inherits from, and every interface it implements. This suggests that the problem is in this part of the macro:
Lines 461 to 483 in d17431e
<$super_name as $crate::wrapper::Wrapper>::GlibType>
seems to expand to gobject_ffi::GObject
for all of them. But there shouldn't even be an implementation like that.
@GuillaumeGomez @EPashkin Any ideas what could be the cause here? :)
Or maybe @federicomenaquintero who currently is going through all this?
Hello.
When trying to compile a project depending on gtk
(and thus glib
), I get the following error:
Compiling glib v0.0.5
error: internal compiler error: ty_is_local invoked on unexpected type: [type error]
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'Box<Any>', ../src/libsyntax/diagnostic.rs:253
stack backtrace:
1: 0x7f3415555150 - sys::backtrace::tracing::imp::write::h5b6ace072a698e367Et
2: 0x7f341555b945 - panicking::log_panic::_<closure>::closure.40164
3: 0x7f341555b3df - panicking::log_panic::h6d8190bda72bc747Arx
4: 0x7f3415525323 - sys_common::unwind::begin_unwind_inner::h94eea8313ef59f71cys
5: 0x7f340f3fc407 - sys_common::unwind::begin_unwind::begin_unwind::h4274098006826536074
6: 0x7f340f3fd2b6 - diagnostic::_<impl>::bug::h58a7af07988e46b3UNB
7: 0x7f34132ade33 - session::_<impl>::bug::h213087ebc98070c1s5w
8: 0x7f34134c6b16 - middle::traits::coherence::ty_is_local_constructor::h75ac300f619dacd4W6R
9: 0x7f34134c5dab - middle::traits::coherence::ty_is_local::h2152d6a6c9a70efdG5R
10: 0x7f34134c43d9 - middle::traits::coherence::orphan_check_trait_ref::h83d5c3db56fab02akWR
11: 0x7f34134e9c92 - middle::traits::select::_<impl>::candidate_from_obligation::h393efaca65f5af5cMuW
12: 0x7f34134f1e0c - middle::traits::select::_<impl>::evaluate_stack::hf9d672f70e730aff6jW
13: 0x7f34134f0ebe - middle::traits::select::_<impl>::evaluate_predicate_recursively::heb447c75ffd8fe018aW
14: 0x7f34134f2145 - middle::traits::select::_<impl>::evaluate_candidate::_<closure>::closure.99512
15: 0x7f34134f1e8e - middle::traits::select::_<impl>::evaluate_stack::hf9d672f70e730aff6jW
16: 0x7f34134f0ebe - middle::traits::select::_<impl>::evaluate_predicate_recursively::heb447c75ffd8fe018aW
17: 0x7f34134c03fb - middle::traits::coherence::overlap::h26b526550e519e4cYDR
18: 0x7f34134bfcac - middle::traits::coherence::overlapping_impls::hb6802312fbcad60fYBR
19: 0x7f3414241645 - coherence::overlap::_<impl>::check_if_impls_overlap::h63d63c4df3f6d9b3zYA
20: 0x7f34140f7c41 - coherence::check_coherence::hd5f57cb933e3799e3UB
21: 0x7f34140f04c9 - check_crate::h9b4d8810bf169e71PpD
22: 0x7f3415a4c85d - driver::phase_3_run_analysis_passes::_<closure>::closure.25151
23: 0x7f3415a303c3 - middle::ty::context::_<impl>::create_and_enter::create_and_enter::h9927264928927630959
24: 0x7f3415a2b77b - driver::phase_3_run_analysis_passes::h9394773446094229087
25: 0x7f34159fd662 - driver::compile_input::h1f61a158c52a8220cca
26: 0x7f34159ef1db - run_compiler::hd87e09e88aee8063zvc
27: 0x7f34159ec206 - sys_common::unwind::try::try_fn::try_fn::h2507626549812350305
28: 0x7f3415552de8 - __rust_try
29: 0x7f341554b24b - sys_common::unwind::try::inner_try::h4958b46263018defKus
30: 0x7f34159ec554 - boxed::_<impl>::call_box::call_box::h4575607361476731753
31: 0x7f341555a473 - sys::thread::_<impl>::new::thread_start::h8f57d9485bcbc18flNw
32: 0x7f340ec4f4a3 - start_thread
33: 0x7f34151ea13c - clone
34: 0x0 - <unknown>
Could not compile `glib`.
To learn more, run the command again with --verbose.
I use rustc 1.6.0-nightly (9303055f3 2015-11-19).
Thanks to fix this issue.
https://github.com/gtk-rs/glib/blob/d8d5df3f9455d885f85740a5b08aa507e2dacb99/src/value.rs
I see that we can do set_long
can we do set_double, it is a private function, is that for a reason? I am not able to otherwise set glib value to a double; any ideas here?
It would be very useful to provide accessors to the raw pointers to the glib/gtk objects underlying the wrappers added by gtk-rs. This would make it easier to port applications to use parts of gtk-rs while not all needed functionality has been wrapped yet.
See gtk-rs/gtk#550 with potential solution based on SendCell
(implementation linked there).
Because glib::idle_add()
and others require Send
on the closure (correctly), no GTK objects (which are non-Send
) can be used in there. GTK has a workaround by having special gtk::idle_add()
, but adding variants for everything else that do this is not scaling.
And it does not solve the problem of actually wanting to pass a GTK object from another thread into the closure, but only use it in the closure (which is valid because it's all from the main thread).
My suggestion would be that we either get something like SendCell
into glib, or I could also make it a separate crate and we point people with such problems to that.
SendCell code: https://github.com/sdroege/gstreamer-rs/blob/5676aeb3efaabe263f2c524746032c8441671830/examples/src/bin/gtksink.rs#L126
Can't build it with beta because of #![feature(alloc)]
and they don't plan to make alloc
stable in 1.0 either.
... simply because library name is GLib in the Gir.toml and multiple can't be specified :) What should we do about this?
Having bindings for the i18n functions (i.e. gettext) would be very useful.
This isn't quite at the top of my todo list so I'm inclined to mark all methods as unsafe pending a rewrite.
Otherwise the process just silently exits with error code 101 without anybody knowing what's going on.
Hello.
It seems the implementation of FromGlibPtrFull
for Value
causes an invalid free:
I updated my pull request #173 to use the content of the pull request #172 by @sdroege and it now segfaults.
Here is the output of valgrind
:
==10812== Invalid free() / delete / delete[] / realloc()
==10812== at 0x4C2C14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10812== by 0x148D8C: _$LT$glib..value..Value$u20$as$u20$glib..translate..FromGlibPtrFull$LT$$BP$mut$u20$gobject_sys..GValue$GT$$GT$::from_glib_full::h20d87ff77f270988 (value.rs:265)
==10812== by 0x144D7E: glib::closure::Closure::invoke::h11509ea4ef43c853 (closure.rs:84)
==10812== by 0x145D99: glib::closure::tests::test_closure::hc4c274cd29409c69 (closure.rs:159)
==10812== by 0x15C5A1: {{closure}} (lib.rs:1451)
==10812== by 0x15C5A1: call_once<closure,(())> (ops.rs:2663)
==10812== by 0x15C5A1: _$LT$F$u20$as$u20$test..FnBox$LT$T$GT$$GT$::call_box::hbc50e286d45b763c (lib.rs:140)
==10812== by 0x197D4A: __rust_maybe_catch_panic (lib.rs:98)
==10812== by 0x1507A3: try<(),std::panic::AssertUnwindSafe<closure>> (panicking.rs:433)
==10812== by 0x1507A3: catch_unwind<std::panic::AssertUnwindSafe<closure>,()> (panic.rs:361)
==10812== by 0x1507A3: {{closure}} (lib.rs:1390)
==10812== by 0x1507A3: std::sys_common::backtrace::__rust_begin_short_backtrace::h0399439aaa17b770 (backtrace.rs:136)
==10812== by 0x151542: {{closure}}<closure,()> (mod.rs:363)
==10812== by 0x151542: call_once<(),closure> (panic.rs:296)
==10812== by 0x151542: std::panicking::try::do_call::h0422a104882722ca (panicking.rs:454)
==10812== by 0x197D4A: __rust_maybe_catch_panic (lib.rs:98)
==10812== by 0x1573AC: try<(),std::panic::AssertUnwindSafe<closure>> (panicking.rs:433)
==10812== by 0x1573AC: catch_unwind<std::panic::AssertUnwindSafe<closure>,()> (panic.rs:361)
==10812== by 0x1573AC: {{closure}}<closure,()> (mod.rs:362)
==10812== by 0x1573AC: _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h8e8eb9ac7178c465 (boxed.rs:648)
==10812== by 0x18FB65: call_once<(),()> (boxed.rs:658)
==10812== by 0x18FB65: start_thread (thread.rs:21)
==10812== by 0x18FB65: std::sys::imp::thread::Thread::new::thread_start::h227b2afaa9316a8d (thread.rs:84)
==10812== by 0x57B02E6: start_thread (in /usr/lib/libpthread-2.25.so)
==10812== Address 0x71fef40 is on thread 2's stack
==10812== in frame #2, created by glib::closure::Closure::invoke::h11509ea4ef43c853 (closure.rs:68)
==10812==
If I remove this line:
glib_ffi::g_free(ptr as *mut c_void);
in the implementation, the test passes.
I think it makes sense to remove this line since Value::unitialized()
returns a zeroed struct, so this tries to free a null pointer, right?
Also, there's some unused imports that can be removed.
.cargo/registry/src/github.com-0a35038f75765ae4/glib-0.0.4/src/signal.rs:12:53: 12:61 error: mismatched types:
expected `*mut gobject_sys::GObject`,
found `*mut libc::types::common::c95::c_void`
(expected struct `gobject_sys::GObject`,
found enum `libc::types::common::c95::c_void`) [E0308]
.cargo/registry/src/github.com-0a35038f75765ae4/glib-0.0.4/src/signal.rs:12 let handle = gobject_ffi::g_signal_connect_data(receiver, signal_name.to_glib_none().0,
^~~~~~~~
.cargo/registry/src/github.com-0a35038f75765ae4/glib-0.0.4/src/signal.rs:12:53: 12:61 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
Could not compile `glib`.
Does a plan exist to support GResource apis?
Nowadays some of gtk apis have _from_resource variations, so embedding GResource bytes with include_bytes! is convinient in gtk-rs programming.
Currently I use GResource with -sys crates directly, but it's ugly (the code is below).
let res_bytes = include_bytes!("resources/resources.gresource");
unsafe {
// gbytes and resource will not be freed
let gbytes = glib_sys::g_bytes_new(res_bytes.as_ptr() as *const libc::c_void, res_bytes.len());
let resource = gio_sys::g_resource_new_from_data(gbytes, std::ptr::null_mut());
gio_sys::g_resources_register(resource);
}
(the full project source is here: https://github.com/sunnyone/gresource-gtkrs-example)
I lack the knowledge of Rust to create GResource binding, especially a part to determine correct lifetime of GResource. I hope a GResource binding will be implemented smartly.
I'm getting this error when trying to build glib (I'm trying to do cargo doc
for cairo-rs
).
Compiling glib v0.0.3 (https://github.com/gtk-rs/glib#607030ed)
src/patterns.rs:33:5: 42:6 error: non-exhaustive patterns: `Mesh` not covered [E0004]
src/patterns.rs:33 match pattern_type {
src/patterns.rs:34 PatternType::Solid => Box::new(SolidPattern::wrap(ptr)) as Box<Pattern>,
src/patterns.rs:35 PatternType::Surface => Box::new(SurfacePattern::wrap(ptr)) as Box<Pattern>,
src/patterns.rs:36 PatternType::LinearGradient => Box::new(LinearGradient::wrap(ptr)) as Box<Pattern>,
src/patterns.rs:37 PatternType::RadialGradient => Box::new(RadialGradient::wrap(ptr)) as Box<Pattern>,
src/patterns.rs:38 #[cfg(cairo_1_12)]
I.e. what the connect functions return. These are not arbitrary u64 but have a meaning, and we probably want to prevent people from mixing these with other u64 (or doing arithmetic on them, etc).
Might also make sense to not implement Copy/Clone on them (and the same for SourceId), as you can only really disconnect a signal handler once.
Sorry, it seems that safe Rust version of g_object_bind_property and other property binding functions are currently missing...
We don't have 'em yet.
let mut meh: TypedValue<i32> = (&123i32).into();
let meh2: Value = (&1u8).to_value();
*meh = meh2;
And suddenly we have a TypedValue<i32>
that actually contains an u8
.
Bindings for g_log()
and its derivatives (g_debug()
, g_warning()
, ...) are still missing.
One can of course use Rust's print!()
macro's, but that means either manually parsing the G_DEBUG variable or the similar options like --g-debug, or ignoring them.
I'm thinking of creating a gio
crate to avoid some workarounds and special-casing. Most of the G*
object hierarchy (e.g. GApplication
, GMenu
) lives in gio
. Generating them will be more straightforward if they have their own crate.
There's an additional wrapper complication that needs to be introduced. Turns out I've pushed convenience of declarations too far and coherence prevents cross-crate inheritance now. This can't work:
glib_wrapper! {
pub struct Application(Object<ffi::GtkApplication>): glib::Application;
...
A more extended version would look like this:
glib_wrapper! {
pub struct Application(Object<ffi::GtkApplication>): [glib::Application => gio_sys::GApplication];
The confusing discrepancy between glib
and gio
is apparent here.
I'm working on gnome-class, the code generator for gobject implementations in Rust.
If I have Gtk::Widget, I can conveniently obtain the type of the ffi struct that is wrapped (gtk_ffi::GtkWidget) by writing
<Gtk::Widget as glib::wrapper::Wrapper>::GlibType
However, I would like to be able to get to ffi:GtkWidgetClass as well. This is so that the gobject implementation can access parent_class.finalize(), for example.
Right now we have
impl $crate::wrapper::Wrapper for $name {
type GlibType = $ffi_name;
}
inside the macro glib_object_wrapper!()
. Could we also have a "type GlibClassType = $ffi_class_name
" in the Wrapper
trait?
This leads to the question of how to obtain that. I think we may need to modify glib_wrapper!()
so that it can be called as
glib_wrapper! {
pub struct Widget(Object<ffi::GtkWidget, ffi::GtkWidgetClass>): Buildable;
match fn {
get_type => || ffi::gtk_widget_get_type(),
}
}
i.e. with an extra "argument" inside the Object<>.
This is obviously an API break. I'm open to ideas :)
Some places in the documentation mention interfaces, for example this bit in the docs for IsA<>
/// For instance, since originally `GtkWidget` is a subclass of `GObject` and
/// implements the `GtkBuildable` interface, `gtk::Widget` implements
/// `IsA<glib::Object>` and `IsA<gtk::Buildable>`.
I was looking at where the IsA trait is implemented for the various object types. Let's look at the docs for the macro that generates it...
/// glib_wrapper! {
/// /// A container with just one child.
/// pub struct Bin(Object<ffi::GtkBin>): Container, Widget, Buildable;
But in the actual bin.rs there is only this:
glib_wrapper! {
pub struct Bin(Object<ffi::GtkBin>): Container, Widget;
Also, GtkWidget supports Buildable and AtkImplementor (see here), but they are not listed in gtk/src/auto/widget.rs
.
Some other interfaces are declared just fine, however. For example, recent_chooser_widget.rs properly declares Orientable (because of Box), and the RecentChooser iface.
Also, I'm not sure how glib-rs handles calling an interface method on an instance. For example, GTK+ has this code:
void
gtk_recent_chooser_set_sort_func (GtkRecentChooser *chooser,
GtkRecentSortFunc sort_func,
gpointer sort_data,
GDestroyNotify data_destroy)
{
g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
GTK_RECENT_CHOOSER_GET_IFACE (chooser)->set_sort_func (chooser,
sort_func,
sort_data,
data_destroy);
}
That GTK_RECENT_CHOOSER_GET_IFACE()
expands to a call to g_type_interface_peek()
, which returns NULL if the instance is not of a class that supports that interface. I can't find any calls to g_type_interface_peek()
in glib-rs at all :)
I don't think there's a way to get the message from a GError in safe code right now. I need to add this and add a Debug implementation for glib::Error
so I can use it in a Result
.
I can implement a message() -> &str
function to access the field, if that's all that needs to be done.
See e.g. https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/gtksink.rs#L6
It is re-exported from src/lib.rs, so not sure what is missing.
From here - @sdroege suggests that it would be nice to have glib_object_wrapper!() generate
#[repr(C)]
pub struct FooClass(ffi::BarFooClass);
impl IsA<ParentOfFooClass> for FooClass { }
impl IsA<ParentOfParentParentOfFooClass> for FooClass { }
impl Foo {
pub fn get_class(&self) -> &FooClass {
unsafe {
let stash = self.to_glib_none();
let ptr: ffi::Foo = stash.0;
let class = *(ptr as *const *const ffi::BarFooClass);
&*(class as *const FooClass)
}
}
To generate the FooClass
identifier, we either need the concat_idents!() macro, which is a nightly-only feature, or a procedural macro inside glib-rs that generates such an identifier.
Otherwise it seems rather incompatible with error_chain crate.
I get e.g.:
error[E0277]: the trait bound `*mut glib_sys::GError: std::marker::Send` is not satisfied in `errors::Error`
--> src/errors.rs:9:1
|
9 | / error_chain! {
10 | | foreign_links {
11 | | Alsa(alsa::Error);
12 | | IO(std::io::Error);
... |
15 | | }
16 | | }
| |_^ `*mut glib_sys::GError` cannot be sent between threads safely
|
= help: within `errors::Error`, the trait `std::marker::Send` is not implemented for `*mut glib_sys::GError`
= note: required because it appears within the type `glib::boxed::AnyBox<glib_sys::GError>`
= note: required because it appears within the type `glib::boxed::Boxed<glib_sys::GError, glib::error::MemoryManager>`
= note: required because it appears within the type `glib::Error`
= note: required because it appears within the type `errors::ErrorKind`
= note: required because it appears within the type `errors::Error`
= note: required by `error_chain::ChainedError`
= note: this error originates in a macro outside of the current crate
error[E0277]: the trait bound `*mut i8: std::marker::Send` is not satisfied in `glib_sys::GError`
--> src/errors.rs:9:1
|
9 | / error_chain! {
10 | | foreign_links {
11 | | Alsa(alsa::Error);
12 | | IO(std::io::Error);
... |
15 | | }
16 | | }
| |_^ `*mut i8` cannot be sent between threads safely
|
= help: within `glib_sys::GError`, the trait `std::marker::Send` is not implemented for `*mut i8`
= note: required because it appears within the type `glib_sys::GError`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<glib_sys::GError>`
= note: required because it appears within the type `std::boxed::Box<glib_sys::GError>`
= note: required because it appears within the type `glib::boxed::AnyBox<glib_sys::GError>`
= note: required because it appears within the type `glib::boxed::Boxed<glib_sys::GError, glib::error::MemoryManager>`
= note: required because it appears within the type `glib::Error`
= note: required because it appears within the type `errors::ErrorKind`
= note: required because it appears within the type `errors::Error`
= note: required by `error_chain::ChainedError`
= note: this error originates in a macro outside of the current crate
The AppInfo and AppLaunchContext implementations should be moved into this crate.
There is an empty AppInfoExt trait that should receive the appropriate methods. AppLaunchContext
could go into the same module.
Is there any way I could implement mainloop-aware signal for my struct? In glibmm there is sigc which is pretty awesome since it allows to define statically typed signals. In python bindings I could set "gsignals" property. How could I define signals in rust bindings?
Currently only the static variants around the global default main context are exposed. This is useful to have more control
The FileError
enum variant names are cryptic and confusing. We should consider changing them to platform neutral understandable names similarly to std::io::ErrorKind
. See also errno to ErrorKind conversion.
Line 77 in e46aa7f
Line 743 in e46aa7f
It would make sense to use a stack allocated array here for < N parameters to make things more efficient and not have that many allocations per call. N = 10 for example would be sufficient already for 99% of the cases, and only uses up 10*(8+8+8) == 240 bytes of stack memory.
E.g. you can store a gtk::Widget in a GValue and then send it to another thread. GValue is (and should be) Send, but it's content might not be.
A solution might be to have two kinds of Value, one Send and one not. And being able to transform from the Send one to the other, similar to TypedValue.
Lines 562 to 564 in ba748d1
Either as trait objects (which fortunately work for ToValue), or generics. Neither doesn't really make a difference, for you to decide.
Could also use ToValue for ::emit() at least, but as this is more of a plumbing function it is maybe not too useful. And for ::connect() we can't do it anyway, so maybe let's keep the symmetry there.
Comments?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.