summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-02-28 00:09:05 +0100
committerDave Davenport <qball@gmpclient.org>2016-02-28 00:09:05 +0100
commitd813d03a5fa16d187e446dd565cc4a6073d5ba68 (patch)
tree301c355ce2378a06ecc3cfeb9c49c500804154d8 /source
parent4c661c39326d815318cabea213a405fb31faec96 (diff)
Convert more stuff to xcb, keyboard grab, cleanup
Diffstat (limited to 'source')
-rw-r--r--source/dialogs/window.c47
-rw-r--r--source/i3-support.c14
-rw-r--r--source/rofi.c4
-rw-r--r--source/view.c43
-rw-r--r--source/x11-helper.c137
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 )