30 #define G_LOG_DOMAIN "X11Helper"
40 #include <cairo-xcb.h>
43 #include <xcb/xcb_aux.h>
44 #include <xcb/randr.h>
45 #include <xcb/xinerama.h>
46 #include <xcb/xcb_ewmh.h>
47 #include <xcb/xproto.h>
49 #include <xkbcommon/xkbcommon.h>
50 #include <xkbcommon/xkbcommon-x11.h>
52 #define SN_API_NOT_YET_FROZEN
54 #define sn_launcher_context_set_application_id sn_launcher_set_application_id
67 #define RANDR_PREF_MAJOR_VERSION 1
69 #define RANDR_PREF_MINOR_VERSION 5
72 #define INTERSECT( x, y, x1, y1, w1, h1 ) ( ( ( ( x ) >= ( x1 ) ) && ( ( x ) < ( x1 + w1 ) ) ) && ( ( ( y ) >= ( y1 ) ) && ( ( y ) < ( y1 + h1 ) ) ) )
93 xcb_colormap_t
map = XCB_COLORMAP_NONE;
103 xcb_depth_iterator_t d;
104 d = xcb_screen_allowed_depths_iterator ( s );
105 for (; d.rem; xcb_depth_next ( &d ) ) {
106 xcb_visualtype_iterator_t v = xcb_depth_visuals_iterator ( d.data );
107 for (; v.rem; xcb_visualtype_next ( &v ) ) {
108 if ( v.data->visual_id ==
visual ) {
118 xcb_get_geometry_cookie_t cookie;
119 xcb_get_geometry_reply_t *reply;
122 reply = xcb_get_geometry_reply (
xcb->
connection, cookie, NULL );
123 if ( reply == NULL ) {
127 xcb_get_window_attributes_cookie_t attributesCookie = xcb_get_window_attributes (
xcb->
connection, window );
128 xcb_get_window_attributes_reply_t *attributes = xcb_get_window_attributes_reply (
xcb->
connection,
131 if ( attributes == NULL || ( attributes->map_state != XCB_MAP_STATE_VIEWABLE ) ) {
142 cairo_surface_t *t = cairo_xcb_surface_create (
xcb->
connection, window, vt, reply->width, reply->height );
144 if ( cairo_surface_status ( t ) != CAIRO_STATUS_SUCCESS ) {
145 cairo_surface_destroy ( t );
151 int max = MAX ( reply->width, reply->height );
152 double scale = (double) size / max;
154 cairo_surface_t *s2 = cairo_surface_create_similar_image ( t, CAIRO_FORMAT_ARGB32, reply->width * scale, reply->height * scale );
157 if ( cairo_surface_status ( s2 ) != CAIRO_STATUS_SUCCESS ) {
158 cairo_surface_destroy ( t );
162 cairo_t *d = cairo_create ( s2 );
163 cairo_scale ( d, scale, scale );
164 cairo_set_source_surface ( d, t, 0, 0 );
168 cairo_surface_destroy ( t );
186 xcb_get_property_cookie_t cookie;
187 xcb_get_property_reply_t *reply;
188 xcb_pixmap_t rootpixmap = XCB_NONE;
190 cookie = xcb_get_property ( c,
198 reply = xcb_get_property_reply ( c, cookie, NULL );
201 if ( xcb_get_property_value_length ( reply ) ==
sizeof ( xcb_pixmap_t ) ) {
202 memcpy ( &rootpixmap, xcb_get_property_value ( reply ),
sizeof ( xcb_pixmap_t ) );
213 if ( pm == XCB_NONE ) {
224 xcb_get_property_cookie_t c = xcb_get_property (
xcb->
connection, 0, w, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX );
225 xcb_get_property_reply_t *r = xcb_get_property_reply (
xcb->
connection, c, NULL );
227 if ( xcb_get_property_value_length ( r ) > 0 ) {
229 if ( r->type ==
netatoms[UTF8_STRING] ) {
230 str = g_strndup ( xcb_get_property_value ( r ), xcb_get_property_value_length ( r ) );
232 else if ( r->type ==
netatoms[STRING] ) {
236 str = g_strdup (
"Invalid encoding." );
249 xcb_change_property (
xcb->
connection, XCB_PROP_MODE_REPLACE, w, prop, XCB_ATOM_ATOM, 32,
count, atoms );
279 xcb_randr_get_output_info_reply_t *op_reply;
280 xcb_randr_get_crtc_info_reply_t *crtc_reply;
281 xcb_randr_get_output_info_cookie_t it = xcb_randr_get_output_info (
xcb->
connection, out, XCB_CURRENT_TIME );
282 op_reply = xcb_randr_get_output_info_reply (
xcb->
connection, it, NULL );
283 if ( op_reply->crtc == XCB_NONE ) {
287 xcb_randr_get_crtc_info_cookie_t ct = xcb_randr_get_crtc_info (
xcb->
connection, op_reply->crtc, XCB_CURRENT_TIME );
288 crtc_reply = xcb_randr_get_crtc_info_reply (
xcb->
connection, ct, NULL );
294 retv->
x = crtc_reply->x;
295 retv->
y = crtc_reply->y;
296 retv->
w = crtc_reply->width;
297 retv->
h = crtc_reply->height;
299 retv->
mw = op_reply->mm_width;
300 retv->
mh = op_reply->mm_height;
302 char *tname = (
char *) xcb_randr_get_output_info_name ( op_reply );
303 int tname_len = xcb_randr_get_output_info_name_length ( op_reply );
305 retv->
name = g_malloc0 ( ( tname_len + 1 ) *
sizeof (
char ) );
306 memcpy ( retv->
name, tname, tname_len );
313 #if ( ( ( XCB_RANDR_MAJOR_VERSION >= RANDR_PREF_MAJOR_VERSION ) && ( XCB_RANDR_MINOR_VERSION >= RANDR_PREF_MINOR_VERSION ) ) \
314 || XCB_RANDR_MAJOR_VERSION > RANDR_PREF_MAJOR_VERSION )
322 static workarea *x11_get_monitor_from_randr_monitor ( xcb_randr_monitor_info_t *
mon )
325 xcb_generic_error_t *err;
327 xcb_get_atom_name_reply_t *atom_reply = xcb_get_atom_name_reply (
xcb->
connection, anc, &err );
329 g_warning (
"Could not get RandR monitor name: X11 error code %d\n", err->error_code );
341 retv->
w =
mon->width;
342 retv->
h =
mon->height;
345 retv->
mw =
mon->width_in_millimeters;
346 retv->
mh =
mon->height_in_millimeters;
349 retv->
name = g_strdup_printf (
"%.*s", xcb_get_atom_name_name_length ( atom_reply ), xcb_get_atom_name_name ( atom_reply ) );
360 xcb_query_extension_cookie_t randr_cookie = xcb_query_extension (
xcb->
connection, strlen ( extension ), extension );
362 xcb_query_extension_reply_t *randr_reply = xcb_query_extension_reply (
xcb->
connection, randr_cookie, NULL );
364 int present = randr_reply->present;
366 free ( randr_reply );
373 xcb_xinerama_query_screens_cookie_t screens_cookie = xcb_xinerama_query_screens_unchecked (
377 xcb_xinerama_query_screens_reply_t *screens_reply = xcb_xinerama_query_screens_reply (
383 xcb_xinerama_screen_info_iterator_t screens_iterator = xcb_xinerama_query_screens_screen_info_iterator (
387 for (; screens_iterator.rem > 0; xcb_xinerama_screen_info_next ( &screens_iterator ) ) {
390 w->
x = screens_iterator.data->x_org;
391 w->
y = screens_iterator.data->y_org;
392 w->
w = screens_iterator.data->width;
393 w->
h = screens_iterator.data->height;
404 free ( screens_reply );
416 g_debug (
"Query XINERAMA for monitor layout." );
420 g_debug (
"No RANDR or Xinerama available for getting monitor layout." );
423 g_debug (
"Query RANDR for monitor layout." );
425 g_debug (
"Randr XCB api version: %d.%d.", XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION );
426 #if ( ( ( XCB_RANDR_MAJOR_VERSION == RANDR_PREF_MAJOR_VERSION ) && ( XCB_RANDR_MINOR_VERSION >= RANDR_PREF_MINOR_VERSION ) ) \
427 || XCB_RANDR_MAJOR_VERSION > RANDR_PREF_MAJOR_VERSION )
428 xcb_randr_query_version_cookie_t cversion = xcb_randr_query_version (
xcb->
connection,
430 xcb_randr_query_version_reply_t *rversion = xcb_randr_query_version_reply (
xcb->
connection, cversion, NULL );
432 g_debug (
"Found randr version: %d.%d", rversion->major_version, rversion->minor_version );
437 xcb_randr_get_monitors_reply_t *mreply = xcb_randr_get_monitors_reply (
xcb->
connection, t, NULL );
439 xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator ( mreply );
440 while ( iter.rem > 0 ) {
441 workarea *w = x11_get_monitor_from_randr_monitor ( iter.data );
446 xcb_randr_monitor_info_next ( &iter );
457 xcb_randr_get_screen_resources_current_reply_t *res_reply;
458 xcb_randr_get_screen_resources_current_cookie_t src;
460 res_reply = xcb_randr_get_screen_resources_current_reply (
xcb->
connection, src, NULL );
464 int mon_num = xcb_randr_get_screen_resources_current_outputs_length ( res_reply );
465 xcb_randr_output_t *ops = xcb_randr_get_screen_resources_current_outputs ( res_reply );
468 xcb_randr_get_output_primary_cookie_t pc = xcb_randr_get_output_primary (
xcb->
connection,
xcb->
screen->root );
469 xcb_randr_get_output_primary_reply_t *pc_rep = xcb_randr_get_output_primary_reply (
xcb->
connection, pc, NULL );
471 for (
int i = mon_num - 1; i >= 0; i-- ) {
476 if ( pc_rep && pc_rep->output == ops[i] ) {
491 iter->monitor_id = index++;
497 int is_term = isatty ( fileno ( stdout ) );
498 printf (
"Monitor layout:\n" );
500 printf (
"%s ID%s: %d", ( is_term ) ?
color_bold :
"", is_term ?
color_reset :
"", iter->monitor_id );
501 if ( iter->primary ) {
502 printf (
" (primary)" );
506 printf (
"%s position%s: %d,%d\n", ( is_term ) ?
color_bold :
"", is_term ?
color_reset :
"", iter->x, iter->y );
507 printf (
"%s size%s: %d,%d\n", ( is_term ) ?
color_bold :
"", is_term ?
color_reset :
"", iter->w, iter->h );
508 if ( iter->mw > 0 && iter->mh > 0 ) {
509 printf (
"%s size%s: %dmm,%dmm dpi: %.0f,%.0f\n",
514 iter->w * 25.4 / (
double) iter->mw,
515 iter->h * 25.4 / (
double) iter->mh
524 if ( context == NULL ) {
534 if ( context->
binary != NULL ) {
537 if ( context->
icon != NULL ) {
538 sn_launcher_context_set_icon_name (
sncontext, context->
icon );
540 if ( context->
app_id != NULL ) {
543 if ( context->
wmclass != NULL ) {
547 xcb_get_property_cookie_t c;
548 unsigned int current_desktop = 0;
551 if ( xcb_ewmh_get_current_desktop_reply ( &
xcb->
ewmh, c, ¤t_desktop, NULL ) ) {
552 sn_launcher_context_set_workspace (
sncontext, current_desktop );
557 *child_setup = (GSpawnChildSetupFunc) sn_launcher_context_setup_child_process;
584 if (
INTERSECT ( x, y, iter->x, iter->y, iter->w, iter->h ) ) {
604 xcb_query_pointer_cookie_t c = xcb_query_pointer (
xcb->
connection, root );
605 xcb_query_pointer_reply_t *r = xcb_query_pointer_reply (
xcb->
connection, c, NULL );
618 xcb_get_geometry_cookie_t c = xcb_get_geometry (
xcb->
connection,
id );
619 xcb_get_geometry_reply_t *r = xcb_get_geometry_reply (
xcb->
connection, c, NULL );
621 xcb_translate_coordinates_cookie_t ct = xcb_translate_coordinates (
xcb->
connection,
id, root, r->x, r->y );
622 xcb_translate_coordinates_reply_t *t = xcb_translate_coordinates_reply (
xcb->
connection, ct, NULL );
627 mon->
x = t->dst_x - r->x;
628 mon->
y = t->dst_y - r->y;
642 xcb_window_t active_window;
643 xcb_get_property_cookie_t awc;
645 if ( !xcb_ewmh_get_active_window_reply ( &
xcb->
ewmh, awc, &active_window, NULL ) ) {
646 g_debug (
"Failed to get active window, falling back to mouse location (-5)." );
649 xcb_query_tree_cookie_t tree_cookie = xcb_query_tree (
xcb->
connection, active_window );
650 xcb_query_tree_reply_t *tree_reply = xcb_query_tree_reply (
xcb->
connection, tree_cookie, NULL );
652 g_debug (
"Failed to get parent window, falling back to mouse location (-5)." );
656 xcb_get_geometry_cookie_t c = xcb_get_geometry (
xcb->
connection, active_window );
657 xcb_get_geometry_reply_t *r = xcb_get_geometry_reply (
xcb->
connection, c, NULL );
659 g_debug (
"Failed to get geometry of active window, falling back to mouse location (-5)." );
663 xcb_translate_coordinates_cookie_t ct = xcb_translate_coordinates (
xcb->
connection, tree_reply->parent, r->root, r->x, r->y );
664 xcb_translate_coordinates_reply_t *t = xcb_translate_coordinates_reply (
xcb->
connection, ct, NULL );
666 if ( mon_id == -2 ) {
670 mon->
x = t->dst_x - r->x;
671 mon->
y = t->dst_y - r->y;
676 else if ( mon_id == -4 ) {
683 g_debug (
"Failed to get translate position of active window, falling back to mouse location (-5)." );
694 if ( mon_id == -3 ) {
703 else if ( mon_id == -1 ) {
705 unsigned int current_desktop = 0;
706 xcb_get_property_cookie_t gcdc;
708 if ( xcb_ewmh_get_current_desktop_reply ( &
xcb->
ewmh, gcdc, ¤t_desktop, NULL ) ) {
710 xcb_ewmh_get_desktop_viewport_reply_t vp;
711 if ( xcb_ewmh_get_desktop_viewport_reply ( &
xcb->
ewmh, c, &vp, NULL ) ) {
712 if ( current_desktop < vp.desktop_viewport_len ) {
714 vp.desktop_viewport[current_desktop].y,
mon );
715 xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp );
719 g_debug (
"Viewport does not exist for current desktop: %d, falling back to mouse location (-5)", current_desktop );
721 xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp );
724 g_debug (
"Failed to get viewport for current desktop: %d, falling back to mouse location (-5).", current_desktop );
728 g_debug (
"Failed to get current desktop, falling back to mouse location (-5)." );
731 else if ( mon_id == -2 || mon_id == -4 ) {
737 else if ( mon_id == -5 ) {
745 g_debug (
"Failed to find monitor, fall back to monitor showing mouse." );
763 if ( iter->primary ) {
771 xcb_drawable_t win = g_ascii_strtoll (
config.
monitor + 4, &end, 0 );
787 g_warning (
"Failed to find selected monitor." );
807 if ( xse->property == XCB_ATOM_NONE ) {
808 g_warning (
"Failed to convert selection" );
810 else if ( xse->property ==
xcb->
ewmh.UTF8_STRING ) {
812 if ( text != NULL && text[0] !=
'\0' ) {
813 unsigned int dl = strlen ( text );
815 for (
unsigned int i = 0; i < dl; i++ ) {
816 if ( text[i] ==
'\n' ) {
825 g_warning (
"Failed" );
831 switch ( x11_button )
834 *button = NK_BINDINGS_MOUSE_BUTTON_PRIMARY;
837 *button = NK_BINDINGS_MOUSE_BUTTON_SECONDARY;
840 *button = NK_BINDINGS_MOUSE_BUTTON_MIDDLE;
843 *button = NK_BINDINGS_MOUSE_BUTTON_BACK;
846 *button = NK_BINDINGS_MOUSE_BUTTON_FORWARD;
854 *button = NK_BINDINGS_MOUSE_BUTTON_EXTRA + x11_button;
862 switch ( x11_button )
868 *axis = NK_BINDINGS_SCROLL_AXIS_VERTICAL;
874 *axis = NK_BINDINGS_SCROLL_AXIS_HORIZONTAL;
888 if ( state == NULL ) {
892 switch ( event->response_type & ~0x80 )
897 case XCB_CONFIGURE_NOTIFY:
899 xcb_configure_notify_event_t *xce = (xcb_configure_notify_event_t *) event;
903 case XCB_MOTION_NOTIFY:
908 xcb_motion_notify_event_t *xme = (xcb_motion_notify_event_t *) event;
912 case XCB_BUTTON_PRESS:
914 xcb_button_press_event_t *bpe = (xcb_button_press_event_t *) event;
915 NkBindingsMouseButton button;
916 NkBindingsScrollAxis axis;
922 nk_bindings_seat_handle_button (
xcb->
bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_PRESS, bpe->time );
929 case XCB_BUTTON_RELEASE:
931 xcb_button_release_event_t *bre = (xcb_button_release_event_t *) event;
932 NkBindingsMouseButton button;
936 nk_bindings_seat_handle_button (
xcb->
bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_RELEASE, bre->time );
947 case XCB_SELECTION_NOTIFY:
950 case XCB_KEYMAP_NOTIFY:
952 xcb_keymap_notify_event_t *kne = (xcb_keymap_notify_event_t *) event;
953 for ( gint32 by = 0; by < 31; ++by ) {
954 for ( gint8 bi = 0; bi < 7; ++bi ) {
955 if ( kne->keys[by] & ( 1 << bi ) ) {
957 nk_bindings_seat_handle_key (
xcb->
bindings_seat, NULL, ( 8 * by + bi ) + 8, NK_BINDINGS_KEY_STATE_PRESSED );
965 xcb_key_press_event_t *xkpe = (xcb_key_press_event_t *) event;
969 text = nk_bindings_seat_handle_key_with_modmask (
xcb->
bindings_seat, NULL, xkpe->state, xkpe->detail, NK_BINDINGS_KEY_STATE_PRESS );
970 if ( text != NULL ) {
975 case XCB_KEY_RELEASE:
977 xcb_key_release_event_t *xkre = (xcb_key_release_event_t *) event;
979 nk_bindings_seat_handle_key (
xcb->
bindings_seat, NULL, xkre->detail, NK_BINDINGS_KEY_STATE_RELEASE );
993 g_warning (
"The XCB connection to X server had a fatal error: %d", status );
995 return G_SOURCE_REMOVE;
998 g_warning (
"main_loop_x11_event_handler: ev == NULL, status == %d", status );
999 return G_SOURCE_CONTINUE;
1002 uint8_t type = ev->response_type & ~0x80;
1006 case XCB_XKB_MAP_NOTIFY:
1011 xkb_keymap_unref ( keymap );
1012 xkb_state_unref ( state );
1015 case XCB_XKB_STATE_NOTIFY:
1017 xcb_xkb_state_notify_event_t *ksne = (xcb_xkb_state_notify_event_t *) ev;
1024 ksne->lockedGroup );
1029 return G_SOURCE_CONTINUE;
1035 return G_SOURCE_CONTINUE;
1043 g_warning (
"Connection has error" );
1044 exit ( EXIT_FAILURE );
1046 xcb_grab_pointer_cookie_t cc = xcb_grab_pointer (
xcb->
connection, 1, w, XCB_EVENT_MASK_BUTTON_RELEASE,
1047 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, w, XCB_NONE, XCB_CURRENT_TIME );
1048 xcb_grab_pointer_reply_t *r = xcb_grab_pointer_reply (
xcb->
connection, cc, NULL );
1050 if ( r->status == XCB_GRAB_STATUS_SUCCESS ) {
1056 if ( ( ++i ) > iters ) {
1059 struct timespec del = {
1063 nanosleep ( &del, NULL );
1073 g_warning (
"Connection has error" );
1074 exit ( EXIT_FAILURE );
1076 xcb_grab_keyboard_cookie_t cc = xcb_grab_keyboard (
xcb->
connection,
1077 1, w, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC,
1078 XCB_GRAB_MODE_ASYNC );
1079 xcb_grab_keyboard_reply_t *r = xcb_grab_keyboard_reply (
xcb->
connection, cc, NULL );
1081 if ( r->status == XCB_GRAB_STATUS_SUCCESS ) {
1087 if ( ( ++i ) > iters ) {
1090 struct timespec del = {
1094 nanosleep ( &del, NULL );
1110 static void error_trap_push ( G_GNUC_UNUSED SnDisplay *display, G_GNUC_UNUSED xcb_connection_t *xdisplay )
1115 static void error_trap_pop ( G_GNUC_UNUSED SnDisplay *display, xcb_connection_t *xdisplay )
1118 g_warning (
"Error trap underflow!" );
1119 exit ( EXIT_FAILURE );
1122 xcb_flush ( xdisplay );
1134 xcb_intern_atom_reply_t *r = xcb_intern_atom_reply (
xcb->
connection, cc, NULL );
1144 xcb_window_t wm_win = 0;
1145 xcb_get_property_cookie_t cc = xcb_ewmh_get_supporting_wm_check_unchecked ( &
xcb->
ewmh,
1148 if ( xcb_ewmh_get_supporting_wm_check_reply ( &
xcb->
ewmh, cc, &wm_win, NULL ) ) {
1149 xcb_ewmh_get_utf8_strings_reply_t wtitle;
1150 xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name_unchecked ( &(
xcb->
ewmh ), wm_win );
1151 if ( xcb_ewmh_get_wm_name_reply ( &(
xcb->
ewmh ), cookie, &wtitle, (
void *) 0 ) ) {
1152 if ( wtitle.strings_len > 0 ) {
1153 g_debug (
"Found window manager: %s", wtitle.strings );
1154 if ( g_strcmp0 ( wtitle.strings,
"i3" ) == 0 ) {
1158 xcb_ewmh_get_utf8_strings_reply_wipe ( &wtitle );
1167 char *display_str = (
char *) g_getenv (
"DISPLAY" );
1173 g_warning (
"Failed to open display: %s", display_str );
1178 TICK_N (
"Open Display" );
1185 xcb_generic_error_t *errors = NULL;
1186 xcb_ewmh_init_atoms_replies ( &
xcb->
ewmh, ac, &errors );
1188 g_warning (
"Failed to create EWMH atoms" );
1195 if ( xkb_x11_setup_xkb_extension (
xcb->
connection, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION,
1196 XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, NULL, NULL, &
xcb->
xkb.
first_event, NULL ) < 0 ) {
1197 g_warning (
"cannot setup XKB extension!" );
1206 ( XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
1207 XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
1208 XCB_XKB_EVENT_TYPE_STATE_NOTIFY ),
1210 required_nkn_details =
1211 ( XCB_XKB_NKN_DETAIL_KEYCODES ),
1213 required_map_parts =
1214 ( XCB_XKB_MAP_PART_KEY_TYPES |
1215 XCB_XKB_MAP_PART_KEY_SYMS |
1216 XCB_XKB_MAP_PART_MODIFIER_MAP |
1217 XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
1218 XCB_XKB_MAP_PART_KEY_ACTIONS |
1219 XCB_XKB_MAP_PART_VIRTUAL_MODS |
1220 XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP ),
1222 required_state_details =
1223 ( XCB_XKB_STATE_PART_MODIFIER_BASE |
1224 XCB_XKB_STATE_PART_MODIFIER_LATCH |
1225 XCB_XKB_STATE_PART_MODIFIER_LOCK |
1226 XCB_XKB_STATE_PART_GROUP_BASE |
1227 XCB_XKB_STATE_PART_GROUP_LATCH |
1228 XCB_XKB_STATE_PART_GROUP_LOCK ),
1231 static const xcb_xkb_select_events_details_t details = {
1232 .affectNewKeyboard = required_nkn_details,
1233 .newKeyboardDetails = required_nkn_details,
1234 .affectState = required_state_details,
1235 .stateDetails = required_state_details,
1246 if ( keymap == NULL ) {
1247 g_warning (
"Failed to get Keymap for current keyboard device." );
1251 if ( state == NULL ) {
1252 g_warning (
"Failed to get state object for current keyboard device." );
1257 xkb_state_unref ( state );
1258 xkb_keymap_unref ( keymap );
1264 g_warning (
"Connection has error" );
1271 g_warning (
"Connection has error" );
1279 g_warning (
"Connection has error" );
1288 xcb_depth_t *root_depth = NULL;
1289 xcb_depth_iterator_t depth_iter;
1290 for ( depth_iter = xcb_screen_allowed_depths_iterator (
xcb->
screen ); depth_iter.rem; xcb_depth_next ( &depth_iter ) ) {
1291 xcb_depth_t *d = depth_iter.data;
1293 xcb_visualtype_iterator_t visual_iter;
1294 for ( visual_iter = xcb_depth_visuals_iterator ( d ); visual_iter.rem; xcb_visualtype_next ( &visual_iter ) ) {
1295 xcb_visualtype_t *v = visual_iter.data;
1296 if ( ( v->bits_per_rgb_value == 8 ) && ( d->depth == 32 ) && ( v->_class == XCB_VISUAL_CLASS_TRUE_COLOR ) ) {
1300 if (
xcb->
screen->root_visual == v->visual_id ) {
1307 xcb_void_cookie_t c;
1308 xcb_generic_error_t *e;
1335 return G_SOURCE_REMOVE;
1338 return G_SOURCE_REMOVE;
1341 return G_SOURCE_CONTINUE;
1349 return G_SOURCE_REMOVE;
1352 return G_SOURCE_REMOVE;
1355 return G_SOURCE_CONTINUE;
1368 if (
find_arg (
"-normal-window" ) >= 0 ) {
1371 if (
find_arg (
"-no-lazy-grab" ) >= 0 ) {
1373 g_warning (
"Failed to grab keyboard, even after %d uS.", 500 * 1000 );
1377 g_warning (
"Failed to grab mouse pointer, even after %d uS.", 100 * 1000 );
1409 g_debug (
"Cleaning up XCB and XKB" );
1421 xcb_ewmh_connection_wipe ( &(
xcb->
ewmh ) );
1424 g_water_xcb_source_free (
xcb->
source );
1434 const uint32_t MWM_HINTS_DECORATIONS = ( 1 << 1 );
1440 uint32_t decorations;
1445 struct MotifWMHints hints;
1446 hints.flags = MWM_HINTS_DECORATIONS;
1447 hints.decorations = 0;
1448 hints.functions = 0;
1449 hints.inputMode = 0;
1452 xcb_atom_t ha =
netatoms[_MOTIF_WM_HINTS];
1453 xcb_change_property (
xcb->
connection, XCB_PROP_MODE_REPLACE, window, ha, ha, 32, 5, &hints );
char * rofi_latin_to_utf8_strdup(const char *input, gssize length)
int find_arg_str(const char *const key, char **val)
int find_arg(const char *const key)
RofiViewState * rofi_view_get_active(void)
void rofi_view_handle_mouse_motion(RofiViewState *state, gint x, gint y)
void rofi_view_handle_text(RofiViewState *state, char *text)
void rofi_view_temp_click_to_exit(RofiViewState *state, xcb_window_t target)
void rofi_view_temp_configure_notify(RofiViewState *state, xcb_configure_notify_event_t *xce)
void rofi_view_frame_callback(void)
void rofi_view_maybe_update(RofiViewState *state)
const gchar * description
xcb_connection_t * connection
SnLauncheeContext * sncontext
struct _workarea * monitors
xcb_timestamp_t last_timestamp
xcb_ewmh_connection_t ewmh
NkBindingsSeat * bindings_seat
struct _xcb_stuff::@6 xkb
gboolean display_late_setup(void)
static int take_pointer(xcb_window_t w, int iters)
int monitor_active(workarea *mon)
static void x11_build_monitor_layout_xinerama()
#define RANDR_PREF_MAJOR_VERSION
void display_early_cleanup(void)
static int x11_is_extension_present(const char *extension)
static gboolean lazy_grab_pointer(G_GNUC_UNUSED gpointer data)
cairo_surface_t * x11_helper_get_screenshot_surface(void)
void display_startup_notification(RofiHelperExecuteContext *context, GSpawnChildSetupFunc *child_setup, gpointer *user_data)
static void x11_build_monitor_layout()
void display_cleanup(void)
static xcb_pixmap_t get_root_pixmap(xcb_connection_t *c, xcb_screen_t *screen, xcb_atom_t atom)
static void release_pointer(void)
struct _xcb_stuff xcb_int
static int monitor_active_from_winid(xcb_drawable_t id, workarea *mon)
static void x11_create_visual_and_colormap(void)
static gboolean x11_button_to_nk_bindings_scroll(guint32 x11_button, NkBindingsScrollAxis *axis, gint32 *steps)
static void monitor_dimensions(int x, int y, workarea *mon)
static gboolean lazy_grab_keyboard(G_GNUC_UNUSED gpointer data)
static xcb_visualtype_t * lookup_visual(xcb_screen_t *s, xcb_visualid_t visual)
#define INTERSECT(x, y, x1, y1, w1, h1)
static void error_trap_pop(G_GNUC_UNUSED SnDisplay *display, xcb_connection_t *xdisplay)
cairo_surface_t * x11_helper_get_bg_surface(void)
unsigned int lazy_grab_retry_count_pt
static xcb_visualtype_t * root_visual
static void x11_create_frequently_used_atoms(void)
static int monitor_active_from_id_focused(int mon_id, workarea *mon)
static gboolean x11_button_to_nk_bindings_button(guint32 x11_button, NkBindingsMouseButton *button)
static void x11_monitor_free(workarea *m)
cairo_surface_t * x11_helper_get_screenshot_surface_window(xcb_window_t window, int size)
static void x11_helper_discover_window_manager(void)
static int monitor_get_dimension(int monitor_id, workarea *mon)
static int take_keyboard(xcb_window_t w, int iters)
xcb_window_t xcb_stuff_get_root_window(void)
unsigned int lazy_grab_retry_count_kb
static void rofi_view_paste(RofiViewState *state, xcb_selection_notify_event_t *xse)
void window_set_atom_prop(xcb_window_t w, xcb_atom_t prop, xcb_atom_t *atoms, int count)
const char * netatom_names[]
static int monitor_active_from_id(int mon_id, workarea *mon)
static void x11_monitors_free(void)
gboolean display_setup(GMainLoop *main_loop, NkBindings *bindings)
void display_dump_monitor_layout(void)
static void error_trap_push(G_GNUC_UNUSED SnDisplay *display, G_GNUC_UNUSED xcb_connection_t *xdisplay)
WindowManagerQuirk current_window_manager
static int pointer_get(xcb_window_t root, int *x, int *y)
#define RANDR_PREF_MINOR_VERSION
#define sn_launcher_context_set_application_id
static int error_trap_depth
static void release_keyboard(void)
char * window_get_text_prop(xcb_window_t w, xcb_atom_t atom)
static gboolean main_loop_x11_event_handler(xcb_generic_event_t *ev, G_GNUC_UNUSED gpointer user_data)
void x11_disable_decoration(xcb_window_t window)
static void main_loop_x11_event_handler_view(xcb_generic_event_t *event)
static workarea * x11_get_monitor_from_output(xcb_randr_output_t out)
xcb_atom_t netatoms[NUM_NETATOMS]
xcb_visualtype_t * visual
@ WM_PANGO_WORKSPACE_NAMES
@ WM_DO_NOT_CHANGE_CURRENT_DESKTOP