feat: fixing very single gtk4 migration error! yippee!

This commit is contained in:
Byson94
2025-10-01 16:53:22 +05:30
parent a9ccb25cae
commit 3120d7556e
3 changed files with 77 additions and 56 deletions

View File

@@ -879,29 +879,45 @@ fn initialize_window<B: DisplayBackend>(
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::<gdk4_x11::X11Surface>()
.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;
}
});
}

View File

@@ -38,7 +38,7 @@ impl DisplayBackend for NoBackend {
) -> Option<Window> {
// top level
let window = Window::new();
// window.move_(x, y);
Some(window)

View File

@@ -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::<gtk4::Container>().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::<gtk4::Box>().ok() {
box_container.add(&gtk_widget);
// insert into container if it's a Box
if let Ok(box_container) = parent_widget.clone().dynamic_cast::<gtk4::Box>() {
box_container.append(&gtk_widget);
if let Some(pos) = position {
log::trace!("Reordering contents of gtk4::Box. Position: '{}'", pos);
box_container.reorder_child(&gtk_widget, pos as i32);
}
} else {
container.add(&gtk_widget);
}
// reordering widgets
if let Some(prev) = prev_sibling {
box_container.reorder_child_after(&gtk_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(&gtk_widget, next_prev.as_ref());
} // else: only child, already appended, do nothing
} else if let Ok(overlay) = parent_widget.clone().dynamic_cast::<gtk4::Overlay>() {
// TODO: Handle changing main widget
overlay.add_overlay(&gtk_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::<gtk4::Container>().ok() {
container.remove(&entry.widget);
}
}
entry.widget.unparent();
}
}
}