diff --git a/src/app.rs b/src/app.rs index be2c72f..f995d29 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,14 +4,13 @@ use crate::{ eww_state, script_var_handler::*, util, - value::{Coords, NumWithUnit, PrimitiveValue, VarName}, + value::{AttrValue, Coords, NumWithUnit, PrimitiveValue, VarName}, widgets, }; use anyhow::*; use crossbeam_channel; use debug_stub_derive::*; use gdk::WindowExt; -use glib::Cast; use gtk::{ContainerExt, CssProviderExt, GtkWindowExt, StyleContextExt, WidgetExt}; use itertools::Itertools; @@ -109,7 +108,7 @@ impl App { .eww_config .get_windows() .get(window_name) - .context(format!("No window named '{}' defined", window_name))? + .with_context(|| format!("No window named '{}' defined", window_name))? .clone(); let display = gdk::Display::get_default().expect("could not get default display"); @@ -119,16 +118,23 @@ impl App { let monitor_geometry = display.get_default_screen().get_monitor_geometry(*screen_number); - window_def.position = pos.unwrap_or_else(|| window_def.position); - window_def.size = size.unwrap_or_else(|| window_def.size); + window_def.position = pos.unwrap_or(window_def.position); + window_def.size = size.unwrap_or(window_def.size); let actual_window_rect = get_window_rectangle_in_screen(monitor_geometry, window_def.position, window_def.size); - let window = gtk::Window::new(gtk::WindowType::Popup); + let window = if window_def.focusable { + gtk::Window::new(gtk::WindowType::Toplevel) + } else { + gtk::Window::new(gtk::WindowType::Popup) + }; + window.set_title(&format!("Eww - {}", window_name)); let wm_class_name = format!("eww-{}", window_name); window.set_wmclass(&wm_class_name, &wm_class_name); - window.set_type_hint(gdk::WindowTypeHint::Dock); + if !window_def.focusable { + window.set_type_hint(gdk::WindowTypeHint::Dock); + } window.set_position(gtk::WindowPosition::Center); window.set_default_size(actual_window_rect.width, actual_window_rect.height); window.set_size_request(actual_window_rect.width, actual_window_rect.height); @@ -138,16 +144,12 @@ impl App { // run on_screen_changed to set the visual correctly initially. on_screen_changed(&window, None); window.connect_screen_changed(on_screen_changed); - let mut almost_empty_local_state = HashMap::new(); - almost_empty_local_state.insert( - VarName("window_name".to_string()), - crate::value::AttrValue::from_primitive(window_name.to_string()), - ); + let root_widget = &widgets::widget_use_to_gtk_widget( &self.eww_config.get_widgets(), &mut self.eww_state, window_name, - &almost_empty_local_state, + &maplit::hashmap! { "window_name".into() => AttrValue::from_primitive(window_name.to_string()) }, &window_def.widget, )?; root_widget.get_style_context().add_class(&window_name.to_string()); @@ -156,7 +158,7 @@ impl App { window.show_all(); let gdk_window = window.get_window().context("couldn't get gdk window from gtk window")?; - gdk_window.set_override_redirect(true); + gdk_window.set_override_redirect(!window_def.focusable); gdk_window.move_(actual_window_rect.x, actual_window_rect.y); if window_def.stacking == WindowStacking::Foreground { diff --git a/src/config/window_definition.rs b/src/config/window_definition.rs index 587c2d1..cf7dfa6 100644 --- a/src/config/window_definition.rs +++ b/src/config/window_definition.rs @@ -15,6 +15,7 @@ pub struct EwwWindowDefinition { pub screen_number: Option, pub widget: WidgetUse, pub struts: Struts, + pub focusable: bool, } impl EwwWindowDefinition { @@ -28,6 +29,7 @@ impl EwwWindowDefinition { let stacking = xml.attr("stacking").ok().map(|x| x.parse()).transpose()?.unwrap_or_default(); let screen_number = xml.attr("screen").ok().map(|x| x.parse()).transpose()?; + let focusable = xml.attr("focusable").ok().map(|x| x.parse()).transpose()?; let struts = xml.child("struts").ok().map(Struts::from_xml_element).transpose()?; let widget = WidgetUse::from_xml_node(xml.child("widget")?.only_child()?)?; @@ -37,6 +39,7 @@ impl EwwWindowDefinition { widget, stacking, screen_number, + focusable: focusable.unwrap_or(false), struts: struts.unwrap_or_default(), }) } diff --git a/src/value/mod.rs b/src/value/mod.rs index c0a4057..d9219be 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -21,6 +21,12 @@ impl std::borrow::Borrow for VarName { } } +impl From<&str> for VarName { + fn from(s: &str) -> Self { + VarName(s.to_owned()) + } +} + impl fmt::Debug for VarName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "VarName(\"{}\")", self.0) @@ -38,6 +44,12 @@ impl std::borrow::Borrow for AttrName { } } +impl From<&str> for AttrName { + fn from(s: &str) -> Self { + AttrName(s.to_owned()) + } +} + impl fmt::Debug for AttrName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "AttrName(\"{}\")", self.0) diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs index f99797d..fb9ce0c 100644 --- a/src/widgets/widget_definitions.rs +++ b/src/widgets/widget_definitions.rs @@ -223,15 +223,17 @@ fn build_gtk_scale(bargs: &mut BuilderArgs) -> Result { fn build_gtk_input(bargs: &mut BuilderArgs) -> Result { let gtk_widget = gtk::Entry::new(); let on_change_handler_id: Rc>> = Rc::new(RefCell::new(None)); - gtk_widget.set_editable(true); - gtk_widget.set_visible(true); - gtk_widget.set_text("fuck"); - gtk_widget.set_can_focus(true); resolve_block!(bargs, gtk_widget, { + // @prop value - the content of the text field + prop(value: as_string) { + gtk_widget.set_text(&value); + }, + + // @prop onchange - Command to run when the text changes. The placeholder `{}` will be replaced by the value prop(onchange: as_string) { let old_id = on_change_handler_id.replace(Some( - gtk_widget.connect_insert_text(move |_, text, _| { - run_command(&onchange, text); + gtk_widget.connect_changed(move |gtk_widget| { + run_command(&onchange, gtk_widget.get_text().to_string()); }) )); old_id.map(|id| gtk_widget.disconnect(id));