mirror of
https://github.com/davatorium/rofi.git
synced 2025-04-07 17:33:14 -04:00
Convert more stuff to xcb, keyboard grab, cleanup
This commit is contained in:
parent
4c661c3932
commit
d813d03a5f
8 changed files with 93 additions and 206 deletions
|
@ -83,7 +83,7 @@ dnl ---------------------------------------------------------------------
|
|||
dnl X11, Glib, Xinerama, Pango, Cairo, libstartup notification
|
||||
dnl ---------------------------------------------------------------------
|
||||
PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40])
|
||||
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11 xcb-ewmh xcb-xinerama])
|
||||
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11 xcb-ewmh xcb-xinerama xcb-icccm])
|
||||
PKG_CHECK_MODULES([x11], [x11 x11-xcb])
|
||||
PKG_CHECK_MODULES([pango], [pango pangocairo])
|
||||
PKG_CHECK_MODULES([cairo], [cairo cairo-xcb])
|
||||
|
|
|
@ -28,7 +28,7 @@ void i3_support_focus_window ( Window id );
|
|||
* @returns TRUE when i3 is running, FALSE when not.
|
||||
*/
|
||||
|
||||
int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection );
|
||||
int i3_support_initialize ( xcb_connection_t *xcb_connection );
|
||||
|
||||
/**
|
||||
* Cleanup.
|
||||
|
|
|
@ -11,13 +11,9 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
int window_get_prop ( Display *display, Window w, Atom prop,
|
||||
Atom *type, int *items,
|
||||
void *buffer, unsigned int bytes ) __attribute__ ( ( nonnull ( 4, 5 ) ) );
|
||||
|
||||
/**
|
||||
* @param display Connection to the X server.
|
||||
* @param w The Window to read property from.
|
||||
* @param w The xcb_window_t to read property from.
|
||||
* @param atom The property identifier
|
||||
*
|
||||
* Get text property defined by atom from window.
|
||||
|
@ -25,45 +21,25 @@ int window_get_prop ( Display *display, Window w, Atom prop,
|
|||
*
|
||||
* @returns a newly allocated string with the result or NULL
|
||||
*/
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
/**
|
||||
* Window info.
|
||||
* xcb_window_t info.
|
||||
*/
|
||||
#define ATOM_ENUM( x ) x
|
||||
#define ATOM_CHAR( x ) # x
|
||||
|
||||
// usable space on a monitor
|
||||
#define EWMH_ATOMS( X ) \
|
||||
X ( _NET_CLIENT_LIST_STACKING ), \
|
||||
X ( _NET_NUMBER_OF_DESKTOPS ), \
|
||||
X ( _NET_CURRENT_DESKTOP ), \
|
||||
X ( _NET_ACTIVE_WINDOW ), \
|
||||
X ( _NET_CLIENT_LIST ), \
|
||||
X ( _NET_WM_NAME ), \
|
||||
X ( _NET_WM_STATE ), \
|
||||
X ( _NET_WM_STATE_SKIP_TASKBAR ), \
|
||||
X ( _NET_WM_STATE_SKIP_PAGER ), \
|
||||
X ( _NET_WM_STATE_ABOVE ), \
|
||||
X ( _NET_WM_STATE_DEMANDS_ATTENTION ), \
|
||||
X ( _NET_WM_STATE_WITHDRAWN ), \
|
||||
X ( _NET_WM_WINDOW_TYPE ), \
|
||||
X ( _NET_WM_WINDOW_TYPE_DOCK ), \
|
||||
X ( _NET_WM_WINDOW_TYPE_DESKTOP ), \
|
||||
X ( _NET_WM_WINDOW_TYPE_NORMAL ), \
|
||||
X ( _NET_WM_STATE_FULLSCREEN ), \
|
||||
X ( _NET_WM_DESKTOP ), \
|
||||
X ( _NET_DESKTOP_VIEWPORT ), \
|
||||
X ( CLIPBOARD ), \
|
||||
X ( UTF8_STRING ), \
|
||||
X ( _NET_WM_WINDOW_OPACITY )
|
||||
X ( _NET_WM_WINDOW_OPACITY ), \
|
||||
X ( WM_WINDOW_ROLE)
|
||||
|
||||
enum { EWMH_ATOMS ( ATOM_ENUM ), NUM_NETATOMS };
|
||||
|
||||
extern const char *netatom_names[];
|
||||
extern Atom netatoms[NUM_NETATOMS];
|
||||
extern xcb_atom_t netatoms[NUM_NETATOMS];
|
||||
typedef struct
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
@ -83,17 +59,17 @@ int monitor_get_smallest_size ( xcb_connection_t *xcb_connection );
|
|||
*
|
||||
* Release keyboard.
|
||||
*/
|
||||
void release_keyboard ( Display *display );
|
||||
void release_keyboard ( xcb_connection_t *xcb_connection );
|
||||
|
||||
/**
|
||||
* @param display The display.
|
||||
* @param w Window we want to grab keyboard on.
|
||||
* @param w xcb_window_t we want to grab keyboard on.
|
||||
*
|
||||
* Grab keyboard and mouse.
|
||||
*
|
||||
* @return 1 when keyboard is grabbed, 0 not.
|
||||
*/
|
||||
int take_keyboard ( Display *display, Window w );
|
||||
int take_keyboard ( xcb_connection_t *xcb_connection, xcb_window_t w );
|
||||
|
||||
/**
|
||||
* @param mask The mask to canonilize
|
||||
|
@ -118,7 +94,7 @@ void x11_parse_key ( char *combo, unsigned int *mod, xkb_keysym_t *key );
|
|||
*
|
||||
* Set the opacity of the window and sub-windows.
|
||||
*/
|
||||
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 );
|
||||
|
||||
/**
|
||||
* Setup several items required.
|
||||
|
@ -126,7 +102,7 @@ void x11_set_window_opacity ( xcb_connection_t *xcb_connection, Window box, unsi
|
|||
* * Numlock detection
|
||||
* * Cache
|
||||
*/
|
||||
void x11_setup ( Display *display, xkb_stuff *xkb );
|
||||
void x11_setup ( xcb_connection_t *xcb_connection, xkb_stuff *xkb );
|
||||
|
||||
extern xcb_depth_t *depth;
|
||||
extern xcb_visualtype_t *visual;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 " );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if ( prop.value ) {
|
||||
XFree ( prop.value );
|
||||
}
|
||||
|
||||
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 )
|
||||
|
||||
void x11_setup ( xcb_connection_t *xcb_connection, xkb_stuff *xkb )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
// 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 )
|
||||
|
|
Loading…
Add table
Reference in a new issue