cnx icon indicating copy to clipboard operation
cnx copied to clipboard

How to make it work with Penrose?

Open MrFoxPro opened this issue 2 years ago • 1 comments

I'm trying to launch cnx with https://github.com/sminez/penrose Here is my code:

use cnx::Cnx;
use penrose::{
    builtin::{
        actions::{exit, log_current_state, modify_with, send_layout_message, spawn},
        layout::{
            messages::{ExpandMain, IncMain, ShrinkMain},
            transformers::{Gaps, ReflectHorizontal, ReserveTop},
            MainAndStack,
        },
    },
    core::{
        bindings::{parse_keybindings_with_xmodmap, KeyEventHandler},
        layout::LayoutStack,
        Config, WindowManager,
    },
    extensions::hooks::add_ewmh_hooks,
    map, stack,
    x11rb::RustConn,
};
use std::{collections::HashMap, thread, time::Duration};
use tracing::log::debug;
use tracing_subscriber::{self, prelude::*, EnvFilter};

fn raw_key_bindings() -> HashMap<String, Box<dyn KeyEventHandler<RustConn>>> {
    let mut raw_bindings = map! {
        // map_keys: |k: &str| format!("C-{k}");
        map_keys: |k: &str| k.to_owned();

        "M-j" => modify_with(|cs| cs.focus_down()),
        "M-k" => modify_with(|cs| cs.focus_up()),
        "M-S-j" => modify_with(|cs| cs.swap_down()),
        "M-S-k" => modify_with(|cs| cs.swap_up()),
        "M-S-q" => modify_with(|cs| cs.kill_focused()),
        "M-Tab" => modify_with(|cs| cs.toggle_tag()),
        "M-bracketright" => modify_with(|cs| cs.next_screen()),
        "M-bracketleft" => modify_with(|cs| cs.previous_screen()),
        "M-grave" => modify_with(|cs| cs.next_layout()),
        "M-S-grave" => modify_with(|cs| cs.previous_layout()),
        "M-Up" => send_layout_message(|| IncMain(1)),
        "M-Down" => send_layout_message(|| IncMain(-1)),
        "M-Right" => send_layout_message(|| ExpandMain),
        "M-Left" => send_layout_message(|| ShrinkMain),
        "M-semicolon" => spawn("dmenu_run"),
        "M-S-s" => log_current_state(),
        "M-Return" => spawn("st"),
        "M-A-Escape" => exit(),
    };

    for tag in &["1", "2", "3", "4", "5", "6", "7", "8", "9"] {
        raw_bindings.extend([
            (
                format!("M-{tag}"),
                // change_workspace(tag.to_string()),
                modify_with(move |client_set| {
                    // change_workspace::<RustConn>(tag.to_string());
                    client_set.focus_tag(tag);
                }),
            ),
            (
                format!("M-S-{tag}"),
                modify_with(move |client_set| client_set.move_focused_to_tag(tag)),
            ),
        ]);
    }

    raw_bindings
}

fn layouts() -> LayoutStack {
    let max_main = 1;
    let ratio = 0.6;
    let ratio_step = 0.1;
    let outer_px = 5;
    let inner_px = 5;
    let top_px = 18;

    stack!(
        MainAndStack::side(max_main, ratio, ratio_step),
        ReflectHorizontal::wrap(MainAndStack::side(max_main, ratio, ratio_step)),
        MainAndStack::bottom(max_main, ratio, ratio_step)
    )
    .map(|layout| ReserveTop::wrap(Gaps::wrap(layout, outer_px, inner_px), top_px))
}

fn main() {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .finish()
        .init();
    debug!("=====STARTING=======");
    let wm_handle = thread::spawn(|| {
        let config = add_ewmh_hooks(Config {
            default_layouts: layouts(),

            ..Config::default()
        });

        let conn = RustConn::new().unwrap();
        let key_bindings = parse_keybindings_with_xmodmap(raw_key_bindings()).unwrap();
        let wm = WindowManager::new(config, key_bindings, HashMap::new(), conn).unwrap();
        wm.run().unwrap();
    });

    let cnx_handle = thread::spawn(|| {
        let attr = cnx::text::Attributes {
            font: cnx::text::Font::new("Consolas"),
            fg_color: cnx::text::Color::blue(),
            bg_color: Some(cnx::text::Color::red()),
            padding: cnx::text::Padding::new(0.0, 0.0, 0.0, 0.0),
        };

        let mut cnx = Cnx::new(cnx::Position::Bottom);
        let time_template = Some("<span foreground=\"#808080\">[</span>%d-%m-%Y %a %I:%M %p<span foreground=\"#808080\">]</span>".into());
        cnx.add_widget(cnx::widgets::Clock::new(attr.clone(), time_template));
        cnx.add_widget(cnx::widgets::ActiveWindowTitle::new(attr.clone()));
        cnx.run().unwrap();
    });

    wm_handle.join();
    debug!("wm_handle is done");

    cnx_handle.join();
    debug!("cnx_handle is done");
}

In this case cnx doesn't launch properly (see small top rectangle): image

But it works only if I run it as another process or without spawning penrose thread. image

MrFoxPro avatar Feb 05 '23 13:02 MrFoxPro

Looks like it's related to hooks that penrose sets up. Don't actually do this, but I know because this works:

fn main() -> Result<()> {
    std::thread::spawn(cnx::run);
    std::thread::sleep(std::time::Duration::from_secs(1));
    println!("Picking up the torch in penrose land!");
    start_window_manager()?;
}

Mstrodl avatar Mar 29 '24 21:03 Mstrodl