feat: fixing very single gtk4 migration error! yippee!
This commit is contained in:
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ impl DisplayBackend for NoBackend {
|
||||
) -> Option<Window> {
|
||||
// top level
|
||||
let window = Window::new();
|
||||
|
||||
|
||||
// window.move_(x, y);
|
||||
|
||||
Some(window)
|
||||
|
||||
@@ -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(>k_widget);
|
||||
// insert into container if it's a Box
|
||||
if let Ok(box_container) = parent_widget.clone().dynamic_cast::<gtk4::Box>() {
|
||||
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::<gtk4::Overlay>() {
|
||||
// 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::<gtk4::Container>().ok() {
|
||||
container.remove(&entry.widget);
|
||||
}
|
||||
}
|
||||
entry.widget.unparent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user