From 4c661c39326d815318cabea213a405fb31faec96 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Sat, 27 Feb 2016 22:55:47 +0100 Subject: [PATCH] Move most of window modi to xcb --- include/helper.h | 2 +- include/x11-helper.h | 4 -- source/dialogs/window.c | 100 ++++++++++++++++++---------------------- source/helper.c | 2 +- source/i3-support.c | 2 +- source/rofi.c | 2 +- source/x11-helper.c | 16 ------- 7 files changed, 48 insertions(+), 80 deletions(-) diff --git a/include/helper.h b/include/helper.h index 0d47762e..6caf2ed2 100644 --- a/include/helper.h +++ b/include/helper.h @@ -137,7 +137,7 @@ void remove_pid_file ( int fd ); * * This functions exits the program with 1 when it finds an invalid configuration. */ -int config_sanity_check ( Display *display ); +int config_sanity_check ( xcb_connection_t *xcb_connection); /** * @param arg string to parse. diff --git a/include/x11-helper.h b/include/x11-helper.h index 6e4b9363..944a7dfa 100644 --- a/include/x11-helper.h +++ b/include/x11-helper.h @@ -72,10 +72,6 @@ typedef struct void monitor_active ( xcb_connection_t *xcb_connection, workarea *mon ); -int window_send_message ( Display *display, Window target, Window subject, - Atom atom, unsigned long protocol, - unsigned long mask, Time time ); - // find the dimensions of the monitor displaying point x,y void monitor_dimensions ( xcb_connection_t *xcb_connection, xcb_screen_t *screen, int x, int y, workarea *mon ); // Find the dimensions of the monitor specified by user. diff --git a/source/dialogs/window.c b/source/dialogs/window.c index 08dd4a8e..e17c8a95 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -64,16 +64,16 @@ extern int xcb_screen_nbr; // a manageable window typedef struct { - Window window, trans; - XWindowAttributes xattr; + xcb_window_t window; + xcb_get_window_attributes_reply_t xattr; char title[CLIENTTITLE]; char class[CLIENTCLASS]; char name[CLIENTNAME]; char role[CLIENTROLE]; int states; - Atom state[CLIENTSTATE]; + xcb_atom_t state[CLIENTSTATE]; int window_types; - Atom window_type[CLIENTWINDOWTYPE]; + xcb_atom_t window_type[CLIENTWINDOWTYPE]; workarea monitor; int active; int demands; @@ -210,19 +210,17 @@ static void x11_cache_free ( void ) * * @returns a XWindowAttributes */ -static XWindowAttributes* window_get_attributes ( Display *display, Window w ) +static xcb_get_window_attributes_reply_t * window_get_attributes ( xcb_connection_t *xcb_connection, xcb_window_t w ) { int idx = winlist_find ( cache_xattr, w ); if ( idx < 0 ) { - XWindowAttributes *cattr = g_malloc ( sizeof ( XWindowAttributes ) ); - - if ( XGetWindowAttributes ( display, w, cattr ) ) { - winlist_append ( cache_xattr, w, cattr ); - return cattr; + xcb_get_window_attributes_cookie_t c = xcb_get_window_attributes(xcb_connection, w); + xcb_get_window_attributes_reply_t *r = xcb_get_window_attributes_reply ( xcb_connection, c, NULL); + if ( r ) { + winlist_append ( cache_xattr, w, r); + return r; } - - g_free ( cattr ); return NULL; } @@ -250,7 +248,7 @@ static int client_has_window_type ( client *c, Atom type ) return 0; } -static client* window_client ( Display *display, Window win ) +static client* window_client ( Display *display, xcb_window_t win ) { if ( win == None ) { return NULL; @@ -263,18 +261,17 @@ static client* window_client ( Display *display, Window win ) } // if this fails, we're up that creek - XWindowAttributes *attr = window_get_attributes ( display, win ); + xcb_get_window_attributes_reply_t *attr = window_get_attributes ( xcb_connection, win ); if ( !attr ) { return NULL; } - client *c = g_malloc0 ( sizeof ( client ) ); c->window = win; // copy xattr so we don't have to care when stuff is freed - memmove ( &c->xattr, attr, sizeof ( XWindowAttributes ) ); - XGetTransientForHint ( display, win, &c->trans ); + memmove ( &c->xattr, attr, sizeof ( xcb_get_window_attributes_reply_t ) ); + xcb_get_property_cookie_t cky = xcb_ewmh_get_wm_state(&xcb_ewmh, win); xcb_ewmh_get_atoms_reply_t states; @@ -289,7 +286,7 @@ static client* window_client ( Display *display, Window win ) } char *name; - if ( ( name = window_get_text_prop ( display, c->window, netatoms[_NET_WM_NAME] ) ) && name ) { + if ( ( name = window_get_text_prop ( display, c->window, xcb_ewmh._NET_WM_NAME ) ) && name ) { snprintf ( c->title, CLIENTTITLE, "%s", name ); g_free ( name ); } @@ -320,7 +317,7 @@ static client* window_client ( Display *display, Window win ) XFree ( wh ); } - monitor_dimensions ( xcb_connection, xcb_screen, c->xattr.x, c->xattr.y, &c->monitor ); +// monitor_dimensions ( xcb_connection, xcb_screen, c->xattr.x, c->xattr.y, &c->monitor ); winlist_append ( cache_client, c->window, c ); return c; } @@ -390,23 +387,18 @@ static unsigned int window_mode_get_num_entries ( const Mode *sw ) static void _window_mode_load_data ( Mode *sw, unsigned int cd ) { ModeModePrivateData *pd = (ModeModePrivateData *) mode_get_private_data ( sw ); - Screen *screen = DefaultScreenOfDisplay ( display ); - Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); // find window list - Atom type; int nwins = 0; - Window wins[100]; - int count = 0; - Window curr_win_id = 0; + xcb_window_t wins[100]; + xcb_window_t curr_win_id; // Create cache x11_cache_create (); // Check for i3 pd->config_i3_mode = i3_support_initialize ( display, xcb_connection ); - // Get the active window so we can highlight this. - if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) ) - && type == XA_WINDOW && count > 0 ) ) { + if ( !xcb_ewmh_get_active_window_reply ( &xcb_ewmh, + xcb_ewmh_get_active_window( &xcb_ewmh, xcb_screen_nbr), &curr_win_id, NULL )) { curr_win_id = 0; } @@ -417,14 +409,17 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) current_desktop = 0; } - unsigned int nw = 100 * sizeof ( Window ); - // First try Stacking order.. If this fails. - if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, nw ) - && type == XA_WINDOW ) ) { - // Try to get order by age. - if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST], &type, &nwins, wins, nw ) - && type == XA_WINDOW ) ) { - nwins = 0; + xcb_get_property_cookie_t cc = xcb_ewmh_get_client_list_stacking ( &xcb_ewmh, 0); + xcb_ewmh_get_windows_reply_t clients; + if ( xcb_ewmh_get_client_list_stacking_reply ( &xcb_ewmh, cc, &clients, NULL)){ + nwins = MIN ( 100, clients.windows_len); + memcpy(wins, clients.windows, nwins*sizeof(xcb_window_t) ); + } + else { + cc = xcb_ewmh_get_client_list ( &xcb_ewmh, xcb_screen_nbr); + if ( xcb_ewmh_get_client_list_reply ( &xcb_ewmh, cc, &clients, NULL)) { + nwins = MIN ( 100, clients.windows_len); + memcpy(wins, clients.windows, nwins*sizeof(xcb_window_t) ); } } if ( nwins > 0 ) { @@ -438,17 +433,16 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) // calc widths of fields for ( i = nwins - 1; i > -1; i-- ) { - client *c; - - if ( ( c = window_client ( display, wins[i] ) ) + client *c = window_client ( display, wins[i] ); + if ( ( c != NULL ) && !c->xattr.override_redirect - && !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DOCK] ) - && !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DESKTOP] ) - && !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_PAGER] ) - && !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_TASKBAR] ) ) { + && !client_has_window_type ( c, xcb_ewmh._NET_WM_WINDOW_TYPE_DOCK ) + && !client_has_window_type ( c, xcb_ewmh._NET_WM_WINDOW_TYPE_DESKTOP ) + && !client_has_state ( c, xcb_ewmh._NET_WM_STATE_SKIP_PAGER ) + && !client_has_state ( c, xcb_ewmh._NET_WM_STATE_SKIP_TASKBAR ) ) { classfield = MAX ( classfield, strlen ( c->class ) ); - if ( client_has_state ( c, netatoms[_NET_WM_STATE_DEMANDS_ATTENTION] ) ) { + if ( client_has_state ( c, xcb_ewmh._NET_WM_STATE_DEMANDS_ATTENTION ) ) { c->demands = TRUE; } if ( ( c->hint_flags & XUrgencyHint ) == XUrgencyHint ) { @@ -496,10 +490,10 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) cookie = xcb_get_property(xcb_connection, 0, c->window, xcb_ewmh._NET_WM_DESKTOP, XCB_GET_PROPERTY, 0, sizeof(unsigned int)); r = xcb_get_property_reply(xcb_connection, cookie, NULL); - if ( r->type == XCB_ATOM_INTEGER){ + if ( r&& r->type == XCB_ATOM_INTEGER){ wmdesktop = *((int *)xcb_get_property_value(r)); } - if ( r->type != XCB_ATOM_INTEGER) { + if ( r&&r->type != XCB_ATOM_INTEGER) { // Assume the client is on all desktops. wmdesktop = 0xFFFFFFFF; } @@ -563,16 +557,10 @@ static ModeMode window_mode_result ( Mode *sw, int mretv, G_GNUC_UNUSED char **i i3_support_focus_window ( rmpd->ids->array[selected_line] ); } else{ - Screen *screen = DefaultScreenOfDisplay ( display ); - Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); - // Change to the desktop of the selected window/client. - // TODO: get rid of strtol - window_send_message ( display, root, root, netatoms[_NET_CURRENT_DESKTOP], strtol ( rmpd->cmd_list[selected_line], NULL, 10 ), - SubstructureNotifyMask | SubstructureRedirectMask, 0 ); - XSync ( display, False ); - - window_send_message ( display, root, rmpd->ids->array[selected_line], netatoms[_NET_ACTIVE_WINDOW], 2, // 2 = pager - SubstructureNotifyMask | SubstructureRedirectMask, 0 ); + xcb_ewmh_request_change_active_window ( &xcb_ewmh, xcb_screen_nbr, rmpd->ids->array[selected_line], + XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER , + XCB_CURRENT_TIME, None); + xcb_flush(xcb_connection); } } return retv; diff --git a/source/helper.c b/source/helper.c index 76036daf..dcce57ce 100644 --- a/source/helper.c +++ b/source/helper.c @@ -511,7 +511,7 @@ void remove_pid_file ( int fd ) * * This functions exits the program with 1 when it finds an invalid configuration. */ -int config_sanity_check ( Display *display ) +int config_sanity_check ( xcb_connection_t* xcb_connection) { // If alternative row is not set, copy the normal background color. // Do this at the beginning as we might use it in the error dialog. diff --git a/source/i3-support.c b/source/i3-support.c index c3a10594..4ed23669 100644 --- a/source/i3-support.c +++ b/source/i3-support.c @@ -141,7 +141,7 @@ void i3_support_free_internals ( void ) #else -void i3_support_focus_window ( Window id ) +void i3_support_focus_window ( G_GNUC_UNUSED Window id ) { fprintf ( stderr, "Trying to control i3, when i3 support is not enabled.\n" ); abort (); diff --git a/source/rofi.c b/source/rofi.c index ace30aab..aa38ecf5 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -520,7 +520,7 @@ static gboolean startup ( G_GNUC_UNUSED gpointer data ) char *msg = NULL; // // Sanity check - if ( config_sanity_check ( display ) ) { + if ( config_sanity_check ( xcb_connection) ) { return G_SOURCE_REMOVE; } TICK_N ( "Config sanity check" ); diff --git a/source/x11-helper.c b/source/x11-helper.c index c4f63a79..bad7fec6 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -367,22 +367,6 @@ void monitor_active ( xcb_connection_t *xcb_connection, workarea *mon ) monitor_dimensions ( xcb_connection, xcb_screen, 0, 0, mon ); } -int window_send_message ( Display *display, Window trg, Window subject, Atom atom, unsigned long protocol, unsigned long mask, Time time ) -{ - XEvent e; - memset ( &e, 0, sizeof ( XEvent ) ); - e.xclient.type = ClientMessage; - e.xclient.message_type = atom; - e.xclient.window = subject; - e.xclient.data.l[0] = protocol; - e.xclient.data.l[1] = time; - e.xclient.send_event = True; - e.xclient.format = 32; - int r = XSendEvent ( display, trg, False, mask, &e ) ? 1 : 0; - XFlush ( display ); - return r; -} - int take_keyboard ( Display *display, Window w ) { for ( int i = 0; i < 500; i++ ) {