Skip to content

Commit

Permalink
feat(linux): implement MonitorHandle and related methods (#125)
Browse files Browse the repository at this point in the history
* Implement `MonitorHandle` on Linux

* Fix type and add todo

* Add comment about linux on set_fullscreen
  • Loading branch information
Ngo Iok Ui (Wu Yu Wei) authored Jul 12, 2021
1 parent 921c901 commit 6fcfa62
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changes/gtk-monitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": patch
---

Implement `MonitorHandle` and related methods on Linux.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ gio = "0.9"
glib = "0.10"
glib-sys = "0.10"
gtk = { version = "0.9", features = [ "v3_16" ] }
gdk = "0.13"
gdk = { version = "0.13", features = [ "v3_22" ] }
gdk-sys = "0.10"
gdk-pixbuf = { version = "0.9", features = [ "v2_36_8" ] }
sourceview = { version = "0.9", optional = true }
Expand Down
21 changes: 19 additions & 2 deletions src/platform_impl/linux/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ use super::{
};

pub struct EventLoopWindowTarget<T> {
/// Gdk display
pub(crate) display: gdk::Display,
/// Gtk application
pub(crate) app: gtk::Application,
/// Window Ids of the application
Expand All @@ -52,12 +54,24 @@ pub struct EventLoopWindowTarget<T> {
impl<T> EventLoopWindowTarget<T> {
#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
todo!()
let mut handles = VecDeque::new();
let display = &self.display;
let numbers = display.get_n_monitors();

for i in 0..numbers {
let monitor = MonitorHandle::new(&display, i);
handles.push_back(monitor);
}

handles
}

#[inline]
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
todo!()
let screen = self.display.get_default_screen();
let number = screen.get_primary_monitor();
let handle = MonitorHandle::new(&self.display, number);
Some(RootMonitorHandle { inner: handle })
}
}

Expand Down Expand Up @@ -85,7 +99,10 @@ impl<T: 'static> EventLoop<T> {

// Create event loop window target.
let (window_requests_tx, window_requests_rx) = glib::MainContext::channel(Priority::default());
let display = gdk::Display::get_default()
.expect("GdkDisplay not found. This usually means `gkt_init` hasn't called yet.");
let window_target = EventLoopWindowTarget {
display,
app,
windows: Rc::new(RefCell::new(HashSet::new())),
window_requests_tx,
Expand Down
31 changes: 26 additions & 5 deletions src/platform_impl/linux/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,45 @@ use crate::{
};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MonitorHandle;
pub struct MonitorHandle {
monitor: gdk::Monitor,
// We have to store the monitor number in GdkScreen despite
// it's deprecated. Otherwise, there's no way to set it in
// GtkWindow in Gtk3.
number: i32,
}

impl MonitorHandle {
pub fn new(display: &gdk::Display, number: i32) -> Self {
let monitor = display.get_monitor(number).unwrap();
Self { monitor, number }
}

#[inline]
pub fn name(&self) -> Option<String> {
todo!()
self.monitor.get_model().map(|s| s.as_str().to_string())
}

#[inline]
pub fn size(&self) -> PhysicalSize<u32> {
todo!()
PhysicalSize {
width: self.monitor.get_width_mm() as u32,
height: self.monitor.get_height_mm() as u32,
}
}

#[inline]
pub fn position(&self) -> PhysicalPosition<i32> {
todo!()
let rect = self.monitor.get_geometry();
PhysicalPosition {
x: rect.x,
y: rect.y,
}
}

#[inline]
pub fn scale_factor(&self) -> f64 {
todo!()
self.monitor.get_scale_factor() as f64
}

#[inline]
Expand All @@ -36,6 +54,9 @@ impl MonitorHandle {
}
}

unsafe impl Send for MonitorHandle {}
unsafe impl Sync for MonitorHandle {}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct VideoMode;

Expand Down
23 changes: 20 additions & 3 deletions src/platform_impl/linux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ impl Window {

// Rest attributes
window.set_title(&attributes.title);
// TODO set it with Fullscreen enum
if attributes.fullscreen.is_some() {
window.fullscreen();
}
Expand Down Expand Up @@ -620,16 +621,32 @@ impl Window {
}

pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
todo!()
let screen = self.window.get_display().get_default_screen();
let window = self.window.get_window().unwrap();
let number = screen.get_monitor_at_window(&window);
let handle = MonitorHandle::new(&self.window.get_display(), number);
Some(RootMonitorHandle { inner: handle })
}

#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
todo!()
let mut handles = VecDeque::new();
let display = self.window.get_display();
let numbers = display.get_n_monitors();

for i in 0..numbers {
let monitor = MonitorHandle::new(&display, i);
handles.push_back(monitor);
}

handles
}

pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
todo!()
let screen = self.window.get_display().get_default_screen();
let number = screen.get_primary_monitor();
let handle = MonitorHandle::new(&self.window.get_display(), number);
Some(RootMonitorHandle { inner: handle })
}

pub fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
Expand Down
1 change: 1 addition & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ impl Window {
/// The dock and the menu bar are always disabled in fullscreen mode.
/// - **iOS:** Can only be called on the main thread.
/// - **Windows:** Screen saver is disabled in fullscreen mode.
/// - **Linux:** The window will only fullscreen to current monitor no matter which enum variant.
/// - **Android:** Unsupported.
#[inline]
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
Expand Down

0 comments on commit 6fcfa62

Please sign in to comment.