Skip to content

Commit

Permalink
Move WindowIdExt to its own file; eliminate force-paint hack - better…
Browse files Browse the repository at this point in the history
… fix available
  • Loading branch information
timboudreau committed May 30, 2024
1 parent c1c9a6a commit 318a4ae
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 79 deletions.
79 changes: 1 addition & 78 deletions src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,34 +258,20 @@ impl ViewId {
self.request_changes(ChangeFlags::LAYOUT)
}

fn is_in_active_window(&self) -> bool {
pub fn is_in_active_window(&self) -> bool {
if let Some(root) = self.root() {
return crate::window_handle::get_current_view() == root;
}
false
}

fn force_repaint(&self) -> bool {
if let Some(window_id) = self.window_id() {
// This should not fail unless, say, the view was never
// added to a parent view that is realized
if crate::window_tracking::force_window_repaint(&window_id) {
return true;
}
}
crate::window_tracking::force_all_repaint()
}

pub fn window_id(&self) -> Option<WindowId> {
self.root().and_then(window_id_for_root)
}

pub fn request_paint(&self) {
let active = self.is_in_active_window();
self.add_update_message(UpdateMessage::RequestPaint);
if !active {
self.force_repaint();
}
}

/// request that this node be styled again
Expand Down Expand Up @@ -356,23 +342,6 @@ impl ViewId {
id: *self,
state: Box::new(state),
});
// A state update sent from the active window to a view
// in another window will be enqueued, but will not actually
// be retrieved and processed some external OS-level event
// triggers a repaint; in order to get the event processed,
// we need to force a repaint via the winit window, bypassing
// the usual mechanism to trigger a repaint (repaint messages
// too, will just be enqueued but not run until ... a repaint
// happens for some external reason).
//
// Without this, it is impossible for popup windows and similar
// to deliver messages to their parent that affect their display
// (or close the popup window), because the inactive window is
// completely quiescent unless jogged by, say the mouse passing
// over it.
if !self.is_in_active_window() {
self.force_repaint();
}
}

/// `viewport` is relative to the `id` view.
Expand Down Expand Up @@ -489,49 +458,3 @@ impl ViewId {
crate::screen_layout::try_create_screen_layout(self)
}
}

/// Ensures `WindowIdExt` cannot be implemented on arbitrary types.
trait WindowIdExtSealed {}
impl WindowIdExtSealed for WindowId {}

/// Extends WindowId to give instances methods to retrieve properties of the associated window,
/// much as ViewId does. Methods may return None if the view is not realized on-screen, or
/// if information needed to compute the result is not available on the current platform or
/// available on the current platform but not from the calling thread.
#[allow(private_bounds)]
pub trait WindowIdExt: WindowIdExtSealed {
/// Get the bounds of the content of this window, including
/// titlebar and native window borders.
fn bounds_on_screen_including_frame(&self) -> Option<Rect>;
/// Get the bounds of the content of this window, excluding
/// titlebar and native window borders.
fn bounds_of_content_on_screen(&self) -> Option<Rect>;
/// Get the location of the window including any OS titlebar.
fn position_on_screen_including_frame(&self) -> Option<Point>;
/// Get the location of the window **excluding** any OS titlebar.
fn position_of_content_on_screen(&self) -> Option<Point>;
/// Get the logical bounds of the monitor this window is on
fn monitor_bounds(&self) -> Option<Rect>;
}

impl WindowIdExt for WindowId {
fn bounds_on_screen_including_frame(&self) -> Option<Rect> {
window_outer_screen_bounds(self)
}

fn bounds_of_content_on_screen(&self) -> Option<Rect> {
window_inner_screen_bounds(self)
}

fn position_on_screen_including_frame(&self) -> Option<Point> {
window_outer_screen_position(self)
}

fn position_of_content_on_screen(&self) -> Option<Point> {
window_inner_screen_position(self)
}

fn monitor_bounds(&self) -> Option<Rect> {
monitor_bounds(self)
}
}
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ pub mod view_tuple;
pub mod views;
pub mod window;
mod window_handle;
mod window_id;
mod window_tracking;

pub use app::{launch, quit_app, AppEvent, Application};
Expand All @@ -189,10 +190,11 @@ pub use clipboard::{Clipboard, ClipboardError};
pub use floem_reactive as reactive;
pub use floem_renderer::cosmic_text;
pub use floem_renderer::Renderer;
pub use id::{ViewId, WindowIdExt};
pub use id::ViewId;
pub use peniko;
pub use peniko::kurbo;
pub use screen_layout::ScreenLayout;
pub use taffy;
pub use view::{recursively_layout_view, AnyView, IntoView, View};
pub use window::{close_window, new_window};
pub use window_id::WindowIdExt;
52 changes: 52 additions & 0 deletions src/window_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::window_tracking::{
monitor_bounds, window_inner_screen_bounds, window_inner_screen_position,
window_outer_screen_bounds, window_outer_screen_position,
};
use floem_winit::window::WindowId;
use peniko::kurbo::{Point, Rect};

/// Ensures `WindowIdExt` cannot be implemented on arbitrary types.
trait WindowIdExtSealed {}
impl WindowIdExtSealed for WindowId {}

/// Extends WindowId to give instances methods to retrieve properties of the associated window,
/// much as ViewId does. Methods may return None if the view is not realized on-screen, or
/// if information needed to compute the result is not available on the current platform or
/// available on the current platform but not from the calling thread.
#[allow(private_bounds)]
pub trait WindowIdExt: WindowIdExtSealed {
/// Get the bounds of the content of this window, including
/// titlebar and native window borders.
fn bounds_on_screen_including_frame(&self) -> Option<Rect>;
/// Get the bounds of the content of this window, excluding
/// titlebar and native window borders.
fn bounds_of_content_on_screen(&self) -> Option<Rect>;
/// Get the location of the window including any OS titlebar.
fn position_on_screen_including_frame(&self) -> Option<Point>;
/// Get the location of the window **excluding** any OS titlebar.
fn position_of_content_on_screen(&self) -> Option<Point>;
/// Get the logical bounds of the monitor this window is on
fn monitor_bounds(&self) -> Option<Rect>;
}

impl WindowIdExt for WindowId {
fn bounds_on_screen_including_frame(&self) -> Option<Rect> {
window_outer_screen_bounds(self)
}

fn bounds_of_content_on_screen(&self) -> Option<Rect> {
window_inner_screen_bounds(self)
}

fn position_on_screen_including_frame(&self) -> Option<Point> {
window_outer_screen_position(self)
}

fn position_of_content_on_screen(&self) -> Option<Point> {
window_inner_screen_position(self)
}

fn monitor_bounds(&self) -> Option<Rect> {
monitor_bounds(self)
}
}

0 comments on commit 318a4ae

Please sign in to comment.