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