Project

General

Profile

Hooks and Subtlext spawn issues

Added by Łukasz Jachymczyk over 8 years ago

Hey,

I have recently started playing around with subtle. It seems to be very minimalistic yet powerful and I like it.

During customizing my config script I found some strange issues and problems I can't figure out. Here they are:

1. I added simple hook to my default config script:

on :client_create do |c|
  puts c.name
end

Client names seem to be printed not every client creation. In fact, I managed to get only first few clients' names printed and then hook was gone.

2. Subtlext spawn problem

Consider following example of using Subtlext in irb (I omitted here require line)

irb(main):011:0> c = Subtlext::Subtle.spawn('terminal')
=> 
irb(main):012:0> c.class
=> Subtlext::Client
irb(main):013:0> c.name
=> nil
irb(main):014:0> c.pid
=> nil

Other methods are not working as well. The same occurs in i.e. grab blocks.
Am I missing something?

I have more issues but these are bothering me the most. Looking forward to your feedback. My subtle version is 0.9.2773-2.


Replies (7)

RE: Hooks and Subtlext spawn issues - Added by Christoph Kappel over 8 years ago

1) Actually hooks cannot be gone, they are called whenever a window under subtle's management is created. Did you check if any error happend during the hook with your missing clients?

2) This causes a race condition, subtlext cannot create the client AND fetch the client data in one call. subtle needs some time to handle the events. You need to call #update afterwards to fill the missing fields.

c = Subtlext::Subtle.spawn("terminal"); c.update; 

RE: Hooks and Subtlext spawn issues - Added by Łukasz Jachymczyk over 8 years ago

1. Apparently I had my config script messed up, I can't reproduce this issue right now.

2. Great, that's what I was looking for.
It works for hooks, but... I set up grab:

grab "W-t" do |c| 
  puts 'spawning terminal'
  c = Subtlext::Subtle.spawn("terminal")
  puts 'spawned terminal'
  c.update
  puts 'updated terminal ' + c.pid
  c.focus
end

Update and focus does not work in this case.
This is what is logged:
spawning terminal
spawned terminal
<WARNING> StandardError: Failed updating client
        from /home/lfx/.config/subtle/subtle.rb:435:in `update'
        from /home/lfx/.config/subtle/subtle.rb:435:in `block in <main>'
        from subtle:in `call'

3. Another issue came up. I would like to have certain clients focused after clicking them. Is there any way to do that i.e. using hooks?

RE: Hooks and Subtlext spawn issues - Added by Christoph Kappel over 8 years ago

1+2) That this is a race condition, especially in grabs and hooks.

subtle is single threaded, when you spawn a client inside of a block like a grab, subtle needs to finish the block before it can handle the event that creates a new client. To minimize problems like that, Subtlext::Subtle.spawn returns a client with a good guess of the id of the next client and you can update that after subtle processed the event.

3) Nope, focus model is focus follows pointer, when your pointer enters a client window it already has focus.

RE: Hooks and Subtlext spawn issues - Added by Łukasz Jachymczyk over 8 years ago

Christoph Kappel wrote:

To minimize problems like that, Subtlext::Subtle.spawn returns a client with a good guess of the id of the next client and you can update that after subtle processed the event.

Ok, I understand. So is there any way to remember this client id and process it somewhere else (i.e. in :client_create hook)? Or any other way to obtain valid client spawned in grab block?

3) Nope, focus model is focus follows pointer, when your pointer enters a client window it already has focus.

I see. What about rising client up after clicking?

Thanks for your feedback and sorry for bothering that much:)

RE: Hooks and Subtlext spawn issues - Added by Christoph Kappel over 8 years ago

Well, the config is a valid ruby script so you can do something like that:

client = nil

grab "W-t" do
  Subtlext::Subtle.spawn("terminal")
  client = "terminal" 
end

on :client_create do |c|
  if(c.instance == client)
    c.focus
    client = "" 
  end
end

But why not just setting a client to urgent? That automatically draws the focus and urgent state is removed when the window gets focus.

tag "terminal" do
  match "terminal" 
  urgent true
end

Rising on client has some bad side-effects neither you or me are aware of. Generally you can do that but I tried it once and I wouldn't recommend it.

And no problem. :)

RE: Hooks and Subtlext spawn issues - Added by Łukasz Jachymczyk over 8 years ago

It is me again:) After further experiments with subtle config script, I have noticed that managing client's tags in :client_create hook is also limited. Namely, only last call of tag or untag methods is executed. So if I have several tag method calls, only last one of them will be effective. Is there any workaround for that?

RE: Hooks and Subtlext spawn issues - Added by Christoph Kappel over 8 years ago

That again is caused by the race condition, subtle can't add a tag while executing a hooks and therefore just uses the last known tagging. The easiest way to bypass this is to change all tags at once:

on :client_create do |c|
  c.tags = c.tags + [ "tag1", "tag2", "tag3" ]
end

I hope this is coupled with any condition, otherwise just adding the correct tag matches would be easier.

    (1-7/7)