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