From 3120d7556ef11da476cd8433762b7d07bd46162a Mon Sep 17 00:00:00 2001 From: Byson94 Date: Wed, 1 Oct 2025 16:53:22 +0530 Subject: [PATCH] feat: fixing very single gtk4 migration error! yippee! --- crates/ewwii/src/app.rs | 50 ++++++++---- crates/ewwii/src/display_backend.rs | 2 +- .../ewwii/src/widgets/widget_definitions.rs | 81 ++++++++++--------- 3 files changed, 77 insertions(+), 56 deletions(-) diff --git a/crates/ewwii/src/app.rs b/crates/ewwii/src/app.rs index 465fc63..68fd113 100644 --- a/crates/ewwii/src/app.rs +++ b/crates/ewwii/src/app.rs @@ -879,29 +879,45 @@ fn initialize_window( let (conn, screen_num) = x11rb::rust_connection::RustConnection::connect(None)?; let x11_conn = Rc::new(conn); + let gdk_surface = + window.surface().context("Couldn't get gdk window from gtk window")?; + + let win_xid = gdk_surface + .downcast_ref::() + .context("Failed to get x11 window for gtk window")? + .xid() as u32; + + use x11rb::protocol::xproto::*; + x11_conn + .clone() + .change_window_attributes( + win_xid, + &ChangeWindowAttributesAux::new().event_mask(EventMask::STRUCTURE_NOTIFY), + ) + .unwrap(); + let _ = apply_window_position(x11_conn.clone(), geometry, monitor_geometry, &window); if window_init.backend_options.x11.window_type != crate::window::backend_window_options::X11WindowType::Normal { - let last_pos = Rc::new(RefCell::new(None)); - window.connect_configure_event({ - let last_pos = last_pos.clone(); - move |window, _| { - let gdk_window = window.window().unwrap(); - let current_origin = gdk_window.origin(); + let window_clone = window.clone(); + let conn_clone = x11_conn.clone(); - let mut last = last_pos.borrow_mut(); - if Some((current_origin.1, current_origin.2)) != *last { - *last = Some((current_origin.1, current_origin.2)); - let _ = apply_window_position( - x11_conn.clone(), - geometry, - monitor_geometry, - window, - ); + use x11rb::connection::Connection; + + glib::MainContext::default().spawn_local(async move { + loop { + if let Ok(event) = conn_clone.poll_for_event() { + if let Some(x11rb::protocol::Event::ConfigureNotify(_ev)) = event { + let _ = apply_window_position( + conn_clone.clone(), + geometry, + monitor_geometry, + &window_clone, + ); + } } - - false + glib::timeout_future(std::time::Duration::from_millis(10)).await; } }); } diff --git a/crates/ewwii/src/display_backend.rs b/crates/ewwii/src/display_backend.rs index 754b3b9..9cff37a 100644 --- a/crates/ewwii/src/display_backend.rs +++ b/crates/ewwii/src/display_backend.rs @@ -38,7 +38,7 @@ impl DisplayBackend for NoBackend { ) -> Option { // top level let window = Window::new(); - + // window.move_(x, y); Some(window) diff --git a/crates/ewwii/src/widgets/widget_definitions.rs b/crates/ewwii/src/widgets/widget_definitions.rs index bd14653..107b34d 100644 --- a/crates/ewwii/src/widgets/widget_definitions.rs +++ b/crates/ewwii/src/widgets/widget_definitions.rs @@ -68,7 +68,7 @@ pub struct WidgetRegistry { pub enum PatchGtkWidget<'a> { Create(&'a WidgetNode, u64, u64), // node, widget_id, parent_id Update(u64, Map), // widget_id, props - Remove(u64, u64), // widget_id, parent_id + Remove(u64), // widget_id } impl WidgetRegistry { @@ -89,8 +89,8 @@ impl WidgetRegistry { PatchGtkWidget::Update(widget_id, new_props) => { self.update_props(widget_id, new_props); } - PatchGtkWidget::Remove(widget_id, parent_id) => { - self.remove_widget(widget_id, parent_id) + PatchGtkWidget::Remove(widget_id) => { + self.remove_widget(widget_id) } } } @@ -138,10 +138,6 @@ impl WidgetRegistry { if !new_map.contains_key(id) { patch.push(PatchGtkWidget::Remove( *id, - new_info.parent_id.expect(&format!( - "Parent ID must exist. Widget type: {}", - &new_info.widget_type - )), )); } } @@ -157,35 +153,50 @@ impl WidgetRegistry { ) -> Result<()> { log::trace!("Creating '{}'", widget_id); if let Some(parent) = self.widgets.get(&parent_id) { - let parent_widget = parent.widget.clone(); + let parent_widget = &parent.widget.clone(); - if let Some(container) = parent_widget.dynamic_cast::().ok() { - // check if the widget already exists - let position = self.widgets.get(&widget_id).and_then(|old_entry| { - container.children().iter().position(|w| w == &old_entry.widget) - }); + // find old siblings if the widget already exists + let (prev_sibling, next_sibling) = if let Some(old_entry) = self.widgets.get(&widget_id) { + ( + old_entry.widget.prev_sibling(), + old_entry.widget.next_sibling(), + ) + } else { + (None, None) + }; + // check if widget already exists + if let Some(old_entry) = self.widgets.get(&widget_id) { // obliterate that widget.... // how dare it try to create duplication... - if let Some(old_entry) = self.widgets.get(&widget_id) { - container.remove(&old_entry.widget); - } + old_entry.widget.unparent(); + } - // `build_gtk_widget` also inserts info into widgetentry - // self is passed for that reason. - let gtk_widget = build_gtk_widget(&WidgetInput::BorrowedNode(widget_node), self)?; + // build_gtk_widget also inserts info into widgetentry + // self is passed for that reason. + let gtk_widget = build_gtk_widget(&WidgetInput::BorrowedNode(widget_node), self)?; - // insert into container - if let Some(box_container) = container.clone().dynamic_cast::().ok() { - box_container.add(>k_widget); + // insert into container if it's a Box + if let Ok(box_container) = parent_widget.clone().dynamic_cast::() { + box_container.append(>k_widget); - if let Some(pos) = position { - log::trace!("Reordering contents of gtk4::Box. Position: '{}'", pos); - box_container.reorder_child(>k_widget, pos as i32); - } - } else { - container.add(>k_widget); - } + // reordering widgets + if let Some(prev) = prev_sibling { + box_container.reorder_child_after(>k_widget, Some(&prev)); + } else if let Some(next) = next_sibling { + // move before next sibling: reorder after its prev (None if first) + let next_prev = next.prev_sibling(); + box_container.reorder_child_after(>k_widget, next_prev.as_ref()); + } // else: only child, already appended, do nothing + } else if let Ok(overlay) = parent_widget.clone().dynamic_cast::() { + // TODO: Handle changing main widget + overlay.add_overlay(>k_widget); + } else { + // fallback: + // + // Assumes that every other container like widget + // expects only one singular child. + gtk_widget.set_parent(parent_widget); } } @@ -198,16 +209,10 @@ impl WidgetRegistry { } } - pub fn remove_widget(&mut self, widget_id: u64, parent_id: u64) { - log::trace!("Removing '{}' from '{}'", widget_id, parent_id); + pub fn remove_widget(&mut self, widget_id: u64) { + log::trace!("Removing '{}'", widget_id); if let Some(entry) = self.widgets.remove(&widget_id) { - if let Some(parent) = self.widgets.get(&parent_id) { - let parent_widget = parent.widget.clone(); - - if let Some(container) = parent_widget.dynamic_cast::().ok() { - container.remove(&entry.widget); - } - } + entry.widget.unparent(); } } }