emgram769 / lighthouse

A simple scriptable popup dialog to run on X.
MIT License
633 stars 31 forks source link

doesn't grab focus with xmonad #87

Open mwotton opened 8 years ago

mwotton commented 8 years ago

when i run dmenu, keyboard focus goes straight to the input. with lighthouse, i seem to have to move the mouse to the window.

I tried poking it a bit:

  fprintf(stderr, "trying to set focus\n");
  xcb_void_cookie_t set_focus = xcb_set_input_focus_checked(connection, XCB_INPUT_FOCUS_POINTER_ROOT, window, XCB_CURRENT_TIME);
  fprintf(stderr, "set focus, apparently\n");
  xcb_generic_error_t *error;
  if ((error = xcb_request_check(connection, set_focus))) {
    fprintf(stderr, "Could not set focus: %d. responsetype: %d. minor:%d. major:%d.\n",
            error->error_code, error->response_type, error->minor_code, error->major_code);
    free(error);
    goto cleanup;
  }

but got

Could not set focus: 8. responsetype: 0. minor:0. major:42.

any help in debugging would be appreciated, lighthouse looks like exactly what i'm after (just want to hook it up to https://github.com/mwotton/dustme )

JonasRSV commented 4 years ago

I am having the same issue, did you manage to resolve it?

JonasRSV commented 4 years ago

I manged to solve it in a very hacky way.. dmenu works on xmonad and dmenu uses xlib.

It is possible to have a xlib + xcb connection open at the same time

  // X lib connection
  Display * xlib_connection = XOpenDisplay(NULL); 

  /* Connect to the X server. */
  xcb_connection_t *connection = XGetXCBConnection(xlib_connection); 

then using the focus function from dmenu (re-written slightly)

void grab_focus(Display *display, xcb_window_t *window) {

  struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000  };
    Window focuswin, mainwin = *(Window*)window;
    int i, revertwin;

    for (i = 0; i < 100; ++i) {
        XGetInputFocus(display, &focuswin, &revertwin);
        if (focuswin == mainwin)
            return;
        XSetInputFocus(display, mainwin, RevertToParent, CurrentTime);
        nanosleep(&ts, NULL);
    }
}

Then calling that inside the event handlers instead

      case XCB_EXPOSE: {
        /* Get the input focus. */

        grab_focus(xlib_connection, &window);

        /* Redraw. */
        redraw_all(connection, window, cairo_context, cairo_surface, query_string, query_cursor_index);
        break;
      }

I am sure this is a terrible solution to anyone who actually has any experience with this kind of stuff. But atleast it lets me use this awesome tool with Xmonad as well.

JonasRSV commented 4 years ago

I made a fork, https://github.com/JonasRSV/lighthouse with the fix. Don't know if it is worthy of a PR.. If it is im happy to make it, otherwise I'll just leave it at this.