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