djpohly / dwl

dwm for Wayland - ARCHIVE: development has moved to Codeberg
https://codeberg.org/dwl/dwl
Other
1.93k stars 284 forks source link

Run or Raise #519

Open clicseo opened 9 months ago

clicseo commented 9 months ago

Hello,

I am trying to implement a run or raise feature on my new dwl build. I used wlrctl for all my other wayland compositors but I am getting Foreign Toplevel Management interface not found! on dwl.

How can I implement this feature, any other available tool to get it? I want to have keybindings to open apps, or focus them if they're already opened instead of opening new instances of the app.

Thank you in advance!

wochap commented 9 months ago

You could extend the functionality of the namedscratchpads patch:

void
run_or_raise_scratch(const Arg *arg)
{
    Client *c;
    unsigned int found = 0;

    /* search for first window that matches the scratchkey */
    wl_list_for_each(c, &clients, link)
        if (c->scratchkey == ((char**)arg->v)[0][0]) {
            found = 1;
            break;
        }

    if (found) {
        if (VISIBLEON(c, selmon)) {
            if (focustop(selmon) != c) {
                    // focus
                focusclient(c, 1);
            }
        } else {
            // show/move client to current workspace/tags
            c->tags = selmon->tagset[selmon->seltags];
            // TODO: or change current workspace/tags to where client is located

            // focus
            focusclient(c, 1);
        }
        arrange(selmon);
    } else{
        spawnscratch(arg);
    }
}
Sneethe commented 9 months ago

If this works well. Be sure to add it to the patch list.

clicseo commented 9 months ago

You could extend the functionality of the namedscratchpads patch:

void
run_or_raise_scratch(const Arg *arg)
{
  Client *c;
  unsigned int found = 0;

  /* search for first window that matches the scratchkey */
  wl_list_for_each(c, &clients, link)
      if (c->scratchkey == ((char**)arg->v)[0][0]) {
          found = 1;
          break;
      }

  if (found) {
      if (VISIBLEON(c, selmon)) {
          if (focustop(selmon) != c) {
                  // focus
              focusclient(c, 1);
          }
      } else {
          // show/move client to current workspace/tags
          c->tags = selmon->tagset[selmon->seltags];
          // TODO: or change current workspace/tags to where client is located

          // focus
          focusclient(c, 1);
      }
      arrange(selmon);
  } else{
      spawnscratch(arg);
  }
}

After a couple of days fighting with this I managed to make it work. Thank you very much for your help, the only thing I had to change is:


        selmon->tagset[selmon->seltags] = c->tags;
        focusclient(c, 1);
        arrange(selmon);