Move most of window modi to xcb

This commit is contained in:
Dave Davenport 2016-02-27 22:55:47 +01:00
parent bb2f0d8b83
commit 4c661c3932
7 changed files with 48 additions and 80 deletions

View File

@ -137,7 +137,7 @@ void remove_pid_file ( int fd );
* *
* This functions exits the program with 1 when it finds an invalid configuration. * 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. * @param arg string to parse.

View File

@ -72,10 +72,6 @@ typedef struct
void monitor_active ( xcb_connection_t *xcb_connection, workarea *mon ); 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 // 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 ); 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. // Find the dimensions of the monitor specified by user.

View File

@ -64,16 +64,16 @@ extern int xcb_screen_nbr;
// a manageable window // a manageable window
typedef struct typedef struct
{ {
Window window, trans; xcb_window_t window;
XWindowAttributes xattr; xcb_get_window_attributes_reply_t xattr;
char title[CLIENTTITLE]; char title[CLIENTTITLE];
char class[CLIENTCLASS]; char class[CLIENTCLASS];
char name[CLIENTNAME]; char name[CLIENTNAME];
char role[CLIENTROLE]; char role[CLIENTROLE];
int states; int states;
Atom state[CLIENTSTATE]; xcb_atom_t state[CLIENTSTATE];
int window_types; int window_types;
Atom window_type[CLIENTWINDOWTYPE]; xcb_atom_t window_type[CLIENTWINDOWTYPE];
workarea monitor; workarea monitor;
int active; int active;
int demands; int demands;
@ -210,19 +210,17 @@ static void x11_cache_free ( void )
* *
* @returns a XWindowAttributes * @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 ); int idx = winlist_find ( cache_xattr, w );
if ( idx < 0 ) { if ( idx < 0 ) {
XWindowAttributes *cattr = g_malloc ( sizeof ( XWindowAttributes ) ); 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 ( XGetWindowAttributes ( display, w, cattr ) ) { if ( r ) {
winlist_append ( cache_xattr, w, cattr ); winlist_append ( cache_xattr, w, r);
return cattr; return r;
} }
g_free ( cattr );
return NULL; return NULL;
} }
@ -250,7 +248,7 @@ static int client_has_window_type ( client *c, Atom type )
return 0; return 0;
} }
static client* window_client ( Display *display, Window win ) static client* window_client ( Display *display, xcb_window_t win )
{ {
if ( win == None ) { if ( win == None ) {
return NULL; return NULL;
@ -263,18 +261,17 @@ static client* window_client ( Display *display, Window win )
} }
// if this fails, we're up that creek // 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 ) { if ( !attr ) {
return NULL; return NULL;
} }
client *c = g_malloc0 ( sizeof ( client ) ); client *c = g_malloc0 ( sizeof ( client ) );
c->window = win; c->window = win;
// copy xattr so we don't have to care when stuff is freed // copy xattr so we don't have to care when stuff is freed
memmove ( &c->xattr, attr, sizeof ( XWindowAttributes ) ); memmove ( &c->xattr, attr, sizeof ( xcb_get_window_attributes_reply_t ) );
XGetTransientForHint ( display, win, &c->trans );
xcb_get_property_cookie_t cky = xcb_ewmh_get_wm_state(&xcb_ewmh, win); xcb_get_property_cookie_t cky = xcb_ewmh_get_wm_state(&xcb_ewmh, win);
xcb_ewmh_get_atoms_reply_t states; xcb_ewmh_get_atoms_reply_t states;
@ -289,7 +286,7 @@ static client* window_client ( Display *display, Window win )
} }
char *name; 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 ); snprintf ( c->title, CLIENTTITLE, "%s", name );
g_free ( name ); g_free ( name );
} }
@ -320,7 +317,7 @@ static client* window_client ( Display *display, Window win )
XFree ( wh ); 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 ); winlist_append ( cache_client, c->window, c );
return 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 ) static void _window_mode_load_data ( Mode *sw, unsigned int cd )
{ {
ModeModePrivateData *pd = (ModeModePrivateData *) mode_get_private_data ( sw ); ModeModePrivateData *pd = (ModeModePrivateData *) mode_get_private_data ( sw );
Screen *screen = DefaultScreenOfDisplay ( display );
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
// find window list // find window list
Atom type;
int nwins = 0; int nwins = 0;
Window wins[100]; xcb_window_t wins[100];
int count = 0; xcb_window_t curr_win_id;
Window curr_win_id = 0;
// Create cache // Create cache
x11_cache_create (); x11_cache_create ();
// Check for i3 // Check for i3
pd->config_i3_mode = i3_support_initialize ( display, xcb_connection ); pd->config_i3_mode = i3_support_initialize ( display, xcb_connection );
// Get the active window so we can highlight this. if ( !xcb_ewmh_get_active_window_reply ( &xcb_ewmh,
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) ) xcb_ewmh_get_active_window( &xcb_ewmh, xcb_screen_nbr), &curr_win_id, NULL )) {
&& type == XA_WINDOW && count > 0 ) ) {
curr_win_id = 0; curr_win_id = 0;
} }
@ -417,14 +409,17 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd )
current_desktop = 0; current_desktop = 0;
} }
unsigned int nw = 100 * sizeof ( Window ); xcb_get_property_cookie_t cc = xcb_ewmh_get_client_list_stacking ( &xcb_ewmh, 0);
// First try Stacking order.. If this fails. xcb_ewmh_get_windows_reply_t clients;
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, nw ) if ( xcb_ewmh_get_client_list_stacking_reply ( &xcb_ewmh, cc, &clients, NULL)){
&& type == XA_WINDOW ) ) { nwins = MIN ( 100, clients.windows_len);
// Try to get order by age. memcpy(wins, clients.windows, nwins*sizeof(xcb_window_t) );
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST], &type, &nwins, wins, nw ) }
&& type == XA_WINDOW ) ) { else {
nwins = 0; 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 ) { if ( nwins > 0 ) {
@ -438,17 +433,16 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd )
// calc widths of fields // calc widths of fields
for ( i = nwins - 1; i > -1; i-- ) { for ( i = nwins - 1; i > -1; i-- ) {
client *c; client *c = window_client ( display, wins[i] );
if ( ( c != NULL )
if ( ( c = window_client ( display, wins[i] ) )
&& !c->xattr.override_redirect && !c->xattr.override_redirect
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DOCK] ) && !client_has_window_type ( c, xcb_ewmh._NET_WM_WINDOW_TYPE_DOCK )
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DESKTOP] ) && !client_has_window_type ( c, xcb_ewmh._NET_WM_WINDOW_TYPE_DESKTOP )
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_PAGER] ) && !client_has_state ( c, xcb_ewmh._NET_WM_STATE_SKIP_PAGER )
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_TASKBAR] ) ) { && !client_has_state ( c, xcb_ewmh._NET_WM_STATE_SKIP_TASKBAR ) ) {
classfield = MAX ( classfield, strlen ( c->class ) ); 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; c->demands = TRUE;
} }
if ( ( c->hint_flags & XUrgencyHint ) == XUrgencyHint ) { 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)); 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); 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)); 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. // Assume the client is on all desktops.
wmdesktop = 0xFFFFFFFF; 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] ); i3_support_focus_window ( rmpd->ids->array[selected_line] );
} }
else{ else{
Screen *screen = DefaultScreenOfDisplay ( display ); xcb_ewmh_request_change_active_window ( &xcb_ewmh, xcb_screen_nbr, rmpd->ids->array[selected_line],
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER ,
// Change to the desktop of the selected window/client. XCB_CURRENT_TIME, None);
// TODO: get rid of strtol xcb_flush(xcb_connection);
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 );
} }
} }
return retv; return retv;

View File

@ -511,7 +511,7 @@ void remove_pid_file ( int fd )
* *
* This functions exits the program with 1 when it finds an invalid configuration. * 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. // 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. // Do this at the beginning as we might use it in the error dialog.

View File

@ -141,7 +141,7 @@ void i3_support_free_internals ( void )
#else #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" ); fprintf ( stderr, "Trying to control i3, when i3 support is not enabled.\n" );
abort (); abort ();

View File

@ -520,7 +520,7 @@ static gboolean startup ( G_GNUC_UNUSED gpointer data )
char *msg = NULL; char *msg = NULL;
// //
// Sanity check // Sanity check
if ( config_sanity_check ( display ) ) { if ( config_sanity_check ( xcb_connection) ) {
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
TICK_N ( "Config sanity check" ); TICK_N ( "Config sanity check" );

View File

@ -367,22 +367,6 @@ void monitor_active ( xcb_connection_t *xcb_connection, workarea *mon )
monitor_dimensions ( xcb_connection, xcb_screen, 0, 0, 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 ) int take_keyboard ( Display *display, Window w )
{ {
for ( int i = 0; i < 500; i++ ) { for ( int i = 0; i < 500; i++ ) {