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