smithay / wayland-rs Goto Github PK
View Code? Open in Web Editor NEWRust implementation of the wayland protocol (client and server).
License: MIT License
Rust implementation of the wayland protocol (client and server).
License: MIT License
So since by default Wayland doesn't show any cursor I wanted to make that work for my app.
I was looking at https://docs.rs/wayland-client/0.7.6/wayland_client/protocol/wl_pointer/struct.WlPointer.html#method.set_cursor and apparently that just registers a surface as a cursor. I'm assuming that I can now render my cursor using a normal WlShmPool.
However set_cursor
requires not only a WlSurface (which shouldn't be a problem), but also a WlPointer. This WlPointer doesn't seem to get exported to wayland_env and the only way I can find how to acquire such a WlPointer object would be using an event handler like wl_pointer::Handler::enter
.
I now want to know if I really need to register an event handler for the mouse to enter the window to pass that to my set_cursor method for registering a surface which will then draw my cursor.
This seems a little odd to me so I just wanted to know if there is any other way of doing this.
It'll be required to provide a proper concurrent implementation
reminder:
wl_display_dispatch
and wl_display_dispatch_queue
are not thread-safe and should only be used if a single thread handles the connexion to the compositorwl_display_prepare_read{_queue}
, wl_display_read_events
, etc...EventIterator
, which are always threadsafe. (any event_queue can dispatch to any eventiterator)I write some code like this when I try to implement a surface handler.
fn frame(&mut self,
evqh: &mut EventLoopHandle,
client: &Client,
resource: &WlSurface,
callback: WlCallback) {
thread::spawn(move || {
callback.done(mills as u32);
});
}
However, the wayland client can not get the callback done event.
BTW, those code (without a new thread) can work.
fn frame(&mut self,
evqh: &mut EventLoopHandle,
client: &Client,
resource: &WlSurface,
callback: WlCallback) {
callback.done(mills as u32);
}
It seems that we can not call callback.done
in a new thread. I think that will be a problem, because we will store callback and call the done event after some duration when we write a real world compositor.
Do you have some suggestion about this? ๐
This code errors out with a [wayland-client error] Dispatcher got called for a message on a non-managed object.
https://gist.github.com/ripread/6defcb029653faff45c577d16f913d3d
When inspecting dispatch_func, _impl
is a pointer to some stack value as opposed to the static RUST_MANAGED. Changing compositor.rs:21 to evqh.register<...> fixes the issue (although it does error out because of the null buffer).
This can also be seen in smithay:shm:mod.rs:220. Attempting to wl_shm_pool_create_buffer(...) in client code gives the same non-managed object error, and changing this line to evqh.register<...> fixes the issue, although now the destructor isn't being called.
Use git-tags and all, to not rely only on crates.io.
Doing this will most likely cause synchronizing the versions of Wayland-client, wayland-sys and wayland-scanner, which would not be an aberration, as they are very linked together.
This has bugged me for some time now, so I'm asking for outside input.
The wayland C library has a very callback oriented design: when you create an object, you register several functions to handle its events, in the form
void event_vallback(wl_proxy* object, void* user_data, ...) { /* .. */ }
This works in C because the language is ok with having pointers all other the place and shared mutable globals and all, which is obviously not an option with Rust.
My first attempt at this lib (v0.1
and v0.2
) was to just copy this design, and let the user provide closures for the callbacks. For safety reasons, closures had to be Send+Sync+'static
, because wayland is supposed to be threadsafe, which led to a nightmare to handle program state, with lots of Arc<Mutex<_>>
even on single-threaded programs, which is obviously bad.
Second attempt (v0.3
to v0.6
) wraps the events into an EventIterator
, letting the user of the lib handle the dispatching themselves, and thus side stepping the issue with previous attempts.
However this approach has its share of issues:
wayland-client
, as the events must be integrated in the Event
enumwayland-server
: server-side, the lifetime of all protocol objects is controlled by the client, and thus is not really representable server-side out of a callback-based design.All this makes me not completely happy with the current design. Especially given I'd like as much as possible to share a common design between wayland-client
and wayland-server
, and make it easy to use 3rd party protocol extensions. As such, I'm thinking about going back to callback-based design, but different from the first one.
Rather go by traits to define handlers. Probably one trait for each wayland object. The use would then give to the lib one or several objects implementing the appropriate handler traits, and let it do the dispatching of events. The interest of this approach is that as the lib has ownership of the object, all handler methods can take &mut self
without need for more synchronization mechanisms, the rest is fully guaranteed by the wayland C library.
The two central methods of the EventLoop
interface would probably be something like that
impl<S> EventLoop<S> {
/// Handle all wayland pending events and dispatch them to appropriate handlers
fn dispatch(&smut self) { /* ... */ }
/// Get access to the internal state, to handle non-wayland events for example
fn get_state(&mut self) -> &mut S { /* ... */ }
}
Here, the Rust borrowing rules can guarantee that no callback can be called while a reference to the state is held elsewhere, as callbacks are called during the execution of the dispatch(...)
method. Note that the wayland C library also provide the necessary mechanisms to have more than one event-loop, and assign each wayland object to the appropriate one (for example to handle keyboard and drawing events in different threads).
Now, I have still some unresolved questions about this:
In the current code, there is a big safety hole around destructors:
Wayland Proxies/Resources objects do not have a Drop
impl. The rationale behind this is that you don't need to keep them around if the reference provided to you in the handler methods is enough, this stays close to the design of the original C library.
However, there are destructor events. So for now, once you've called a destructor method or received a destructor event, you must not use the object again, or it may completely mess up the internal state of the C library.
This is obviously unsafe, but without any unsafe keyword. But I can't find a way to handle this properly which isn't either very cumbersome for the user of the libs, or adds significant overhead.
My ideas for now:
There is still a lot missing
All is in the title
https://crates.io/crates/wayland-client is 0.5.10 which still depends on dlib 0.2.0
That makes it conflict with wayland-kbd which depends on dlib 0.3.0
Sorry if this is off-topic, couldn't find a better place to ask this / reach you.
I have implemented the unstable redshift Wayland protocol in Way Cooler recently, but I found it a bit difficult to do without dropping down into the primitives exposed by wayland_sys
. I assume part of this is due to wlc, but there were a few things I had to implement that I expected wayland-scanner
to do for me.
For example, I expected wayland-scanner
to make some #[repr(C)]
structs which I could fill in with extern "C"
functions that would trigger when the appropriate request was fired from the client. However, I had to make those myself which I thought a bit strange.
I don't mind working this way, at least until Way Cooler switches to a different compositor framework that will hopefully be less opinionated than wlc, but I wanted to double check I'm not doing this in a very silly way.
I am trying to create an app using this Wayland crate in Rust and ran into the issue that I find the example very hard to build up on.
My goal is to implement the geometry
method of wl_output::Handler
so I would be able to get the current dimensions of the window. Implementing the handler itself is pretty straight forward, but registering it on the EventQueue
seems a little more difficult.
In the example everything is first created in a separate scope and after that the scope is closed and the objects are added. This works since the methods like env.seat.get_pointer()
return new objects and don't rely on the env
anymore. If I want to use env.output
however I always need to keep the env
around which will lead to issues since during the creation of env
event_queue
is mutably borrowed and event_queue.register
requires a mutable borrow, too.
My current code attempt looks like this: http://hastebin.com/uzojuxukuc.rs
All the other stuff like wayland_env!
and declare_handler!
should be fine.
Looking at the example getting the width and height of an output seems really awkward. Is there a simple way to solve this issue?
This issue is to track the support of the core, official protocol
Display
sync
get_registry
Compositor
create_surface
create_region
ShmPool
create_buffer
resize
Shm
create_pool
format
Buffer
release
DataOffer
accept
receive
offer
DataSource
offer
target
send
DataDevice
start_drag
set_selection
data_offer
enter
leave
motion
drop
selection
DataDeviceManager
create_data_source
get_data_device
Shell
get_shell_sruface
ShellSurface
pong
/ event: ping
move
resize
set_toplevel
set_transient
set_fullscreen
set_popup
set_maximized
set_title
set_class
configure
popup_done
Surface
attach
damage
frame
set_opaque_region
set_input_region
commit
set_buffer_transform
set_buffer_scale
enter
leave
Seat
get_pointer
get_keyboard
get_touch
capabilities
name
Pointer
set_cursor
release
enter
leave
motion
button
axis
Keyboard
release
keymap
enter
leave
key
modifiers
repeat_info
Touch
release
down
up
motion
frame
cancel
Output
geometry
mode
done
scale
Region
add
subtract
SubCompositor
get_subsurface
SubSurface
set_position
place_above
place_below
set_sync
/ set_desync
If the object cannot be destroyed, its method should maybe not return a result, or this result should have a "unwrap that cannot panic" method (like a Result<T,Void>
).
Apologies, in case this actually needs to be fixed in glutin -- here was just a one-line-change for me:
Why does client.rs
use panic!
here in case of a missing symbol?
pub static ref WAYLAND_CLIENT_OPTION: Option<WaylandClient> = {
match WaylandClient::open("libwayland-client.so") {
Ok(h) => Some(h),
Err(::dlib::DlError::NotFound) => None,
Err(::dlib::DlError::MissingSymbol(s)) => {
panic!("Found library libwayland-client.so but symbol {} is missing.", s);
}
}
}
replacing with
Err(::dlib::DlError::MissingSymbol(_)) => None
fixed the following issue for me:
Compiling glutin 0.8.1, (with rustup and cargo) fails because there is an older version of libwayland-client.so
in my system (Linux 16.04):
Package: libwayland-client0
Version: 1.9.0-1
which does not have wl_proxy_marshal_array_constructor_versioned
, yet.
Without the panic, glutins api_dispatch.rs
uses the fallback.
(It could, of course catch the panic, if it is needed here for other reasons.)
The current set of examples is quite minimalistic, and does not provide hints about more complex setups.
and figure out the actual semantic of "destroy" vs "destructor"
Hey, I was trying to use your library, specfically with the dlopen
feature in order to use the functions defined in the WaylandServer
struct, and after running my program I get a panic saying libwayland-server.so
could not be found. However, ldd
reports that the binary can find libwayland-server.so
on my system, is there something I'm missing or is this feature not complete yet?
I've registered a global wl_compositor handler and thus have impl'd bind for that global, however my bind implementation never gets called. In my client code I the register_global callback gets alled for wl_compositor so I know my code registering the global works. In the client code I then make a call to wl_registry_bind and while the eventloop never receives an event and my bind function is never called, the wl_registry_bind does return a pointer.
I've simply followed your examples on the server documentation page, can you think of anything that might be causing this?
Ideally, adding a new protocol to the library should not be a breaking change at all. This would allow to easily use cargo features to enable / disable protocols.
My only idea to do that for now would be to define the Event
enum like this:
pub enum Event {
Wayland(::wayland::WaylandProtocolEvent),
#[cfg(feature = "protocol1"]
Protocol1(::protocol1::Protocol1Event),
#[cfg(feature = "protocol2"]
Protocol2(::protocol2::Protocol2Event),
/* etc ... */
#[doc(hidden)]
__HiddenVariantNotToBeMatched,
}
The idea of this last hidden variant would be to force matching on this enum to have a _ => { ... }
branch, to handle unknown event (normally by ignoring them). This branch would actually never be taken, as it is not possible to receive messages from a proxy defined by a secondary protocol as long as you haven't created it !
This would pragmatically future-proof the enum, making adding new variant automatically be handled in the good way (caught by the _
pattern).
Are there better options ?
Using the bitfield crate forces the use of submodules to avoir polluting the namespace, which is quite terrible.
Ideally, bitfields value would be associated consts. Is there a way to emulate this temporarily ?
I get this lovely error message (after enabling wayland logging in gnome) when running the sample from the webrender repository:
"wl_display@1: error 1: invalid method 9 (since 3 < 4), object wl_surface@25"
The wayland server then sends the error to the client which panics in the swap_buffer implementation for EGL in glutin (version 0.7).
I'll come back with the rest of the log, and maybe a smaller test case shortly.
Now that we have coverage measure, it'll help a lot in guiding test wrinting.
Coverage is currently very low, and needs to be brought up!
Finally it's be merged, we can use it.
It'll be a breaking change, hence 0.4.0.
Hi,
I guess you haven't caught up with this issue yet :)
Here's a first, coming from an ARM Linux machine using 1.7 nightly:
Compiling wayland-client v0.2.1
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/registry.rs:248:49: 248:58 error: mismatched types:
expected `*const u8`,
found `*const i8`
(expected u8,
found i8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/registry.rs:248 let interface_str = unsafe { CStr::from_ptr(interface) };
^~~~~~~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/registry.rs:248:49: 248:58 help: run `rustc --explain E0308` to see a detailed explanation
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:256:44: 256:56 error: mismatched types:
expected `*const u8`,
found `*const i8`
(expected u8,
found i8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:256 let manu_str = unsafe { CStr::from_ptr(manufacturer) };
^~~~~~~~~~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:256:44: 256:56 help: run `rustc --explain E0308` to see a detailed explanation
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:257:45: 257:50 error: mismatched types:
expected `*const u8`,
found `*const i8`
(expected u8,
found i8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:257 let model_str = unsafe { CStr::from_ptr(model) };
^~~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/output/output.rs:257:45: 257:50 help: run `rustc --explain E0308` to see a detailed explanation
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/seat/seat.rs:196:44: 196:48 error: mismatched types:
expected `*const u8`,
found `*const i8`
(expected u8,
found i8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/seat/seat.rs:196 let name_str = unsafe { CStr::from_ptr(name) };
^~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/seat/seat.rs:196:44: 196:48 help: run `rustc --explain E0308` to see a detailed explanation
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:213:17: 213:31 error: mismatched types:
expected `*const i8`,
found `*const u8`
(expected i8,
found u8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:213 title.as_ptr()
^~~~~~~~~~~~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:213:17: 213:31 help: run `rustc --explain E0308` to see a detailed explanation
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:227:17: 227:31 error: mismatched types:
expected `*const i8`,
found `*const u8`
(expected i8,
found u8) [E0308]
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:227 title.as_ptr()
^~~~~~~~~~~~~~
/home/odroid/.cargo/registry/src/github.com-48ad6e4054423464/wayland-client-0.2.1/src/core/shell/shell_surface.rs:227:17: 227:31 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to 6 previous errors
BTW:
Is there a way to disable building wayland dependencies on X? It's really slow on arm...
This will make event loops actually worth it server-side.
Secondary sources to handle:
There's a build error in src/display.rs:93 on OpenBSD, because ::libc::EPROTO isn't defined.
Get inspiration from https://cgit.freedesktop.org/wayland/weston/tree/tests/weston-test-client-helper.c?id=87743e93036c661b7d46a3ebb2a1a16233064004#n719
Will maybe require some fiddling with the scanner, in order to map back the error to its enum.
The code of the scanner is currently very messy, and was only designed to have something which works.
It should be cleaned and properly refactored, in order to reuse as much code as possible in the future server side of the generation.
$ rust --version
rustc 1.16.0
$ cargo --version
cargo-0.17.0 (built 2017-03-19)
The following code (main.rs
) doesn't compile for me:
#[macro_use]
extern crate wayland_client;
use wayland_client::default_connect;
use wayland_client::protocol::wl_registry;
fn main() {
let (display, event_queue) = default_connect().unwrap();
let handler_id = event_queue.add_handler(RegistryHandler::new());
}
struct RegistryHandler { }
impl wl_registry::Handler for RegistryHandler {
fn global(
&mut self,
evqh: &mut EventQueueHandle,
proxy: &WlRegistry,
name: u32,
interface: String,
version: u32
) { }
fn global_remove(
&mut self,
evqh: &mut EventQueueHandle,
proxy: &WlRegistry,
name: u32
) { }
declare_handler!(RegistryHandler, wl_registry::Handler, wl_registry::WlRegistry);
}
This is the error message:
$ cargo build
Compiling nightshift v0.1.0 (file:///home/embik/Workspace/Apps/nightshift)
error: expected one of `extern` or `fn`, found `impl`
--> <client_declare_handler macros>:2:8
|
2 | unsafe impl $ crate :: Handler < $ handled_type > for $ handler_struct {
| ^^^^
error: Could not compile `nightshift`.
To learn more, run the command again with --verbose.
I'm new to Rust and not familiar with some concepts, so this might very well be an issue on my side. But what's the issue with this?
It will probably be needed in some complex setups and simplify a lot building abstractions.
Most likely, user_data()
method for the Proxy
and Resource
traits, providing an UserDataGuard
wrapping an interior MutexGuard
, and deref-ing to a &mut Option<Box<Any+Send+'static>>
.
Is it possible to receive events without enum Event
? It would be ideal to rename WaylandProtocolEvent
to Event
and get it in the event loop.
Currrently, I am trying to use this wayland-server
crate to implement my wayland compositor.
However, I am stuck in the wl_surface::Handler interface.
impl wl_surface::Handler for SurfaceHandler {
fn attach(&mut self,
_evqh: &mut EventLoopHandle,
_client: &Client,
_resource: &WlSurface,
_buffer: Option<&WlBuffer>,
_x: i32,
_y: i32) {
// my surface logic
}
To get a workable wl_surface handler, I need to implement the attach
function. According to the Wayland api reference, I think I need store _buffer
in somewhere as pending buffer. But the _buffer
's type (Option<&WlBuffer>) makes the work diffcult. I can't store it because of the lifetime logic in rust.
Do you have some suggestion about this. Maybe this is not a issue about this crate, If I am wrong, please tell me. Thanks.
Hi!
We would like to issue a new release of mdBook containing some changes that could potentially break current books, the config file changed a bit for example. However we found out that a lot of projects automatically deploy using the latest available version and so any breaking update could result in books not being deployed anymore..
We would like to avoid that and recommend pinning the version of mdBook in your deployment script. Cargo supports semver ranges on cargo install
(right now it issues a deprecation warning, but in the future this warning should go away thanks to rust-lang/cargo#4229)
You can thus simply change cargo install mdbook
to
cargo install mdbook --vers "^0.0.22"
Next release will be 0.1.0
and we will try to adhere to semver as much as possible.
For more info, azerupi/mdBook#327 is the tracking issue on our repository.
From what I have seen of most examples in C, when constructing a wl_listener
to listen for signals a struct is created that has a pointer to wl_notify_func
(which you define) in the .notify
field.
However, in the wayland-sys crate in server.rs
, it's defined as a opaque pointer which means it can't be constructed by this library directly. Is this a bug?
Here is the common definition I'm finding in the header files: https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Server/structwl__listener.html
Should be able to reuse a lot of the client code generation.
wayland-sys
wayland-server
libhttps://gist.github.com/ripread/6defcb029653faff45c577d16f913d3d
I compiled the client code with gcc -lwayland-client client.c
$ rust-gdb compositor
(gdb) b compositor::{{impl}}::bind
(gdb) run
Breakpoint 1, compositor::{{impl}}::bind (self=0x1, evqh=0x3, global=WlCompositor = {...})
As you can see, both self and evqh are invalid pointers.
wl_proxy_marshall
and wl_proxy_marshall constructor
are currently assumed to never fail. It could be ok if we prevented any call with invalid arguments.
But this is not possible given how thin this wrapper library is. So, all generated method creating a new object should return a Result
.
Need to figure out how the error handling is to be done in such cases. Does this generate a protocol error ?
Can be found here: http://cgit.freedesktop.org/wayland/wayland-protocols/tree/
The plan is to add other protocol files to this lib, under cargo features. Probably under the naming convention wp_<protocol_name>
(wp
stands for Wayland Protocol
).
There are two states for a secondary protocol: either it is stable or unstable. Currently no protocol is stable except the core one.
The use of unstable protocols will certainly be constrained by an other cargo feature, like unstable_wayland_protocols
.
So to use wdg_shell
for example, you would have to add both the unstable_wayland_protocols
and wp_sdg_shell
cargo features.
Also, no stability guaranties are given for unstable protocols, and a breaking update of one of these protocols won't be considered as a breaking change for wayland-client
, from a semver point of view.
libwayland-server provides a few helper functions, notably regarding wl_shm
handling: wayland_shm.c.
These helpers cannot be used as-is with the crate wayland-server, as they would violate the user_data
structure the safety of the whole lib depends on. But they can be re-implemented on top of the current rust API, as they require no special knowledge of the internals.
#[macro_use]
extern crate lazy_static;
extern crate wayland_client as wayland;
use wayland::wayland::WlDisplay;
lazy_static!{
static ref DISPLAY: WlDisplay = {
match wayland::wayland::get_display() {
Some(d) => d,
None => panic!("Unable to connect to a wayland compositor.")
}
};
}
fn main() {
println!("Hello, World!");
}
Compiler error:
<lazy_static macros>:33:22: 33:34 error: the trait `core::marker::Sync` is not implemented for the type `*mut wayland_sys::client::wl_proxy` [E0277]
<lazy_static macros>:33 = __stability ( ) ; require_sync ( static_ref ) ; static_ref } } }
^~~~~~~~~~~~
<lazy_static macros>:4:1: 5:73 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
src/main.rs:7:1: 14:2 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
<lazy_static macros>:33:22: 33:34 help: run `rustc --explain E0277` to see a detailed explanation
<lazy_static macros>:33:22: 33:34 note: `*mut wayland_sys::client::wl_proxy` cannot be shared between threads safely
<lazy_static macros>:33:22: 33:34 note: required because it appears within the type `wayland::sys::wayland::client::WlDisplay`
<lazy_static macros>:33:22: 33:34 note: required by `DISPLAY.::std::ops::Deref::deref::require_sync`
error: aborting due to previous error
Could not compile `wayland_ffi`.
To learn more, run the command again with --verbose.
<lazy_static macros>:2:32: 3:65 error: the trait bound `*mut wayland_sys::client::wl_display: std::marker::Send` is not satisfied [E0277]
<lazy_static macros>:2 use std :: sync :: ONCE_INIT ; static mut $ NAME : $ crate :: lazy :: Lazy < $
^
<lazy_static macros>:21:1: 21:40 note: in this expansion of __lazy_static_create! (defined in <lazy_static macros>)
<lazy_static macros>:9:1: 10:74 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
src/api/wayland/context.rs:20:1: 24:2 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
<lazy_static macros>:2:32: 3:65 help: run `rustc --explain E0277` to see a detailed explanation
<lazy_static macros>:2:32: 3:65 note: `*mut wayland_sys::client::wl_display` cannot be sent between threads safely
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `wayland_client::EventIterator`
<lazy_static macros>:2:32: 3:65 note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::Mutex<wayland_client::EventIterator>`
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `api::wayland::context::WaylandContext`
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `std::option::Option<api::wayland::context::WaylandContext>`
<lazy_static macros>:2:32: 3:65 note: required by `lazy_static::lazy::Lazy`
<lazy_static macros>:2:32: 3:65 error: the trait bound `*mut wayland_sys::client::wl_event_queue: std::marker::Send` is not satisfied [E0277]
<lazy_static macros>:2 use std :: sync :: ONCE_INIT ; static mut $ NAME : $ crate :: lazy :: Lazy < $
^
<lazy_static macros>:21:1: 21:40 note: in this expansion of __lazy_static_create! (defined in <lazy_static macros>)
<lazy_static macros>:9:1: 10:74 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
src/api/wayland/context.rs:20:1: 24:2 note: in this expansion of lazy_static! (defined in <lazy_static macros>)
<lazy_static macros>:2:32: 3:65 help: run `rustc --explain E0277` to see a detailed explanation
<lazy_static macros>:2:32: 3:65 note: `*mut wayland_sys::client::wl_event_queue` cannot be sent between threads safely
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `std::option::Option<*mut wayland_sys::client::wl_event_queue>`
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `wayland_client::EventIterator`
<lazy_static macros>:2:32: 3:65 note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::Mutex<wayland_client::EventIterator>`
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `api::wayland::context::WaylandContext`
<lazy_static macros>:2:32: 3:65 note: required because it appears within the type `std::option::Option<api::wayland::context::WaylandContext>`
<lazy_static macros>:2:32: 3:65 note: required by `lazy_static::lazy::Lazy`
I was debugging a crash similar to #75, and ended up with a segfault where the wl_pointer
interface ends up in an event queue (so when trying to read the signature wayland crashes).
Does this ring any bells? I have an RR trace and it was a simple glutin example (just clearing colors).
Wayland servers can have sockets added in several ways:
wl_display_add_socket
. Which either: uses a given display name, WAYLAND_DISPLAY
or wayland-0
. (In that order)wl_display_add_socket_auto
. Which scans through $XDG_RUNTIME_DIR
for an unused wayland-$d
(where $d is < 32) and binds the first available.wl_display_add_socket_fd
. Which accepts a file descriptor. This can be for:My initial thoughts:
The first method seems to be the documented behavior of create_display
. But, I'm not seeing it happen. Although it may not be the best behavior. By which I mean create_display
should probably only do what wl_display_create
does (the get event loop is probably fine).
Perhaps adding add_socket
methods to Display
or EventLoop
. eg:
fn add_socket(&mut self, name: Option<&OsStr>) -> Result<()>
wl_display_add_socket
fn add_socket_auto(&mut self) -> Result<String>
wl_display_add_socket_auto
. Returns the resulting string. (Which should be utf8, although an OsString
might be better anyway)fn add_socket_rawfd(&mut self, fd: RawFd) -> Result<()>
wl_display_add_socket_fd
with the passed fd.fn add_socket_intofd<F>(&mut self, fd: F) -> Result<()> where F: IntoRawFd
add_socket_rawfd
.I might be able to do somethings about this, but I'm a bit busy over the next week or two.
... and correct if necessary.
I'm not completely confident about some edge cases.
Also, the lifetimes of the callbacks (currently 'static
) could maybe be relaxed?
So I was just playing around with mouse events and noticed something weird.
If I run the window example the mouse motion event doesn't work.
However, if I add a second surface.commit()
right after the first one (https://github.com/vberger/wayland-client-rs/blob/master/wayland-client/examples/simple_window.rs#L115) it does work.
I am currently running into this problem with my own program that I need to do the first commit twice for mouse events to work and I am not sure if this is a bug, since it's even present in the example.
I've tested this with Sway if that matters.
I plan to reorganize the lib for 0.2.0, which will resolve in a big load of breaking changes, including:
Serial
as input argument of all the callback functions who have it (it can be more useful than I first expected)dlopen
to activate the use of dlopen
to find the libraries rather than dynamic linkingcore
core
in a more clean may (probably a module for each global object and all its children)Sould be done only once #1 is finished.
It is actually blocking for https://github.com/vberger/wayland-window , so should probably be done faster.
List of things still to be done:
wayland-scanner:
wayland-client:
wayland-server:
Hey there. I'm trying to simply print out the associated key when the keysym is provided to the wl_keyboard::Handler::key
callback using the xkbcommon
crate.
However, I evidently need to use this method because the symbol ids given to me in the method don't correspond to the correct key, unfortunately I'm not sure how I am able to construct that with the information provided to the client (Do I need to use the RawFd
provided in the keymap
callback?).
Should I be using a different method to map keys to their string representations, or do I need to construct a xkb::State
somehow?
Here's what I have, which is not printing the correct character when I press it on the keyboard:
fn key(&mut self,
evqh: &mut EventQueueHandle,
proxy: &wl_keyboard::WlKeyboard,
serial: u32,
time: u32,
key: u32,
state: wl_keyboard::KeyState) {
if state == wl_keyboard::KeyState::Pressed {
println!("Number: {:#?}", key);
println!("Got key: {:#?}", xkb::keysym_get_name(key));
// self.input is just a string made up of all the keys pressed so far
self.input.push_str(keysym_to_utf8(key).as_str());
println!("Input is: {}", self.input);
}
}
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.