Giter Club home page Giter Club logo

i3ipc-rs's People

Contributors

celti avatar chrde avatar emantor avatar emersion avatar jplatte avatar lbonn avatar lincheney avatar mosbasik avatar rkanati avatar soenkehahn avatar soumya92 avatar svenstaro avatar tmerr avatar wawe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

i3ipc-rs's Issues

Add missing WorkspaceChange enum variants

@soumya92 reported he was getting errors on an event workspace:reload

It looks like it has actually been around for a while but it was accidentally left undocumented until recently: i3/i3#2656 . We should add these cases to our WorkspaceChange enum, and probably "move" as well, which is also undocumented but hopefully not for long i3/i3#2847 .

Add the WorkspaceChangeEnum variants Rename, Reload, Restored, Move.

Should Node.id have type usize instead of i64?

At first glance, I would assume that id should be a usize...

    /// The internal ID (actually a C pointer value) of this container. Do not make any
    /// assumptions about it. You can use it to (re-)identify and address containers when
    /// talking to i3.
    pub id: i64,

@leshow's implementation does it that way:
https://github.com/leshow/tokio-i3ipc/blob/0a8be5fa88982851f9d924ddff7c60b4bfa51fe8/i3ipc-types/src/reply.rs#L40-L43

/// Tree/Node reply
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Node {
    pub id: usize,

i3 appears to treat it as a uintptr_t:
https://github.com/i3/i3/blob/f4964faef08d6add93afbd24cc00fef0c3f6c72a/src/ipc.c#L355-L358

void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
    y(map_open);
    ystr("id");
    y(integer, (uintptr_t)con);

https://github.com/i3/i3/blob/6339427f017e1265a022e6537e16a8b4a921e52f/include/yajl_utils.h#L18-L19

/* Shorter names for all those yajl_gen_* functions */
#define y(x, ...) yajl_gen_##x(gen, ##__VA_ARGS__)

...but then yajl treats it as a long long int / %lld?
https://github.com/lloyd/yajl/blob/5e3a7856e643b4d6410ddc3f84bc2f38174f2872/src/yajl_gen.c#L208-L218

yajl_gen_status
yajl_gen_integer(yajl_gen g, long long int number)
{
    char i[32];
    ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
    sprintf(i, "%lld", number);
    g->print(g->ctx, i, (unsigned int)strlen(i));
    APPENDED_ATOM;
    FINAL_NEWLINE;
    return yajl_gen_status_ok;
}

I don't know anymore. Anyone care to verify this?

Unreachable code error when subscribing to Subscription::Workspace

When running the following code, a runtime error is generated, included below.

use i3ipc::I3EventListener;
use i3ipc::Subscription;
use i3ipc::event::Event;

fn main() {
    let mut listener = I3EventListener::connect().unwrap();
    let subs = [Subscription::Workspace];
    listener.subscribe(&subs).unwrap();

    for event in listener.listen() {
    }
}
thread '<main>' panicked at 'internal error: entered unreachable code', /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/common.rs:38
stack backtrace:
   1:     0x55565ae3f1d0 - sys::backtrace::tracing::imp::write::h09d7a562cdce3ef9Xcv
   2:     0x55565ae431db - panicking::default_handler::_$u7b$$u7b$closure$u7d$$u7d$::closure.44519
   3:     0x55565ae42e48 - panicking::default_handler::hf7fdb8082bcb0f80lSz
   4:     0x55565ae35a3c - sys_common::unwind::begin_unwind_inner::hfa667eeafdcc5750g1t
   5:     0x55565adf1627 - sys_common::unwind::begin_unwind::h11005261735870655457
                        at src/libstd/sys/common/unwind/mod.rs:219
   6:     0x55565ae2302e - common::build_tree::h96a7d8fb1d22d801Uba
                        at /home/kerp/projects/rust/testproject/<std macros>:3
   7:     0x55565ae2586a - common::build_tree::_$u7b$$u7b$closure$u7d$$u7d$::closure.10324
                        at /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/common.rs:13
   8:     0x55565ae25843 - ops::impls::_&'a mut F.FnOnce<A>::call_once::h8679080268370381870
                        at src/libcore/ops.rs:1708
   9:     0x55565ae257e0 - option::Option<T>::map::h6160316823303540631
                        at src/libcore/option.rs:390
  10:     0x55565ae2577e - iter::Map<I, F>.Iterator::next::h6949550101614501572
                        at src/libcore/iter.rs:3342
  11:     0x55565ae253d3 - vec::Vec<T>.FromIterator<T>::from_iter::h6849771975379282085
                        at src/libcollections/vec.rs:1292
  12:     0x55565ae25369 - iter::Iterator::collect::h5970782354055407510
                        at src/libcore/iter.rs:1490
  13:     0x55565ae22761 - common::build_tree::h96a7d8fb1d22d801Uba
                        at /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/common.rs:10
  14:     0x55565adfbfd5 - event::WorkspaceEventInfo.FromStr::from_str::h52100c93567f9292S1a
                        at /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/event.rs:48
  15:     0x55565adf8ea1 - EventIterator<'a>.Iterator::next::build_event::h65c8a9849ad9db34kzb
                        at /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/lib.rs:174
  16:     0x55565adf8b8a - EventIterator<'a>.Iterator::next::h4c53229dde1206d7bzb
                        at /home/kerp/.cargo/registry/src/github.com-88ac128001ac3a9a/i3ipc-0.4.0/src/lib.rs:189
  17:     0x55565adeb5f3 - main::h51b6e621fe2aa0d9iaa
                        at src/main.rs:11
  18:     0x55565ae42aa4 - sys_common::unwind::try::try_fn::h17697512651770205889
  19:     0x55565ae3e5cb - __rust_try
  20:     0x55565ae4253b - rt::lang_start::h5628b9e1fb87c585rKz
  21:     0x55565adeec19 - main
  22:     0x7f283e91b740 - __libc_start_main
  23:     0x55565adeb3a8 - _start
  24:                0x0 - <unknown>
`

I Tested a few other events and they seem to work fine, I haven't tested all of them, though.

How to stop event listening?

I have this running:

        let mut event_listener = i3ipc::I3EventListener::connect().unwrap();

        for event in event_listener.listen() {
            match event.as_ref() {
                ...
            }
       }

Then I have a signal handler:

    let signals = Signals::new(&[SIGINT, SIGTERM]).unwrap();
    let signal_handler = thread::spawn(move || {
        for sig in signals.forever() {
            match sig {
                signal_hook::SIGINT => on_exit(&con_thread),
                signal_hook::SIGTERM => on_exit(&con_thread),
                _ => unreachable!(),
            }
        }
    });

There will be race-conditions, since on_exit will trigger i3 events. How can I stop the event listener or unsubscribe from events? Running it in a separate thread isn't an option, because I can't kill that thread, since event listening is a blocking operation.

Implement WindowChange::Mark

Sorry if my pull request wasn't as clear, I'm new to debugging Rust.

Marks showing up in the ipc json payload where introduced with i3 version 4.13 and it breaks i3ipc-rs.

Best regards and happy holidays,
Benny

Add an "unstable" feature to Cargo.toml

There's a few features folks are wanting that are "unstable" in i3 - particularly Node attributes and the like. Since i3 changes quite slowly, these attrs can be around for years. It seems like they could be added and guarded by a feature.

Then it could be simply enabled by something like:

[Dependencies]
i3rpc = { features = ["i3-next", "unstable"] }
...

It also gives a nice path forward for when i3 does update its stable features to include them.

How to find the currently focused workspace in the `Node` tree?

I'd like to be able to get the Node from the Node tree that represents the currently focused workspace.

I think in the current state a possible solution is to

  • call I3Connection::get_workspaces(),
  • traverse the workspaces and find the one where focused is true,
  • remember the name of that workspace,
  • call I3Connection::get_tree(),
  • traverse the tree to find the node that is a workspace and has the same name.

This seems very cumbersome. Also, I'm not 100% sure workspace names in i3 are guaranteed to always be unique. Are there any better solutions?

Also, would it be in the scope of this library to add a helper function for this?

Some tests not passed

Maybe we can fix this somehow?

running 19 tests
test test::connect ... FAILED
test test::from_str_barconfig ... ok
test test::from_str_binding_event ... ok
test test::event_subscribe ... FAILED
test test::from_str_window ... ok
test test::from_str_mode ... ok
test test::from_str_workspace ... ok
test test::get_bar_ids ... FAILED
test test::get_marks ... FAILED
test test::get_outputs ... FAILED
test test::get_bar_ids_and_one_config ... FAILED
test test::get_version ... FAILED
test test::get_workspaces ... FAILED
test test::from_str_output ... ok
test test::run_command_fail ... FAILED
test test::run_command_nothing ... FAILED
test test::run_command_multiple_success ... FAILED
test test::get_tree ... FAILED
test test::run_command_single_sucess ... FAILED
failures:
---- test::connect stdout ----
thread 'test::connect' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- test::event_subscribe stdout ----
thread 'test::event_subscribe' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_bar_ids stdout ----
thread 'test::get_bar_ids' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_marks stdout ----
thread 'test::get_marks' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_outputs stdout ----
thread 'test::get_outputs' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_bar_ids_and_one_config stdout ----
thread 'test::get_bar_ids_and_one_config' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_version stdout ----
thread 'test::get_version' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_workspaces stdout ----
thread 'test::get_workspaces' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::run_command_fail stdout ----
thread 'test::run_command_fail' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::run_command_nothing stdout ----
thread 'test::run_command_nothing' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::run_command_multiple_success stdout ----
thread 'test::run_command_multiple_success' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::get_tree stdout ----
thread 'test::get_tree' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
---- test::run_command_single_sucess stdout ----
thread 'test::run_command_single_sucess' panicked at 'called `Result::unwrap()` on an `Err` value: GetSocketPathError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/libcore/result.rs:1165:5
failures:
    test::connect
    test::event_subscribe
    test::get_bar_ids
    test::get_bar_ids_and_one_config
    test::get_marks
    test::get_outputs
    test::get_tree
    test::get_version
    test::get_workspaces
    test::run_command_fail
    test::run_command_multiple_success
    test::run_command_nothing
    test::run_command_single_sucess
test result: FAILED. 6 passed; 13 failed; 0 ignored; 0 measured; 0 filtered out

Change I3Connection::command to I3Connection::run_command

See i3/i3@607e97e

ipc: rename COMMAND to RUN_COMMAND for consistency
Authors of downstream IPC libraries are encouraged to keep the old name around
so as to not break existing code, but mark it as deprecated.

There's not much of a risk for i3ipc-rs since the README shows an example of using a specific i3ipc-rs version (no star) and we're still not 1.0. That said it would be interesting to do a quick github search to see if this is the case

Tree iteration helpers

A Node.find_focused function would be nice. I wrote out an example in #29 but we have to remember to check floating_nodes too.

An iterator across the entire tree might be helpful as well.

Add struct for rects?

I'm just seeing if there's any interest in creating a struct to wrap the rects received from i3. Ideally these:

https://github.com/tmerr/i3ipc-rs/blob/master/src/reply.rs#L211

Could be changed to something along the lines of:

struct Rect {
    top: i32,
    left: i32,
    width: i32,
    height: i32,
}

Which would make things like:

let height = node.rect.3;

Become much more readable:

let height = node.rect.height;

I'm more than happy to create a PR with these changes if that's something that we can do.

How to get focussed client

Hey there!

First of all, thank you for all the work that went into writing this library! I'm really glad it exists :)

I've been playing around with it a little bit but there's something I'm not super sure about โ€“ maybe because the i3 IPC interface is generally new to me.

I want to find out what client is actually focused. Now, there is the focused field but it includes several id's and when I try to query those from the nodes field I just get back generic eDP-1 or _i3 or whatever.

I guess I'm misunderstanding the API here? Any help would be appreciated! :)

Support for the `marks (array of string)` field in TREE reply

Unless I'm missing something (which is quite possible!) it looks like the marks field of the IPC response to the get_tree method is not present in i3ipc-rs. Is there a reason it's not present? There's a get_marks method that returns the currently used marks, but there's no way to correlate them with the nodes that have the mark, AFAICT.

I'm open to making a PR to add this; I wanted to confirm I'm right and check in first.

Why are `I3Connection` and `I3EventListener` separate?

It seems they both access the same socket file, why are they separate types? Currently, if I want to get the current workspace state at the beginning of my program and then all subscribe to workspace updates, this requires opening the socket file twice.

Be more resilient to additions to ipc interface

At runtime i3ipc-rs shouldn't depend on i3 version == X. It should depend on i3 version >= X. In theory this should be possible since i3 aims to continually add things to its ipc interface while staying backwards compatible. In order to support this we need to change the way we work with the parsed JSON. It's OK to ask for the value of a field, but it's not OK to ask for the value to lie in a fixed set of possibilities, which we do when constructing many enums in events.rs. Rework this library so it doesn't break after routine i3 upgrades.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.