mirror of https://github.com/davatorium/rofi.git
Move most of window modi to xcb
This commit is contained in:
parent
bb2f0d8b83
commit
4c661c3932
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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" );
|
||||||
|
|
|
@ -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++ ) {
|
||||||
|
|
Loading…
Reference in New Issue