5 releases

0.0.51 Jun 11, 2024
0.0.50 Jun 11, 2024
0.0.45 Mar 31, 2022
0.0.40 Dec 18, 2021
0.0.39 Dec 18, 2021

#588 in GUI


Used in wmctl

MIT/Apache

120KB
2K SLoC

libwmctl

license-badge crates.io Minimum rustc

Rust X11 automation

libwmctl implements the Extended Window Manager Hints (EWMH) specification as a way to work along side EWMH compatible window managers as a companion. libwmctl provides the ability to precisely define how windows should be shaped and placed and can fill in gaps for window managers lacking some shaping or placement features. libwmctl exposes X11 details in a simple consumable way opening the door to window manipulation beyond what your favorite EWMH window manager provides.

Usage

This minimum rustc requirement is driven by the tracing_subscriber requirements

Shape window

Shape the active window using the pre-defined Shape::Small shape which is a quarter of the screen.

use libwmctl::prelude::*;

fn main() {
    active().shape(Shape::Small).place().unwrap();
}

Move window

Move the active window to the bottom left corner of the screen using the pre-defined Position::BottomLeft position.

use libwmctl::prelude::*;

fn main() {
    active().pos(Position::BottomLeft).place().unwrap();
}

Place window

Combine the shape and move into a single command by placing the window. First the window is shaped using the pre-defined Shap::Small shape then it is moved to the bottom left using the pre-defined Position:BottomLeft position in a single operation.

use libwmctl::prelude::*;

fn main() {
    active().shape(Shape::Small).pos(Position::BottomLeft).place().unwrap();
}

Window Manager info

use libwmctl::prelude::*;
use prettytable::{format, Cell, Row, Table};

fn main() {
    let wm = info().unwrap();
    let win = active();

    println!("Window Manager Information");
    println!("-----------------------------------------------------------------------");
    println!("Window Manager: {}", wm.name);
    println!("Compositing:    {}", wm.compositing);
    println!("Root Window:    {}", wm.root_win_id);
    println!("Work area:      {}x{}", wm.work_area.0, wm.work_area.1);
    println!("Screen Size:    {}x{}", wm.screen_size.0, wm.screen_size.1);
    println!("Desktops:       {}", wm.desktops);
    println!("Active Window:  {}", win.id);
    println!();

    println!("Window Manager Supported Functions:");
    let mut table = Table::new();
    table.set_format(
        format::FormatBuilder::new()
            .separator(format::LinePosition::Top, format::LineSeparator::new('-', '+', '+', '+'))
            .separator(format::LinePosition::Title, format::LineSeparator::new('=', '+', '+', '+'))
            .padding(1, 1)
            .build(),
    );
    table.set_titles(Row::new(vec![Cell::new("NAME"), Cell::new("ID")]));

    // Sort atoms by name
    let mut atoms = wm.supported.iter().collect::<Vec<_>>();
    atoms.sort_by(|a, b| a.1.cmp(b.1));
    for atom in atoms.iter() {
        table.add_row(Row::new(vec![Cell::new(&atom.1), Cell::new(&atom.0.to_string())]));
    }
    table.printstd();
}

Contribute

Pull requests are always welcome. However understand that they will be evaluated purely on whether or not the change fits with my goals/ideals for the project.

License

This project is licensed under either of:

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


Backlog

Changelog

Dependencies

~8–20MB
~262K SLoC