diff options
author | Dave Davenport <qball@gmpclient.org> | 2016-02-28 00:09:05 +0100 |
---|---|---|
committer | Dave Davenport <qball@gmpclient.org> | 2016-02-28 00:09:05 +0100 |
commit | d813d03a5fa16d187e446dd565cc4a6073d5ba68 (patch) | |
tree | 301c355ce2378a06ecc3cfeb9c49c500804154d8 /source | |
parent | 4c661c39326d815318cabea213a405fb31faec96 (diff) |
Convert more stuff to xcb, keyboard grab, cleanup
Diffstat (limited to 'source')
-rw-r--r-- | source/dialogs/window.c | 47 | ||||
-rw-r--r-- | source/i3-support.c | 14 | ||||
-rw-r--r-- | source/rofi.c | 4 | ||||
-rw-r--r-- | source/view.c | 43 | ||||
-rw-r--r-- | source/x11-helper.c | 137 |
5 files changed, 78 insertions, 167 deletions
diff --git a/source/dialogs/window.c b/source/dialogs/window.c index e17c8a95..4090282f 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -36,9 +36,7 @@ #include <errno.h> #include <xcb/xcb.h> #include <xcb/xcb_ewmh.h> -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> +#include <xcb/xcb_icccm.h> #include "rofi.h" #include "settings.h" @@ -52,7 +50,6 @@ #define CLIENTTITLE 100 #define CLIENTCLASS 50 -#define CLIENTNAME 50 #define CLIENTSTATE 10 #define CLIENTWINDOWTYPE 10 #define CLIENTROLE 50 @@ -68,13 +65,11 @@ typedef struct xcb_get_window_attributes_reply_t xattr; char title[CLIENTTITLE]; char class[CLIENTCLASS]; - char name[CLIENTNAME]; char role[CLIENTROLE]; int states; xcb_atom_t state[CLIENTSTATE]; int window_types; xcb_atom_t window_type[CLIENTWINDOWTYPE]; - workarea monitor; int active; int demands; long hint_flags; @@ -286,38 +281,34 @@ static client* window_client ( Display *display, xcb_window_t win ) } char *name; - if ( ( name = window_get_text_prop ( display, c->window, xcb_ewmh._NET_WM_NAME ) ) && name ) { + if ( ( name = window_get_text_prop ( xcb_connection, c->window, xcb_ewmh._NET_WM_NAME ) ) && name ) { snprintf ( c->title, CLIENTTITLE, "%s", name ); g_free ( name ); } - else if ( XFetchName ( display, c->window, &name ) ) { + else if ( (name = window_get_text_prop ( xcb_connection, c->window, XCB_ATOM_WM_NAME)) && name) { snprintf ( c->title, CLIENTTITLE, "%s", name ); - XFree ( name ); + g_free ( name ); } - name = window_get_text_prop ( display, c->window, XInternAtom ( display, "WM_WINDOW_ROLE", False ) ); + name = window_get_text_prop ( xcb_connection, c->window, XInternAtom ( display, "WM_WINDOW_ROLE", False ) ); if ( name != NULL ) { snprintf ( c->role, CLIENTROLE, "%s", name ); - XFree ( name ); + g_free ( name ); } - XClassHint chint; - - if ( XGetClassHint ( display, c->window, &chint ) ) { - snprintf ( c->class, CLIENTCLASS, "%s", chint.res_class ); - snprintf ( c->name, CLIENTNAME, "%s", chint.res_name ); - XFree ( chint.res_class ); - XFree ( chint.res_name ); + name = window_get_text_prop ( xcb_connection, c->window, XCB_ATOM_WM_CLASS ); + if ( name != NULL ){ + snprintf ( c->class, CLIENTCLASS, "%s", name); + g_free(name); } - XWMHints *wh; - if ( ( wh = XGetWMHints ( display, c->window ) ) != NULL ) { - c->hint_flags = wh->flags; - XFree ( wh ); + xcb_get_property_cookie_t cc = xcb_icccm_get_wm_hints ( xcb_connection, c->window); + xcb_icccm_wm_hints_t r; + if (xcb_icccm_get_wm_hints_reply ( xcb_connection, cc, &r, NULL)){ + c->hint_flags = r.flags; } -// monitor_dimensions ( xcb_connection, xcb_screen, c->xattr.x, c->xattr.y, &c->monitor ); winlist_append ( cache_client, c->window, c ); return c; } @@ -366,10 +357,6 @@ static int window_match ( const Mode *sw, char **tokens, test = token_match ( ftokens, c->role, not_ascii, case_sensitive ); } - if ( !test && c->name[0] != '\0' ) { - test = token_match ( ftokens, c->name, not_ascii, case_sensitive ); - } - if ( test == 0 ) { match = 0; } @@ -395,7 +382,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) x11_cache_create (); // Check for i3 - pd->config_i3_mode = i3_support_initialize ( display, xcb_connection ); + pd->config_i3_mode = i3_support_initialize ( xcb_connection ); if ( !xcb_ewmh_get_active_window_reply ( &xcb_ewmh, xcb_ewmh_get_active_window( &xcb_ewmh, xcb_screen_nbr), &curr_win_id, NULL )) { @@ -445,7 +432,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) if ( client_has_state ( c, xcb_ewmh._NET_WM_STATE_DEMANDS_ATTENTION ) ) { c->demands = TRUE; } - if ( ( c->hint_flags & XUrgencyHint ) == XUrgencyHint ) { + if ( ( c->hint_flags & XCB_ICCCM_WM_HINT_X_URGENCY ) != 0) { c->demands = TRUE; } @@ -600,7 +587,7 @@ static int window_is_not_ascii ( const Mode *sw, unsigned int index ) int idx = winlist_find ( cache_client, ids->array[index] ); g_assert ( idx >= 0 ); client *c = cache_client->data[idx]; - return !g_str_is_ascii ( c->role ) || !g_str_is_ascii ( c->class ) || !g_str_is_ascii ( c->title ) || !g_str_is_ascii ( c->name ); + return !g_str_is_ascii ( c->role ) || !g_str_is_ascii ( c->class ) || !g_str_is_ascii ( c->title ); } #include "mode-private.h" diff --git a/source/i3-support.c b/source/i3-support.c index 4ed23669..713a29ac 100644 --- a/source/i3-support.c +++ b/source/i3-support.c @@ -33,8 +33,7 @@ #include <fcntl.h> #include <errno.h> #include <time.h> -#include <X11/X.h> -#include <X11/Xlib.h> +#include <xcb/xcb.h> #include <sys/socket.h> #include <sys/un.h> @@ -47,6 +46,7 @@ #include <i3/ipc.h> // Path to HAVE_I3_IPC_H socket. char *i3_socket_path = NULL; +extern xcb_screen_t *xcb_screen; void i3_support_focus_window ( Window id ) { @@ -113,7 +113,7 @@ void i3_support_focus_window ( Window id ) close ( s ); } -int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection ) +int i3_support_initialize ( xcb_connection_t *xcb_connection ) { // If we where initialized, clean this first. i3_support_free_internals (); @@ -122,12 +122,8 @@ int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection ) xcb_intern_atom_cookie_t cookie = xcb_intern_atom ( xcb_connection, FALSE, strlen ( "I3_SOCKET_PATH" ), "I3_SOCKET_PATH" ); xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( xcb_connection, cookie, NULL ); if ( reply != NULL ) { - // Get the default screen. - Screen *screen = DefaultScreenOfDisplay ( display ); - // Find the root window (each X has one.). - Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); // Get the i3 path property. - i3_socket_path = window_get_text_prop ( display, root, reply->atom ); + i3_socket_path = window_get_text_prop ( xcb_connection, xcb_screen->root, reply->atom ); } // If we find it, go into i3 mode. return ( i3_socket_path != NULL ) ? TRUE : FALSE; @@ -150,7 +146,7 @@ void i3_support_free_internals ( void ) { } -int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection ) +int i3_support_initialize ( xcb_connection_t *xcb_connection ) { return FALSE; } diff --git a/source/rofi.c b/source/rofi.c index aa38ecf5..eca01995 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -157,7 +157,7 @@ static void teardown ( int pfd ) textbox_cleanup ( ); // Release the window. - release_keyboard ( display ); + release_keyboard ( xcb_connection ); // Cleanup view rofi_view_cleanup (); @@ -778,7 +778,7 @@ int main ( int argc, char *argv[] ) exit ( EXIT_SUCCESS ); } - x11_setup ( display, &xkb ); + x11_setup ( xcb_connection, &xkb ); main_loop_source = g_water_xcb_source_new_for_connection ( NULL, xcb_connection, main_loop_x11_event_handler, NULL, NULL ); TICK_N ( "X11 Setup " ); diff --git a/source/view.c b/source/view.c index 615c57bc..d575d819 100644 --- a/source/view.c +++ b/source/view.c @@ -62,7 +62,6 @@ #include "view-internal.h" // What todo with these. -extern Display *display; extern xcb_connection_t *xcb_connection; extern xcb_screen_t *xcb_screen; extern SnLauncheeContext *sncontext; @@ -998,7 +997,7 @@ static void rofi_view_paste ( RofiViewState *state, xcb_selection_notify_event_t if ( xse->property == XCB_ATOM_NONE ){ fprintf ( stderr, "Failed to convert selection\n" ); } else if ( xse->property == xcb_ewmh.UTF8_STRING ) { - gchar *text = window_get_text_prop ( display, main_window, xcb_ewmh.UTF8_STRING ); + gchar *text = window_get_text_prop ( xcb_connection, main_window, xcb_ewmh.UTF8_STRING ); if ( text != NULL && text[0] != '\0' ) { unsigned int dl = strlen ( text ); // Strip new line @@ -1280,12 +1279,12 @@ static void rofi_view_mainloop_iter ( RofiViewState *state, xcb_generic_event_t { case XCB_FOCUS_IN: if ( ( state->menu_flags & MENU_NORMAL_WINDOW ) == 0 ) { - take_keyboard ( display, main_window ); + take_keyboard ( xcb_connection, main_window ); } break; case XCB_FOCUS_OUT: if ( ( state->menu_flags & MENU_NORMAL_WINDOW ) == 0 ) { - release_keyboard ( display ); + release_keyboard ( xcb_connection ); } break; case XCB_MOTION_NOTIFY: @@ -1492,6 +1491,13 @@ RofiViewState *rofi_view_create ( Mode *sw, state->num_lines = mode_get_num_entries ( sw ); state->lines_not_ascii = g_malloc0_n ( state->num_lines, sizeof ( int ) ); + // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker + if ( main_window == 0 ) { + main_window = __create_window ( xcb_connection, xcb_screen, menu_flags ); + if ( sncontext != NULL ) { + sn_launchee_context_setup_window ( sncontext, main_window ); + } + } // find out which lines contain non-ascii codepoints, so we can be faster in some cases. if ( state->num_lines > 0 ) { TICK_N ( "Is ASCII start" ); @@ -1529,12 +1535,13 @@ RofiViewState *rofi_view_create ( Mode *sw, g_mutex_clear ( &mutex ); TICK_N ( "Is ASCII stop" ); } + TICK_N ( "Startup notification" ); // Try to grab the keyboard as early as possible. // We grab this using the rootwindow (as dmenu does it). // this seems to result in the smallest delay for most people. if ( ( menu_flags & MENU_NORMAL_WINDOW ) == 0 ) { - int has_keyboard = take_keyboard ( display, DefaultRootWindow ( display ) ); + int has_keyboard = take_keyboard ( xcb_connection, xcb_screen->root ); if ( !has_keyboard ) { fprintf ( stderr, "Failed to grab keyboard, even after %d uS.", 500 * 1000 ); @@ -1544,14 +1551,6 @@ RofiViewState *rofi_view_create ( Mode *sw, } } TICK_N ( "Grab keyboard" ); - // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker - if ( main_window == 0 ) { - main_window = __create_window ( xcb_connection, xcb_screen, menu_flags ); - if ( sncontext != NULL ) { - sn_launchee_context_setup_window ( sncontext, main_window ); - } - } - TICK_N ( "Startup notification" ); // Get active monitor size. monitor_active ( xcb_connection, &( state->mon ) ); TICK_N ( "Get active monitor" ); @@ -1697,15 +1696,6 @@ void rofi_view_error_dialog ( const char *msg, int markup ) state->x11_event_loop = __error_dialog_event_loop; state->finalize = process_result_error; - // Try to grab the keyboard as early as possible. - // We grab this using the rootwindow (as dmenu does it). - // this seems to result in the smallest delay for most people. - int has_keyboard = take_keyboard ( display, DefaultRootWindow ( display ) ); - - if ( !has_keyboard ) { - fprintf ( stderr, "Failed to grab keyboard, even after %d uS.", 500 * 1000 ); - return; - } // Get active monitor size. monitor_active ( xcb_connection, &( state->mon ) ); if ( config.fake_transparency ) { @@ -1716,6 +1706,15 @@ void rofi_view_error_dialog ( const char *msg, int markup ) main_window = __create_window ( xcb_connection, xcb_screen, MENU_NORMAL ); } + // Try to grab the keyboard as early as possible. + // We grab this using the rootwindow (as dmenu does it). + // this seems to result in the smallest delay for most people. + int has_keyboard = take_keyboard ( xcb_connection, xcb_screen->root ); + if ( !has_keyboard ) { + fprintf ( stderr, "Failed to grab keyboard, even after %d uS.", 500 * 1000 ); + return; + } + rofi_view_calculate_window_and_element_width ( state ); state->max_elements = 0; diff --git a/source/x11-helper.c b/source/x11-helper.c index bad7fec6..b5d20e9a 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -37,14 +37,6 @@ #include <xcb/xcb.h> #include <xcb/xinerama.h> #include <xcb/xcb_ewmh.h> -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <X11/Xmd.h> -#include <X11/Xutil.h> -#include <X11/Xproto.h> -#include <X11/keysym.h> -#include <X11/XKBlib.h> #include "settings.h" #include <rofi.h> @@ -75,80 +67,30 @@ xcb_visualtype_t *visual = NULL; xcb_colormap_t map = XCB_COLORMAP_NONE; xcb_depth_t *root_depth = NULL; xcb_visualtype_t *root_visual = NULL; -Atom netatoms[NUM_NETATOMS]; +xcb_atom_t netatoms[NUM_NETATOMS]; const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; static unsigned int x11_mod_masks[NUM_X11MOD]; extern xcb_ewmh_connection_t xcb_ewmh; extern xcb_connection_t *xcb_connection; -// retrieve a property of any type from a window -int window_get_prop ( Display *display, Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes ) -{ - int format; - unsigned long nitems, nbytes; - unsigned char *ret = NULL; - memset ( buffer, 0, bytes ); - - if ( XGetWindowProperty ( display, w, prop, 0, bytes / 4, False, AnyPropertyType, type, &format, &nitems, &nbytes, &ret ) == Success && - ret && *type != None && format ) { - if ( format == 8 ) { - memmove ( buffer, ret, MIN ( bytes, nitems ) ); - } - - if ( format == 16 ) { - memmove ( buffer, ret, MIN ( bytes, nitems * sizeof ( short ) ) ); - } - - if ( format == 32 ) { - memmove ( buffer, ret, MIN ( bytes, nitems * sizeof ( long ) ) ); - } - - *items = ( int ) nitems; - XFree ( ret ); - return 1; - } - - return 0; -} - // retrieve a text property from a window // technically we could use window_get_prop(), but this is better for character set support -char* window_get_text_prop ( Display *display, Window w, Atom atom ) +char* window_get_text_prop ( xcb_connection_t *xcb_connection, xcb_window_t w, Atom atom ) { - XTextProperty prop; - char *res = NULL; - char **list = NULL; - int count; - - if ( XGetTextProperty ( display, w, &prop, atom ) && prop.value && prop.nitems ) { - if ( prop.encoding == XA_STRING ) { - size_t l = strlen ( ( char *) prop.value ) + 1; - res = g_malloc ( l ); - // make clang-check happy. - if ( res ) { - g_strlcpy ( res, ( char * ) prop.value, l ); - } - } - else if ( Xutf8TextPropertyToTextList ( display, &prop, &list, &count ) >= Success && count > 0 && *list ) { - size_t l = strlen ( *list ) + 1; - res = g_malloc ( l ); - // make clang-check happy. - if ( res ) { - g_strlcpy ( res, *list, l ); - } - XFreeStringList ( list ); - } - } - - if ( prop.value ) { - XFree ( prop.value ); + xcb_get_property_cookie_t c = xcb_get_property( xcb_connection, 0, w, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); + xcb_get_property_reply_t *r = xcb_get_property_reply( xcb_connection, c, NULL); + if ( r ){ + char *str = g_malloc ( xcb_get_property_value_length(r)+1); + memcpy(str, xcb_get_property_value(r), xcb_get_property_value_length(r)); + str[xcb_get_property_value_length(r)] = '\0'; + free(r); + return str; } - - return res; + return NULL; } -void window_set_atom_prop ( xcb_connection_t *xcb_connection, Window w, xcb_atom_t prop, xcb_atom_t *atoms, int count ) +void window_set_atom_prop ( xcb_connection_t *xcb_connection, xcb_window_t w, xcb_atom_t prop, xcb_atom_t *atoms, int count ) { xcb_change_property ( xcb_connection, XCB_PROP_MODE_REPLACE, w, prop, XCB_ATOM_ATOM, 32, count, atoms); } @@ -283,7 +225,7 @@ void monitor_dimensions ( xcb_connection_t *xcb_connection, xcb_screen_t *screen * * @returns 1 when found */ -static int pointer_get ( xcb_connection_t *xcb_connection, Window root, int *x, int *y ) +static int pointer_get ( xcb_connection_t *xcb_connection, xcb_window_t root, int *x, int *y ) { *x = 0; *y = 0; @@ -367,11 +309,15 @@ void monitor_active ( xcb_connection_t *xcb_connection, workarea *mon ) monitor_dimensions ( xcb_connection, xcb_screen, 0, 0, mon ); } -int take_keyboard ( Display *display, Window w ) +int take_keyboard ( xcb_connection_t *xcb_connection, xcb_window_t w ) { + for ( int i = 0; i < 500; i++ ) { - if ( XGrabKeyboard ( display, w, True, GrabModeAsync, GrabModeAsync, - CurrentTime ) == GrabSuccess ) { + xcb_grab_keyboard_cookie_t cc = xcb_grab_keyboard ( xcb_connection, 1, w, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC); + xcb_grab_keyboard_reply_t *r = xcb_grab_keyboard_reply ( xcb_connection, cc, NULL); + if ( r ) { + free ( r ); return 1; } usleep ( 1000 ); @@ -380,9 +326,9 @@ int take_keyboard ( Display *display, Window w ) return 0; } -void release_keyboard ( Display *display ) +void release_keyboard ( xcb_connection_t *xcb_connection ) { - XUngrabKeyboard ( display, CurrentTime ); + xcb_ungrab_keyboard ( xcb_connection, XCB_CURRENT_TIME); } static unsigned int x11_find_mod_mask ( xkb_stuff *xkb, ... ) @@ -507,7 +453,7 @@ void x11_parse_key ( char *combo, unsigned int *mod, xkb_keysym_t *key ) *key = sym; } -void x11_set_window_opacity ( xcb_connection_t *xcb_connection, Window box, unsigned int opacity ) +void x11_set_window_opacity ( xcb_connection_t *xcb_connection, xcb_window_t box, unsigned int opacity ) { // Scale 0-100 to 0 - UINT32_MAX. unsigned int opacity_set = ( unsigned int ) ( ( opacity / 100.0 ) * UINT32_MAX ); @@ -521,42 +467,25 @@ void x11_set_window_opacity ( xcb_connection_t *xcb_connection, Window box, unsi * * Fill in the list of Atoms. */ -static void x11_create_frequently_used_atoms ( Display *display ) +static void x11_create_frequently_used_atoms ( xcb_connection_t *xcb_connection ) { - // X atom values + // X atom values for ( int i = 0; i < NUM_NETATOMS; i++ ) { - netatoms[i] = XInternAtom ( display, netatom_names[i], False ); + xcb_intern_atom_cookie_t cc = xcb_intern_atom ( xcb_connection, 0, strlen(netatom_names[i]), netatom_names[i]); + xcb_intern_atom_reply_t *r = xcb_intern_atom_reply ( xcb_connection, cc, NULL); + if ( r ) { + netatoms[i] = r->atom; + free(r); + } } } -static int ( *xerror )( Display *, XErrorEvent * ); -/** - * @param d The connection to the X server. - * @param ee The XErrorEvent - * - * X11 Error handler. - */ -static int display_oops ( Display *d, XErrorEvent *ee ) -{ - if ( ee->error_code == BadWindow || ( ee->request_code == X_GrabButton && ee->error_code == BadAccess ) - || ( ee->request_code == X_GrabKey && ee->error_code == BadAccess ) ) { - return 0; - } - - fprintf ( stderr, "error: request code=%d, error code=%d\n", ee->request_code, ee->error_code ); - return xerror ( d, ee ); -} -void x11_setup ( Display *display, xkb_stuff *xkb ) +void x11_setup ( xcb_connection_t *xcb_connection, xkb_stuff *xkb ) { - // Set error handle - XSync ( display, False ); - xerror = XSetErrorHandler ( display_oops ); - XSync ( display, False ); - // determine numlock mask so we can bind on keys with and without it x11_figure_out_masks ( xkb ); - x11_create_frequently_used_atoms ( display ); + x11_create_frequently_used_atoms ( xcb_connection ); } void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen ) |