Skip to content

Commit 987aeae

Browse files
committed
fix(linux): Port to GTK4
Closes tauri-apps#1051
1 parent dae6d88 commit 987aeae

File tree

17 files changed

+1500
-1683
lines changed

17 files changed

+1500
-1683
lines changed

Cargo.lock

+289-229
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ rwh_05 = { package = "raw-window-handle", version = "0.5", features = [ "std" ],
4646
rwh_06 = { package = "raw-window-handle", version = "0.6", features = [ "std" ], optional = true }
4747
bitflags = "2"
4848
crossbeam-channel = "0.5"
49+
async-channel = "2.3"
4950
url = "2"
5051
dpi = "0.1"
5152

@@ -146,9 +147,9 @@ dispatch = "0.2"
146147
scopeguard = "1.2"
147148

148149
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
149-
gtk = "0.18"
150-
gdkx11-sys = "0.18"
151-
gdkwayland-sys = "0.18.0"
150+
gtk = { package = "gtk4", version = "0.9", features = ["v4_6"] }
151+
gdk-x11 = { package = "gdk4-x11", version = "0.9" }
152+
gdk-wayland = { package = "gdk4-wayland", version = "0.9", features = ["wayland_crate"]}
152153
x11-dl = "2.21"
153154
parking_lot = "0.12"
154155
dlopen2 = "0.7.0"

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ Gtk and its related libraries are used to build the support of Linux. Be sure to
4949
#### Arch Linux / Manjaro:
5050

5151
```bash
52-
sudo pacman -S gtk3
52+
sudo pacman -S gtk4
5353
```
5454

5555
#### Debian / Ubuntu:
5656

5757
```bash
58-
sudo apt install libgtk-3-dev
58+
sudo apt install libgtk-4-dev
5959
```
6060

6161
### Acknowledgement

examples/window.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use tao::{
1010

1111
#[allow(clippy::single_match)]
1212
fn main() {
13+
env_logger::init();
1314
let event_loop = EventLoop::new();
1415

1516
let mut window = Some(

src/platform/unix.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use crate::{
2121
error::{ExternalError, OsError},
2222
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
2323
monitor::MonitorHandle,
24-
platform_impl::{x11::xdisplay::XError, Parent, Window as UnixWindow},
24+
platform_impl::{
25+
gtk_window::ApplicationWindow, x11::xdisplay::XError, Parent, Window as UnixWindow,
26+
},
2527
window::{Window, WindowBuilder},
2628
};
2729

@@ -67,11 +69,11 @@ pub trait WindowExtUnix {
6769
/// and know what they're doing.
6870
fn new_from_gtk_window<T: 'static>(
6971
event_loop_window_target: &EventLoopWindowTarget<T>,
70-
window: gtk::ApplicationWindow,
72+
window: ApplicationWindow,
7173
) -> Result<Window, OsError>;
7274

7375
/// Returns the `gtk::ApplicatonWindow` from gtk crate that is used by this window.
74-
fn gtk_window(&self) -> &gtk::ApplicationWindow;
76+
fn gtk_window(&self) -> &ApplicationWindow;
7577

7678
/// Returns the vertical `gtk::Box` that is added by default as the sole child of this window.
7779
/// Returns `None` if the default vertical `gtk::Box` creation was disabled by [`WindowBuilderExtUnix::with_default_vbox`].
@@ -84,7 +86,7 @@ pub trait WindowExtUnix {
8486
}
8587

8688
impl WindowExtUnix for Window {
87-
fn gtk_window(&self) -> &gtk::ApplicationWindow {
89+
fn gtk_window(&self) -> &ApplicationWindow {
8890
&self.window.window
8991
}
9092

@@ -98,10 +100,10 @@ impl WindowExtUnix for Window {
98100

99101
fn new_from_gtk_window<T: 'static>(
100102
event_loop_window_target: &EventLoopWindowTarget<T>,
101-
window: gtk::ApplicationWindow,
103+
window: ApplicationWindow,
102104
) -> Result<Window, OsError> {
103105
let window = UnixWindow::new_from_gtk_window(&event_loop_window_target.p, window)?;
104-
Ok(Window { window: window })
106+
Ok(Window { window })
105107
}
106108

107109
fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) {
@@ -114,7 +116,7 @@ pub trait WindowBuilderExtUnix {
114116
fn with_skip_taskbar(self, skip: bool) -> WindowBuilder;
115117
/// Set this window as a transient dialog for `parent`
116118
/// <https://gtk-rs.org/gtk3-rs/stable/latest/docs/gdk/struct.Window.html#method.set_transient_for>
117-
fn with_transient_for(self, parent: &impl gtk::glib::IsA<gtk::Window>) -> WindowBuilder;
119+
fn with_transient_for(self, parent: &impl gtk::prelude::IsA<gtk::Window>) -> WindowBuilder;
118120

119121
/// Whether to enable or disable the internal draw for transparent window.
120122
///
@@ -158,8 +160,8 @@ impl WindowBuilderExtUnix for WindowBuilder {
158160
self
159161
}
160162

161-
fn with_transient_for(mut self, parent: &impl gtk::glib::IsA<gtk::Window>) -> WindowBuilder {
162-
use gtk::glib::Cast;
163+
fn with_transient_for(mut self, parent: &impl gtk::prelude::IsA<gtk::Window>) -> WindowBuilder {
164+
use gtk::prelude::Cast;
163165
self.platform_specific.parent = Parent::ChildOf(parent.clone().upcast());
164166
self
165167
}

src/platform_impl/linux/device.rs

+22-26
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ use std::{
33
ptr,
44
};
55

6-
use gtk::glib;
76
use x11_dl::{xinput2, xlib};
87

98
use crate::event::{DeviceEvent, ElementState, RawKeyEvent};
109

1110
use super::keycode_from_scancode;
1211

1312
/// Spawn Device event thread. Only works on x11 since wayland doesn't have such global events.
14-
pub fn spawn(device_tx: glib::Sender<DeviceEvent>) {
15-
std::thread::spawn(move || unsafe {
13+
pub fn spawn(device_tx: async_channel::Sender<DeviceEvent>) {
14+
std::thread::spawn(async move || unsafe {
1615
let xlib = xlib::Xlib::open().unwrap();
1716
let xinput2 = xinput2::XInput2::open().unwrap();
1817
let display = (xlib.XOpenDisplay)(ptr::null());
@@ -45,35 +44,32 @@ pub fn spawn(device_tx: glib::Sender<DeviceEvent>) {
4544
}
4645

4746
let event_type = event.get_type();
48-
match event_type {
49-
xlib::GenericEvent => {
50-
let mut xev = event.generic_event_cookie;
51-
if (xlib.XGetEventData)(display, &mut xev) == xlib::True {
52-
match xev.evtype {
53-
xinput2::XI_RawKeyPress | xinput2::XI_RawKeyRelease => {
54-
let xev: &xinput2::XIRawEvent = &*(xev.data as *const _);
55-
let physical_key = keycode_from_scancode(xev.detail as u32);
56-
let state = match xev.evtype {
57-
xinput2::XI_RawKeyPress => ElementState::Pressed,
58-
xinput2::XI_RawKeyRelease => ElementState::Released,
59-
_ => unreachable!(),
60-
};
47+
if event_type == xlib::GenericEvent {
48+
let mut xev = event.generic_event_cookie;
49+
if (xlib.XGetEventData)(display, &mut xev) == xlib::True {
50+
match xev.evtype {
51+
xinput2::XI_RawKeyPress | xinput2::XI_RawKeyRelease => {
52+
let xev: &xinput2::XIRawEvent = &*(xev.data as *const _);
53+
let physical_key = keycode_from_scancode(xev.detail as u32);
54+
let state = match xev.evtype {
55+
xinput2::XI_RawKeyPress => ElementState::Pressed,
56+
xinput2::XI_RawKeyRelease => ElementState::Released,
57+
_ => unreachable!(),
58+
};
6159

62-
let event = RawKeyEvent {
63-
physical_key,
64-
state,
65-
};
60+
let event = RawKeyEvent {
61+
physical_key,
62+
state,
63+
};
6664

67-
if let Err(e) = device_tx.send(DeviceEvent::Key(event)) {
68-
log::info!("Failed to send device event {} since receiver is closed. Closing x11 thread along with it", e);
69-
break;
70-
}
65+
if let Err(e) = device_tx.send_blocking(DeviceEvent::Key(event)) {
66+
log::info!("Failed to send device event {} since receiver is closed. Closing x11 thread along with it", e);
67+
break;
7168
}
72-
_ => {}
7369
}
70+
_ => {}
7471
}
7572
}
76-
_ => {}
7773
}
7874
}
7975
});

0 commit comments

Comments
 (0)