]> git.sur5r.net Git - i3/i3/blob - src/main.c
skip ConfigureNotify events with --force_xinerama
[i3/i3] / src / main.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * main.c: Initialization, main loop
8  *
9  */
10 #include "all.h"
11
12 #include <ev.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/un.h>
17 #include <sys/time.h>
18 #include <sys/resource.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <libgen.h>
22 #include "shmlog.h"
23
24 #ifdef I3_ASAN_ENABLED
25 #include <sanitizer/lsan_interface.h>
26 #endif
27
28 #include "sd-daemon.h"
29
30 /* The original value of RLIMIT_CORE when i3 was started. We need to restore
31  * this before starting any other process, since we set RLIMIT_CORE to
32  * RLIM_INFINITY for i3 debugging versions. */
33 struct rlimit original_rlimit_core;
34
35 /** The number of file descriptors passed via socket activation. */
36 int listen_fds;
37
38 /* We keep the xcb_check watcher around to be able to enable and disable it
39  * temporarily for drag_pointer(). */
40 static struct ev_check *xcb_check;
41
42 extern Con *focused;
43
44 char **start_argv;
45
46 xcb_connection_t *conn;
47 /* The screen (0 when you are using DISPLAY=:0) of the connection 'conn' */
48 int conn_screen;
49
50 /* Display handle for libstartup-notification */
51 SnDisplay *sndisplay;
52
53 /* The last timestamp we got from X11 (timestamps are included in some events
54  * and are used for some things, like determining a unique ID in startup
55  * notification). */
56 xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
57
58 xcb_screen_t *root_screen;
59 xcb_window_t root;
60
61 /* Color depth, visual id and colormap to use when creating windows and
62  * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
63  * otherwise the root window’s default (usually 24 bit TrueColor). */
64 uint8_t root_depth;
65 xcb_visualtype_t *visual_type;
66 xcb_colormap_t colormap;
67
68 struct ev_loop *main_loop;
69
70 xcb_key_symbols_t *keysyms;
71
72 /* Default shmlog size if not set by user. */
73 const int default_shmlog_size = 25 * 1024 * 1024;
74
75 /* The list of key bindings */
76 struct bindings_head *bindings;
77
78 /* The list of exec-lines */
79 struct autostarts_head autostarts = TAILQ_HEAD_INITIALIZER(autostarts);
80
81 /* The list of exec_always lines */
82 struct autostarts_always_head autostarts_always = TAILQ_HEAD_INITIALIZER(autostarts_always);
83
84 /* The list of assignments */
85 struct assignments_head assignments = TAILQ_HEAD_INITIALIZER(assignments);
86
87 /* The list of workspace assignments (which workspace should end up on which
88  * output) */
89 struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignments);
90
91 /* We hope that those are supported and set them to true */
92 bool xcursor_supported = true;
93 bool xkb_supported = true;
94
95 bool force_xinerama = false;
96
97 /*
98  * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.
99  * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
100  *
101  */
102 static void xcb_got_event(EV_P_ struct ev_io *w, int revents) {
103     /* empty, because xcb_prepare_cb and xcb_check_cb are used */
104 }
105
106 /*
107  * Flush before blocking (and waiting for new events)
108  *
109  */
110 static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) {
111     xcb_flush(conn);
112 }
113
114 /*
115  * Instead of polling the X connection socket we leave this to
116  * xcb_poll_for_event() which knows better than we can ever know.
117  *
118  */
119 static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
120     xcb_generic_event_t *event;
121
122     while ((event = xcb_poll_for_event(conn)) != NULL) {
123         if (event->response_type == 0) {
124             if (event_is_ignored(event->sequence, 0))
125                 DLOG("Expected X11 Error received for sequence %x\n", event->sequence);
126             else {
127                 xcb_generic_error_t *error = (xcb_generic_error_t *)event;
128                 DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
129                      error->sequence, error->error_code);
130             }
131             free(event);
132             continue;
133         }
134
135         /* Strip off the highest bit (set if the event is generated) */
136         int type = (event->response_type & 0x7F);
137
138         handle_event(type, event);
139
140         free(event);
141     }
142 }
143
144 /*
145  * Enable or disable the main X11 event handling function.
146  * This is used by drag_pointer() which has its own, modal event handler, which
147  * takes precedence over the normal event handler.
148  *
149  */
150 void main_set_x11_cb(bool enable) {
151     DLOG("Setting main X11 callback to enabled=%d\n", enable);
152     if (enable) {
153         ev_check_start(main_loop, xcb_check);
154         /* Trigger the watcher explicitly to handle all remaining X11 events.
155          * drag_pointer()’s event handler exits in the middle of the loop. */
156         ev_feed_event(main_loop, xcb_check, 0);
157     } else {
158         ev_check_stop(main_loop, xcb_check);
159     }
160 }
161
162 /*
163  * Exit handler which destroys the main_loop. Will trigger cleanup handlers.
164  *
165  */
166 static void i3_exit(void) {
167 /* We need ev >= 4 for the following code. Since it is not *that* important (it
168  * only makes sure that there are no i3-nagbar instances left behind) we still
169  * support old systems with libev 3. */
170 #if EV_VERSION_MAJOR >= 4
171     ev_loop_destroy(main_loop);
172 #endif
173
174     if (*shmlogname != '\0') {
175         fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname);
176         fflush(stderr);
177         shm_unlink(shmlogname);
178     }
179 }
180
181 /*
182  * (One-shot) Handler for all signals with default action "Term", see signal(7)
183  *
184  * Unlinks the SHM log and re-raises the signal.
185  *
186  */
187 static void handle_signal(int sig, siginfo_t *info, void *data) {
188     if (*shmlogname != '\0') {
189         shm_unlink(shmlogname);
190     }
191     raise(sig);
192 }
193
194 int main(int argc, char *argv[]) {
195     /* Keep a symbol pointing to the I3_VERSION string constant so that we have
196      * it in gdb backtraces. */
197     static const char *_i3_version __attribute__((used)) = I3_VERSION;
198     char *override_configpath = NULL;
199     bool autostart = true;
200     char *layout_path = NULL;
201     bool delete_layout_path = false;
202     bool disable_randr15 = false;
203     char *fake_outputs = NULL;
204     bool disable_signalhandler = false;
205     bool only_check_config = false;
206     static struct option long_options[] = {
207         {"no-autostart", no_argument, 0, 'a'},
208         {"config", required_argument, 0, 'c'},
209         {"version", no_argument, 0, 'v'},
210         {"moreversion", no_argument, 0, 'm'},
211         {"more-version", no_argument, 0, 'm'},
212         {"more_version", no_argument, 0, 'm'},
213         {"help", no_argument, 0, 'h'},
214         {"layout", required_argument, 0, 'L'},
215         {"restart", required_argument, 0, 0},
216         {"force-xinerama", no_argument, 0, 0},
217         {"force_xinerama", no_argument, 0, 0},
218         {"disable-randr15", no_argument, 0, 0},
219         {"disable_randr15", no_argument, 0, 0},
220         {"disable-signalhandler", no_argument, 0, 0},
221         {"shmlog-size", required_argument, 0, 0},
222         {"shmlog_size", required_argument, 0, 0},
223         {"get-socketpath", no_argument, 0, 0},
224         {"get_socketpath", no_argument, 0, 0},
225         {"fake_outputs", required_argument, 0, 0},
226         {"fake-outputs", required_argument, 0, 0},
227         {"force-old-config-parser-v4.4-only", no_argument, 0, 0},
228         {0, 0, 0, 0}};
229     int option_index = 0, opt;
230
231     setlocale(LC_ALL, "");
232
233     /* Get the RLIMIT_CORE limit at startup time to restore this before
234      * starting processes. */
235     getrlimit(RLIMIT_CORE, &original_rlimit_core);
236
237     /* Disable output buffering to make redirects in .xsession actually useful for debugging */
238     if (!isatty(fileno(stdout)))
239         setbuf(stdout, NULL);
240
241     srand(time(NULL));
242
243     /* Init logging *before* initializing debug_build to guarantee early
244      * (file) logging. */
245     init_logging();
246
247     /* On release builds, disable SHM logging by default. */
248     shmlog_size = (is_debug_build() || strstr(argv[0], "i3-with-shmlog") != NULL ? default_shmlog_size : 0);
249
250     start_argv = argv;
251
252     while ((opt = getopt_long(argc, argv, "c:CvmaL:hld:V", long_options, &option_index)) != -1) {
253         switch (opt) {
254             case 'a':
255                 LOG("Autostart disabled using -a\n");
256                 autostart = false;
257                 break;
258             case 'L':
259                 FREE(layout_path);
260                 layout_path = sstrdup(optarg);
261                 delete_layout_path = false;
262                 break;
263             case 'c':
264                 FREE(override_configpath);
265                 override_configpath = sstrdup(optarg);
266                 break;
267             case 'C':
268                 LOG("Checking configuration file only (-C)\n");
269                 only_check_config = true;
270                 break;
271             case 'v':
272                 printf("i3 version %s © 2009 Michael Stapelberg and contributors\n", i3_version);
273                 exit(EXIT_SUCCESS);
274                 break;
275             case 'm':
276                 printf("Binary i3 version:  %s © 2009 Michael Stapelberg and contributors\n", i3_version);
277                 display_running_version();
278                 exit(EXIT_SUCCESS);
279                 break;
280             case 'V':
281                 set_verbosity(true);
282                 break;
283             case 'd':
284                 LOG("Enabling debug logging\n");
285                 set_debug_logging(true);
286                 break;
287             case 'l':
288                 /* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
289                 break;
290             case 0:
291                 if (strcmp(long_options[option_index].name, "force-xinerama") == 0 ||
292                     strcmp(long_options[option_index].name, "force_xinerama") == 0) {
293                     force_xinerama = true;
294                     ELOG("Using Xinerama instead of RandR. This option should be "
295                          "avoided at all cost because it does not refresh the list "
296                          "of screens, so you cannot configure displays at runtime. "
297                          "Please check if your driver really does not support RandR "
298                          "and disable this option as soon as you can.\n");
299                     break;
300                 } else if (strcmp(long_options[option_index].name, "disable-randr15") == 0 ||
301                            strcmp(long_options[option_index].name, "disable_randr15") == 0) {
302                     disable_randr15 = true;
303                     break;
304                 } else if (strcmp(long_options[option_index].name, "disable-signalhandler") == 0) {
305                     disable_signalhandler = true;
306                     break;
307                 } else if (strcmp(long_options[option_index].name, "get-socketpath") == 0 ||
308                            strcmp(long_options[option_index].name, "get_socketpath") == 0) {
309                     char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
310                     if (socket_path) {
311                         printf("%s\n", socket_path);
312                         exit(EXIT_SUCCESS);
313                     }
314
315                     exit(EXIT_FAILURE);
316                 } else if (strcmp(long_options[option_index].name, "shmlog-size") == 0 ||
317                            strcmp(long_options[option_index].name, "shmlog_size") == 0) {
318                     shmlog_size = atoi(optarg);
319                     /* Re-initialize logging immediately to get as many
320                      * logmessages as possible into the SHM log. */
321                     init_logging();
322                     LOG("Limiting SHM log size to %d bytes\n", shmlog_size);
323                     break;
324                 } else if (strcmp(long_options[option_index].name, "restart") == 0) {
325                     FREE(layout_path);
326                     layout_path = sstrdup(optarg);
327                     delete_layout_path = true;
328                     break;
329                 } else if (strcmp(long_options[option_index].name, "fake-outputs") == 0 ||
330                            strcmp(long_options[option_index].name, "fake_outputs") == 0) {
331                     LOG("Initializing fake outputs: %s\n", optarg);
332                     fake_outputs = sstrdup(optarg);
333                     break;
334                 } else if (strcmp(long_options[option_index].name, "force-old-config-parser-v4.4-only") == 0) {
335                     ELOG("You are passing --force-old-config-parser-v4.4-only, but that flag was removed by now.\n");
336                     break;
337                 }
338             /* fall-through */
339             default:
340                 fprintf(stderr, "Usage: %s [-c configfile] [-d all] [-a] [-v] [-V] [-C]\n", argv[0]);
341                 fprintf(stderr, "\n");
342                 fprintf(stderr, "\t-a          disable autostart ('exec' lines in config)\n");
343                 fprintf(stderr, "\t-c <file>   use the provided configfile instead\n");
344                 fprintf(stderr, "\t-C          validate configuration file and exit\n");
345                 fprintf(stderr, "\t-d all      enable debug output\n");
346                 fprintf(stderr, "\t-L <file>   path to the serialized layout during restarts\n");
347                 fprintf(stderr, "\t-v          display version and exit\n");
348                 fprintf(stderr, "\t-V          enable verbose mode\n");
349                 fprintf(stderr, "\n");
350                 fprintf(stderr, "\t--force-xinerama\n"
351                                 "\tUse Xinerama instead of RandR.\n"
352                                 "\tThis option should only be used if you are stuck with the\n"
353                                 "\told nVidia closed source driver (older than 302.17), which does\n"
354                                 "\tnot support RandR.\n");
355                 fprintf(stderr, "\n");
356                 fprintf(stderr, "\t--get-socketpath\n"
357                                 "\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
358                 fprintf(stderr, "\n");
359                 fprintf(stderr, "\t--shmlog-size <limit>\n"
360                                 "\tLimits the size of the i3 SHM log to <limit> bytes. Setting this\n"
361                                 "\tto 0 disables SHM logging entirely.\n"
362                                 "\tThe default is %d bytes.\n",
363                         shmlog_size);
364                 fprintf(stderr, "\n");
365                 fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
366                                 "to send to a currently running i3 (like i3-msg). This allows you to\n"
367                                 "use nice and logical commands, such as:\n"
368                                 "\n"
369                                 "\ti3 border none\n"
370                                 "\ti3 floating toggle\n"
371                                 "\ti3 kill window\n"
372                                 "\n");
373                 exit(EXIT_FAILURE);
374         }
375     }
376
377     if (only_check_config) {
378         exit(parse_configuration(override_configpath, false) ? 0 : 1);
379     }
380
381     /* If the user passes more arguments, we act like i3-msg would: Just send
382      * the arguments as an IPC message to i3. This allows for nice semantic
383      * commands such as 'i3 border none'. */
384     if (optind < argc) {
385         /* We enable verbose mode so that the user knows what’s going on.
386          * This should make it easier to find mistakes when the user passes
387          * arguments by mistake. */
388         set_verbosity(true);
389
390         LOG("Additional arguments passed. Sending them as a command to i3.\n");
391         char *payload = NULL;
392         while (optind < argc) {
393             if (!payload) {
394                 payload = sstrdup(argv[optind]);
395             } else {
396                 char *both;
397                 sasprintf(&both, "%s %s", payload, argv[optind]);
398                 free(payload);
399                 payload = both;
400             }
401             optind++;
402         }
403         DLOG("Command is: %s (%zd bytes)\n", payload, strlen(payload));
404         char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
405         if (!socket_path) {
406             ELOG("Could not get i3 IPC socket path\n");
407             return 1;
408         }
409
410         int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
411         if (sockfd == -1)
412             err(EXIT_FAILURE, "Could not create socket");
413
414         struct sockaddr_un addr;
415         memset(&addr, 0, sizeof(struct sockaddr_un));
416         addr.sun_family = AF_LOCAL;
417         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
418         FREE(socket_path);
419         if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
420             err(EXIT_FAILURE, "Could not connect to i3");
421
422         if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_RUN_COMMAND,
423                              (uint8_t *)payload) == -1)
424             err(EXIT_FAILURE, "IPC: write()");
425         FREE(payload);
426
427         uint32_t reply_length;
428         uint32_t reply_type;
429         uint8_t *reply;
430         int ret;
431         if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
432             if (ret == -1)
433                 err(EXIT_FAILURE, "IPC: read()");
434             return 1;
435         }
436         if (reply_type != I3_IPC_REPLY_TYPE_COMMAND)
437             errx(EXIT_FAILURE, "IPC: received reply of type %d but expected %d (COMMAND)", reply_type, I3_IPC_REPLY_TYPE_COMMAND);
438         printf("%.*s\n", reply_length, reply);
439         FREE(reply);
440         return 0;
441     }
442
443     /* Enable logging to handle the case when the user did not specify --shmlog-size */
444     init_logging();
445
446     /* Try to enable core dumps by default when running a debug build */
447     if (is_debug_build()) {
448         struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
449         setrlimit(RLIMIT_CORE, &limit);
450
451         /* The following code is helpful, but not required. We thus don’t pay
452          * much attention to error handling, non-linux or other edge cases. */
453         LOG("CORE DUMPS: You are running a development version of i3, so coredumps were automatically enabled (ulimit -c unlimited).\n");
454         size_t cwd_size = 1024;
455         char *cwd = smalloc(cwd_size);
456         char *cwd_ret;
457         while ((cwd_ret = getcwd(cwd, cwd_size)) == NULL && errno == ERANGE) {
458             cwd_size = cwd_size * 2;
459             cwd = srealloc(cwd, cwd_size);
460         }
461         if (cwd_ret != NULL)
462             LOG("CORE DUMPS: Your current working directory is \"%s\".\n", cwd);
463         int patternfd;
464         if ((patternfd = open("/proc/sys/kernel/core_pattern", O_RDONLY)) >= 0) {
465             memset(cwd, '\0', cwd_size);
466             if (read(patternfd, cwd, cwd_size) > 0)
467                 /* a trailing newline is included in cwd */
468                 LOG("CORE DUMPS: Your core_pattern is: %s", cwd);
469             close(patternfd);
470         }
471         free(cwd);
472     }
473
474     LOG("i3 %s starting\n", i3_version);
475
476     conn = xcb_connect(NULL, &conn_screen);
477     if (xcb_connection_has_error(conn))
478         errx(EXIT_FAILURE, "Cannot open display\n");
479
480     sndisplay = sn_xcb_display_new(conn, NULL, NULL);
481
482     /* Initialize the libev event loop. This needs to be done before loading
483      * the config file because the parser will install an ev_child watcher
484      * for the nagbar when config errors are found. */
485     main_loop = EV_DEFAULT;
486     if (main_loop == NULL)
487         die("Could not initialize libev. Bad LIBEV_FLAGS?\n");
488
489     root_screen = xcb_aux_get_screen(conn, conn_screen);
490     root = root_screen->root;
491
492 /* Place requests for the atoms we need as soon as possible */
493 #define xmacro(atom) \
494     xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
495 #include "atoms.xmacro"
496 #undef xmacro
497
498     root_depth = root_screen->root_depth;
499     colormap = root_screen->default_colormap;
500     visual_type = xcb_aux_find_visual_by_attrs(root_screen, -1, 32);
501     if (visual_type != NULL) {
502         root_depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id);
503         colormap = xcb_generate_id(conn);
504
505         xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(conn,
506                                                                   XCB_COLORMAP_ALLOC_NONE,
507                                                                   colormap,
508                                                                   root,
509                                                                   visual_type->visual_id);
510
511         xcb_generic_error_t *error = xcb_request_check(conn, cm_cookie);
512         if (error != NULL) {
513             ELOG("Could not create colormap. Error code: %d\n", error->error_code);
514             exit(EXIT_FAILURE);
515         }
516     } else {
517         visual_type = get_visualtype(root_screen);
518     }
519
520     init_dpi();
521
522     DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id);
523     DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d\n",
524          root_screen->height_in_pixels, root_screen->height_in_millimeters);
525     DLOG("One logical pixel corresponds to %d physical pixels on this display.\n", logical_px(1));
526
527     xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
528     xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
529
530 /* Setup NetWM atoms */
531 #define xmacro(name)                                                                       \
532     do {                                                                                   \
533         xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
534         if (!reply) {                                                                      \
535             ELOG("Could not get atom " #name "\n");                                        \
536             exit(-1);                                                                      \
537         }                                                                                  \
538         A_##name = reply->atom;                                                            \
539         free(reply);                                                                       \
540     } while (0);
541 #include "atoms.xmacro"
542 #undef xmacro
543
544     load_configuration(conn, override_configpath, false);
545
546     if (config.ipc_socket_path == NULL) {
547         /* Fall back to a file name in /tmp/ based on the PID */
548         if ((config.ipc_socket_path = getenv("I3SOCK")) == NULL)
549             config.ipc_socket_path = get_process_filename("ipc-socket");
550         else
551             config.ipc_socket_path = sstrdup(config.ipc_socket_path);
552     }
553
554     if (config.force_xinerama) {
555         force_xinerama = true;
556     }
557
558     xcb_void_cookie_t cookie;
559     cookie = xcb_change_window_attributes_checked(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){ROOT_EVENT_MASK});
560     xcb_generic_error_t *error = xcb_request_check(conn, cookie);
561     if (error != NULL) {
562         ELOG("Another window manager seems to be running (X error %d)\n", error->error_code);
563 #ifdef I3_ASAN_ENABLED
564         __lsan_do_leak_check();
565 #endif
566         return 1;
567     }
568
569     xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
570     if (greply == NULL) {
571         ELOG("Could not get geometry of the root window, exiting\n");
572         return 1;
573     }
574     DLOG("root geometry reply: (%d, %d) %d x %d\n", greply->x, greply->y, greply->width, greply->height);
575
576     xcursor_load_cursors();
577
578     /* Set a cursor for the root window (otherwise the root window will show no
579        cursor until the first client is launched). */
580     if (xcursor_supported)
581         xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER);
582     else
583         xcb_set_root_cursor(XCURSOR_CURSOR_POINTER);
584
585     const xcb_query_extension_reply_t *extreply;
586     extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
587     xkb_supported = extreply->present;
588     if (!extreply->present) {
589         DLOG("xkb is not present on this server\n");
590     } else {
591         DLOG("initializing xcb-xkb\n");
592         xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
593         xcb_xkb_select_events(conn,
594                               XCB_XKB_ID_USE_CORE_KBD,
595                               XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY,
596                               0,
597                               XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY,
598                               0xff,
599                               0xff,
600                               NULL);
601
602         /* Setting both, XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE and
603          * XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED, will lead to the
604          * X server sending us the full XKB state in KeyPress and KeyRelease:
605          * https://sources.debian.net/src/xorg-server/2:1.17.2-1.1/xkb/xkbEvents.c/?hl=927#L927
606          */
607         xcb_xkb_per_client_flags_reply_t *pcf_reply;
608         /* The last three parameters are unset because they are only relevant
609          * when using a feature called “automatic reset of boolean controls”:
610          * https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Automatic_Reset_of_Boolean_Controls
611          * */
612         pcf_reply = xcb_xkb_per_client_flags_reply(
613             conn,
614             xcb_xkb_per_client_flags(
615                 conn,
616                 XCB_XKB_ID_USE_CORE_KBD,
617                 XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE | XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED,
618                 XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE | XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED,
619                 0 /* uint32_t ctrlsToChange */,
620                 0 /* uint32_t autoCtrls */,
621                 0 /* uint32_t autoCtrlsValues */),
622             NULL);
623         if (pcf_reply == NULL ||
624             !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE)) {
625             ELOG("Could not set XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE\n");
626         }
627         if (pcf_reply == NULL ||
628             !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED)) {
629             ELOG("Could not set XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED\n");
630         }
631         free(pcf_reply);
632         xkb_base = extreply->first_event;
633     }
634
635     restore_connect();
636
637     property_handlers_init();
638
639     ewmh_setup_hints();
640
641     keysyms = xcb_key_symbols_alloc(conn);
642
643     xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
644
645     if (!load_keymap())
646         die("Could not load keymap\n");
647
648     translate_keysyms();
649     grab_all_keys(conn);
650
651     bool needs_tree_init = true;
652     if (layout_path != NULL) {
653         LOG("Trying to restore the layout from \"%s\".\n", layout_path);
654         needs_tree_init = !tree_restore(layout_path, greply);
655         if (delete_layout_path) {
656             unlink(layout_path);
657             const char *dir = dirname(layout_path);
658             /* possibly fails with ENOTEMPTY if there are files (or
659              * sockets) left. */
660             rmdir(dir);
661         }
662     }
663     if (needs_tree_init)
664         tree_init(greply);
665
666     free(greply);
667
668     /* Setup fake outputs for testing */
669     if (fake_outputs == NULL && config.fake_outputs != NULL)
670         fake_outputs = config.fake_outputs;
671
672     if (fake_outputs != NULL) {
673         fake_outputs_init(fake_outputs);
674         FREE(fake_outputs);
675         config.fake_outputs = NULL;
676     } else if (force_xinerama) {
677         /* Force Xinerama (for drivers which don't support RandR yet, esp. the
678          * nVidia binary graphics driver), when specified either in the config
679          * file or on command-line */
680         xinerama_init();
681     } else {
682         DLOG("Checking for XRandR...\n");
683         randr_init(&randr_base, disable_randr15 || config.disable_randr15);
684     }
685
686     /* We need to force disabling outputs which have been loaded from the
687      * layout file but are no longer active. This can happen if the output has
688      * been disabled in the short time between writing the restart layout file
689      * and restarting i3. See #2326. */
690     if (layout_path != NULL && randr_base > -1) {
691         Con *con;
692         TAILQ_FOREACH(con, &(croot->nodes_head), nodes) {
693             Output *output;
694             TAILQ_FOREACH(output, &outputs, outputs) {
695                 if (output->active || strcmp(con->name, output_primary_name(output)) != 0)
696                     continue;
697
698                 /* This will correctly correlate the output with its content
699                  * container. We need to make the connection to properly
700                  * disable the output. */
701                 if (output->con == NULL) {
702                     output_init_con(output);
703                     output->changed = false;
704                 }
705
706                 output->to_be_disabled = true;
707                 randr_disable_output(output);
708             }
709         }
710     }
711     FREE(layout_path);
712
713     scratchpad_fix_resolution();
714
715     xcb_query_pointer_reply_t *pointerreply;
716     Output *output = NULL;
717     if (!(pointerreply = xcb_query_pointer_reply(conn, pointercookie, NULL))) {
718         ELOG("Could not query pointer position, using first screen\n");
719     } else {
720         DLOG("Pointer at %d, %d\n", pointerreply->root_x, pointerreply->root_y);
721         output = get_output_containing(pointerreply->root_x, pointerreply->root_y);
722         if (!output) {
723             ELOG("ERROR: No screen at (%d, %d), starting on the first screen\n",
724                  pointerreply->root_x, pointerreply->root_y);
725             output = get_first_output();
726         }
727
728         con_focus(con_descend_focused(output_get_content(output->con)));
729         free(pointerreply);
730     }
731
732     tree_render();
733
734     /* Create the UNIX domain socket for IPC */
735     int ipc_socket = ipc_create_socket(config.ipc_socket_path);
736     if (ipc_socket == -1) {
737         ELOG("Could not create the IPC socket, IPC disabled\n");
738     } else {
739         struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
740         ev_io_init(ipc_io, ipc_new_client, ipc_socket, EV_READ);
741         ev_io_start(main_loop, ipc_io);
742     }
743
744     /* Also handle the UNIX domain sockets passed via socket activation. The
745      * parameter 1 means "remove the environment variables", we don’t want to
746      * pass these to child processes. */
747     listen_fds = sd_listen_fds(0);
748     if (listen_fds < 0)
749         ELOG("socket activation: Error in sd_listen_fds\n");
750     else if (listen_fds == 0)
751         DLOG("socket activation: no sockets passed\n");
752     else {
753         int flags;
754         for (int fd = SD_LISTEN_FDS_START;
755              fd < (SD_LISTEN_FDS_START + listen_fds);
756              fd++) {
757             DLOG("socket activation: also listening on fd %d\n", fd);
758
759             /* sd_listen_fds() enables FD_CLOEXEC by default.
760              * However, we need to keep the file descriptors open for in-place
761              * restarting, therefore we explicitly disable FD_CLOEXEC. */
762             if ((flags = fcntl(fd, F_GETFD)) < 0 ||
763                 fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
764                 ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd);
765             }
766
767             struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
768             ev_io_init(ipc_io, ipc_new_client, fd, EV_READ);
769             ev_io_start(main_loop, ipc_io);
770         }
771     }
772
773     /* Set up i3 specific atoms like I3_SOCKET_PATH and I3_CONFIG_PATH */
774     x_set_i3_atoms();
775     ewmh_update_workarea();
776
777     /* Set the ewmh desktop properties. */
778     ewmh_update_current_desktop();
779     ewmh_update_number_of_desktops();
780     ewmh_update_desktop_names();
781     ewmh_update_desktop_viewport();
782
783     struct ev_io *xcb_watcher = scalloc(1, sizeof(struct ev_io));
784     xcb_check = scalloc(1, sizeof(struct ev_check));
785     struct ev_prepare *xcb_prepare = scalloc(1, sizeof(struct ev_prepare));
786
787     ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
788     ev_io_start(main_loop, xcb_watcher);
789
790     ev_check_init(xcb_check, xcb_check_cb);
791     ev_check_start(main_loop, xcb_check);
792
793     ev_prepare_init(xcb_prepare, xcb_prepare_cb);
794     ev_prepare_start(main_loop, xcb_prepare);
795
796     xcb_flush(conn);
797
798     /* What follows is a fugly consequence of X11 protocol race conditions like
799      * the following: In an i3 in-place restart, i3 will reparent all windows
800      * to the root window, then exec() itself. In the new process, it calls
801      * manage_existing_windows. However, in case any application sent a
802      * generated UnmapNotify message to the WM (as GIMP does), this message
803      * will be handled by i3 *after* managing the window, thus i3 thinks the
804      * window just closed itself. In reality, the message was sent in the time
805      * period where i3 wasn’t running yet.
806      *
807      * To prevent this, we grab the server (disables processing of any other
808      * connections), then discard all pending events (since we didn’t do
809      * anything, there cannot be any meaningful responses), then ungrab the
810      * server. */
811     xcb_grab_server(conn);
812     {
813         xcb_aux_sync(conn);
814         xcb_generic_event_t *event;
815         while ((event = xcb_poll_for_event(conn)) != NULL) {
816             if (event->response_type == 0) {
817                 free(event);
818                 continue;
819             }
820
821             /* Strip off the highest bit (set if the event is generated) */
822             int type = (event->response_type & 0x7F);
823
824             /* We still need to handle MapRequests which are sent in the
825              * timespan starting from when we register as a window manager and
826              * this piece of code which drops events. */
827             if (type == XCB_MAP_REQUEST)
828                 handle_event(type, event);
829
830             free(event);
831         }
832         manage_existing_windows(root);
833     }
834     xcb_ungrab_server(conn);
835
836     if (autostart) {
837         LOG("This is not an in-place restart, copying root window contents to a pixmap\n");
838         xcb_screen_t *root = xcb_aux_get_screen(conn, conn_screen);
839         uint16_t width = root->width_in_pixels;
840         uint16_t height = root->height_in_pixels;
841         xcb_pixmap_t pixmap = xcb_generate_id(conn);
842         xcb_gcontext_t gc = xcb_generate_id(conn);
843
844         xcb_create_pixmap(conn, root->root_depth, pixmap, root->root, width, height);
845
846         xcb_create_gc(conn, gc, root->root,
847                       XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FILL_STYLE | XCB_GC_SUBWINDOW_MODE,
848                       (uint32_t[]){XCB_GX_COPY, ~0, XCB_FILL_STYLE_SOLID, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS});
849
850         xcb_copy_area(conn, root->root, pixmap, gc, 0, 0, 0, 0, width, height);
851         xcb_change_window_attributes(conn, root->root, XCB_CW_BACK_PIXMAP, (uint32_t[]){pixmap});
852         xcb_flush(conn);
853         xcb_free_gc(conn, gc);
854         xcb_free_pixmap(conn, pixmap);
855     }
856
857 #if defined(__OpenBSD__)
858     if (pledge("stdio rpath wpath cpath proc exec unix", NULL) == -1)
859         err(EXIT_FAILURE, "pledge");
860 #endif
861
862     struct sigaction action;
863
864     action.sa_sigaction = handle_signal;
865     action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
866     sigemptyset(&action.sa_mask);
867
868     if (!disable_signalhandler)
869         setup_signal_handler();
870     else {
871         /* Catch all signals with default action "Core", see signal(7) */
872         if (sigaction(SIGQUIT, &action, NULL) == -1 ||
873             sigaction(SIGILL, &action, NULL) == -1 ||
874             sigaction(SIGABRT, &action, NULL) == -1 ||
875             sigaction(SIGFPE, &action, NULL) == -1 ||
876             sigaction(SIGSEGV, &action, NULL) == -1)
877             ELOG("Could not setup signal handler.\n");
878     }
879
880     /* Catch all signals with default action "Term", see signal(7) */
881     if (sigaction(SIGHUP, &action, NULL) == -1 ||
882         sigaction(SIGINT, &action, NULL) == -1 ||
883         sigaction(SIGALRM, &action, NULL) == -1 ||
884         sigaction(SIGUSR1, &action, NULL) == -1 ||
885         sigaction(SIGUSR2, &action, NULL) == -1)
886         ELOG("Could not setup signal handler.\n");
887
888     /* Ignore SIGPIPE to survive errors when an IPC client disconnects
889      * while we are sending them a message */
890     signal(SIGPIPE, SIG_IGN);
891
892     /* Autostarting exec-lines */
893     if (autostart) {
894         while (!TAILQ_EMPTY(&autostarts)) {
895             struct Autostart *exec = TAILQ_FIRST(&autostarts);
896
897             LOG("auto-starting %s\n", exec->command);
898             start_application(exec->command, exec->no_startup_id);
899
900             FREE(exec->command);
901             TAILQ_REMOVE(&autostarts, exec, autostarts);
902             FREE(exec);
903         }
904     }
905
906     /* Autostarting exec_always-lines */
907     while (!TAILQ_EMPTY(&autostarts_always)) {
908         struct Autostart *exec_always = TAILQ_FIRST(&autostarts_always);
909
910         LOG("auto-starting (always!) %s\n", exec_always->command);
911         start_application(exec_always->command, exec_always->no_startup_id);
912
913         FREE(exec_always->command);
914         TAILQ_REMOVE(&autostarts_always, exec_always, autostarts_always);
915         FREE(exec_always);
916     }
917
918     /* Start i3bar processes for all configured bars */
919     Barconfig *barconfig;
920     TAILQ_FOREACH(barconfig, &barconfigs, configs) {
921         char *command = NULL;
922         sasprintf(&command, "%s --bar_id=%s --socket=\"%s\"",
923                   barconfig->i3bar_command ? barconfig->i3bar_command : "i3bar",
924                   barconfig->id, current_socketpath);
925         LOG("Starting bar process: %s\n", command);
926         start_application(command, true);
927         free(command);
928     }
929
930     /* Make sure to destroy the event loop to invoke the cleeanup callbacks
931      * when calling exit() */
932     atexit(i3_exit);
933
934     ev_loop(main_loop, 0);
935 }