i3
main.c
Go to the documentation of this file.
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-2013 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 
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 static int xkb_event_base;
40 
42 
43 extern Con *focused;
44 
45 char **start_argv;
46 
47 xcb_connection_t *conn;
48 /* The screen (0 when you are using DISPLAY=:0) of the connection 'conn' */
50 
51 /* Display handle for libstartup-notification */
52 SnDisplay *sndisplay;
53 
54 /* The last timestamp we got from X11 (timestamps are included in some events
55  * and are used for some things, like determining a unique ID in startup
56  * notification). */
57 xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
58 
59 xcb_screen_t *root_screen;
60 xcb_window_t root;
61 
62 /* Color depth, visual id and colormap to use when creating windows and
63  * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
64  * otherwise the root window’s default (usually 24 bit TrueColor). */
65 uint8_t root_depth;
66 xcb_visualid_t visual_id;
67 xcb_colormap_t colormap;
68 
69 struct ev_loop *main_loop;
70 
71 xcb_key_symbols_t *keysyms;
72 
73 /* Those are our connections to X11 for use with libXcursor and XKB */
74 Display *xlibdpy, *xkbdpy;
75 
76 /* Default shmlog size if not set by user. */
77 const int default_shmlog_size = 25 * 1024 * 1024;
78 
79 /* The list of key bindings */
80 struct bindings_head *bindings;
81 
82 /* The list of exec-lines */
83 struct autostarts_head autostarts = TAILQ_HEAD_INITIALIZER(autostarts);
84 
85 /* The list of exec_always lines */
87 
88 /* The list of assignments */
89 struct assignments_head assignments = TAILQ_HEAD_INITIALIZER(assignments);
90 
91 /* The list of workspace assignments (which workspace should end up on which
92  * output) */
94 
95 /* We hope that those are supported and set them to true */
96 bool xcursor_supported = true;
97 bool xkb_supported = true;
98 
99 /* This will be set to true when -C is used so that functions can behave
100  * slightly differently. We don’t want i3-nagbar to be started when validating
101  * the config, for example. */
102 bool only_check_config = false;
103 
104 /*
105  * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.
106  * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
107  *
108  */
109 static void xcb_got_event(EV_P_ struct ev_io *w, int revents) {
110  /* empty, because xcb_prepare_cb and xcb_check_cb are used */
111 }
112 
113 /*
114  * Flush before blocking (and waiting for new events)
115  *
116  */
117 static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) {
118  xcb_flush(conn);
119 }
120 
121 /*
122  * Instead of polling the X connection socket we leave this to
123  * xcb_poll_for_event() which knows better than we can ever know.
124  *
125  */
126 static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
127  xcb_generic_event_t *event;
128 
129  while ((event = xcb_poll_for_event(conn)) != NULL) {
130  if (event->response_type == 0) {
131  if (event_is_ignored(event->sequence, 0))
132  DLOG("Expected X11 Error received for sequence %x\n", event->sequence);
133  else {
134  xcb_generic_error_t *error = (xcb_generic_error_t *)event;
135  DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
136  error->sequence, error->error_code);
137  }
138  free(event);
139  continue;
140  }
141 
142  /* Strip off the highest bit (set if the event is generated) */
143  int type = (event->response_type & 0x7F);
144 
145  handle_event(type, event);
146 
147  free(event);
148  }
149 }
150 
151 /*
152  * Enable or disable the main X11 event handling function.
153  * This is used by drag_pointer() which has its own, modal event handler, which
154  * takes precedence over the normal event handler.
155  *
156  */
157 void main_set_x11_cb(bool enable) {
158  DLOG("Setting main X11 callback to enabled=%d\n", enable);
159  if (enable) {
160  ev_check_start(main_loop, xcb_check);
161  /* Trigger the watcher explicitly to handle all remaining X11 events.
162  * drag_pointer()’s event handler exits in the middle of the loop. */
163  ev_feed_event(main_loop, xcb_check, 0);
164  } else {
165  ev_check_stop(main_loop, xcb_check);
166  }
167 }
168 
169 /*
170  * When using xmodmap to change the keyboard mapping, this event
171  * is only sent via XKB. Therefore, we need this special handler.
172  *
173  */
174 static void xkb_got_event(EV_P_ struct ev_io *w, int revents) {
175  DLOG("Handling XKB event\n");
176  XkbEvent ev;
177 
178  /* When using xmodmap, every change (!) gets an own event.
179  * Therefore, we just read all events and only handle the
180  * mapping_notify once. */
181  bool mapping_changed = false;
182  while (XPending(xkbdpy)) {
183  XNextEvent(xkbdpy, (XEvent *)&ev);
184  /* While we should never receive a non-XKB event,
185  * better do sanity checking */
186  if (ev.type != xkb_event_base)
187  continue;
188 
189  if (ev.any.xkb_type == XkbMapNotify) {
190  mapping_changed = true;
191  continue;
192  }
193 
194  if (ev.any.xkb_type != XkbStateNotify) {
195  ELOG("Unknown XKB event received (type %d)\n", ev.any.xkb_type);
196  continue;
197  }
198 
199  /* See The XKB Extension: Library Specification, section 14.1 */
200  /* We check if the current group (each group contains
201  * two levels) has been changed. Mode_switch activates
202  * group XkbGroup2Index */
203  if (xkb_current_group == ev.state.group)
204  continue;
205 
206  xkb_current_group = ev.state.group;
207 
208  if (ev.state.group == XkbGroup2Index) {
209  DLOG("Mode_switch enabled\n");
210  grab_all_keys(conn, true);
211  }
212 
213  if (ev.state.group == XkbGroup1Index) {
214  DLOG("Mode_switch disabled\n");
216  grab_all_keys(conn, false);
217  }
218  }
219 
220  if (!mapping_changed)
221  return;
222 
223  DLOG("Keyboard mapping changed, updating keybindings\n");
224  xcb_key_symbols_free(keysyms);
225  keysyms = xcb_key_symbols_alloc(conn);
226 
228 
230  DLOG("Re-grabbing...\n");
232  grab_all_keys(conn, (xkb_current_group == XkbGroup2Index));
233  DLOG("Done\n");
234 }
235 
236 /*
237  * Exit handler which destroys the main_loop. Will trigger cleanup handlers.
238  *
239  */
240 static void i3_exit(void) {
241 /* We need ev >= 4 for the following code. Since it is not *that* important (it
242  * only makes sure that there are no i3-nagbar instances left behind) we still
243  * support old systems with libev 3. */
244 #if EV_VERSION_MAJOR >= 4
245  ev_loop_destroy(main_loop);
246 #endif
247 
248  if (*shmlogname != '\0') {
249  fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname);
250  fflush(stderr);
251  shm_unlink(shmlogname);
252  }
253 }
254 
255 /*
256  * (One-shot) Handler for all signals with default action "Term", see signal(7)
257  *
258  * Unlinks the SHM log and re-raises the signal.
259  *
260  */
261 static void handle_signal(int sig, siginfo_t *info, void *data) {
262  if (*shmlogname != '\0') {
263  shm_unlink(shmlogname);
264  }
265  raise(sig);
266 }
267 
268 int main(int argc, char *argv[]) {
269  /* Keep a symbol pointing to the I3_VERSION string constant so that we have
270  * it in gdb backtraces. */
271  const char *i3_version __attribute__((unused)) = I3_VERSION;
272  char *override_configpath = NULL;
273  bool autostart = true;
274  char *layout_path = NULL;
275  bool delete_layout_path = false;
276  bool force_xinerama = false;
277  char *fake_outputs = NULL;
278  bool disable_signalhandler = false;
279  static struct option long_options[] = {
280  {"no-autostart", no_argument, 0, 'a'},
281  {"config", required_argument, 0, 'c'},
282  {"version", no_argument, 0, 'v'},
283  {"moreversion", no_argument, 0, 'm'},
284  {"more-version", no_argument, 0, 'm'},
285  {"more_version", no_argument, 0, 'm'},
286  {"help", no_argument, 0, 'h'},
287  {"layout", required_argument, 0, 'L'},
288  {"restart", required_argument, 0, 0},
289  {"force-xinerama", no_argument, 0, 0},
290  {"force_xinerama", no_argument, 0, 0},
291  {"disable-signalhandler", no_argument, 0, 0},
292  {"shmlog-size", required_argument, 0, 0},
293  {"shmlog_size", required_argument, 0, 0},
294  {"get-socketpath", no_argument, 0, 0},
295  {"get_socketpath", no_argument, 0, 0},
296  {"fake_outputs", required_argument, 0, 0},
297  {"fake-outputs", required_argument, 0, 0},
298  {"force-old-config-parser-v4.4-only", no_argument, 0, 0},
299  {0, 0, 0, 0}};
300  int option_index = 0, opt;
301 
302  setlocale(LC_ALL, "");
303 
304  /* Get the RLIMIT_CORE limit at startup time to restore this before
305  * starting processes. */
306  getrlimit(RLIMIT_CORE, &original_rlimit_core);
307 
308  /* Disable output buffering to make redirects in .xsession actually useful for debugging */
309  if (!isatty(fileno(stdout)))
310  setbuf(stdout, NULL);
311 
312  srand(time(NULL));
313 
314  /* Init logging *before* initializing debug_build to guarantee early
315  * (file) logging. */
316  init_logging();
317 
318  /* On release builds, disable SHM logging by default. */
319  shmlog_size = (is_debug_build() || strstr(argv[0], "i3-with-shmlog") != NULL ? default_shmlog_size : 0);
320 
321  start_argv = argv;
322 
323  while ((opt = getopt_long(argc, argv, "c:CvmaL:hld:V", long_options, &option_index)) != -1) {
324  switch (opt) {
325  case 'a':
326  LOG("Autostart disabled using -a\n");
327  autostart = false;
328  break;
329  case 'L':
330  FREE(layout_path);
331  layout_path = sstrdup(optarg);
332  delete_layout_path = false;
333  break;
334  case 'c':
335  FREE(override_configpath);
336  override_configpath = sstrdup(optarg);
337  break;
338  case 'C':
339  LOG("Checking configuration file only (-C)\n");
340  only_check_config = true;
341  break;
342  case 'v':
343  printf("i3 version " I3_VERSION " © 2009-2014 Michael Stapelberg and contributors\n");
344  exit(EXIT_SUCCESS);
345  break;
346  case 'm':
347  printf("Binary i3 version: " I3_VERSION " © 2009-2014 Michael Stapelberg and contributors\n");
349  exit(EXIT_SUCCESS);
350  break;
351  case 'V':
352  set_verbosity(true);
353  break;
354  case 'd':
355  LOG("Enabling debug logging\n");
356  set_debug_logging(true);
357  break;
358  case 'l':
359  /* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
360  break;
361  case 0:
362  if (strcmp(long_options[option_index].name, "force-xinerama") == 0 ||
363  strcmp(long_options[option_index].name, "force_xinerama") == 0) {
364  force_xinerama = true;
365  ELOG("Using Xinerama instead of RandR. This option should be "
366  "avoided at all cost because it does not refresh the list "
367  "of screens, so you cannot configure displays at runtime. "
368  "Please check if your driver really does not support RandR "
369  "and disable this option as soon as you can.\n");
370  break;
371  } else if (strcmp(long_options[option_index].name, "disable-signalhandler") == 0) {
372  disable_signalhandler = true;
373  break;
374  } else if (strcmp(long_options[option_index].name, "get-socketpath") == 0 ||
375  strcmp(long_options[option_index].name, "get_socketpath") == 0) {
376  char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
377  if (socket_path) {
378  printf("%s\n", socket_path);
379  exit(EXIT_SUCCESS);
380  }
381 
382  exit(EXIT_FAILURE);
383  } else if (strcmp(long_options[option_index].name, "shmlog-size") == 0 ||
384  strcmp(long_options[option_index].name, "shmlog_size") == 0) {
385  shmlog_size = atoi(optarg);
386  /* Re-initialize logging immediately to get as many
387  * logmessages as possible into the SHM log. */
388  init_logging();
389  LOG("Limiting SHM log size to %d bytes\n", shmlog_size);
390  break;
391  } else if (strcmp(long_options[option_index].name, "restart") == 0) {
392  FREE(layout_path);
393  layout_path = sstrdup(optarg);
394  delete_layout_path = true;
395  break;
396  } else if (strcmp(long_options[option_index].name, "fake-outputs") == 0 ||
397  strcmp(long_options[option_index].name, "fake_outputs") == 0) {
398  LOG("Initializing fake outputs: %s\n", optarg);
399  fake_outputs = sstrdup(optarg);
400  break;
401  } else if (strcmp(long_options[option_index].name, "force-old-config-parser-v4.4-only") == 0) {
402  ELOG("You are passing --force-old-config-parser-v4.4-only, but that flag was removed by now.\n");
403  break;
404  }
405  /* fall-through */
406  default:
407  fprintf(stderr, "Usage: %s [-c configfile] [-d all] [-a] [-v] [-V] [-C]\n", argv[0]);
408  fprintf(stderr, "\n");
409  fprintf(stderr, "\t-a disable autostart ('exec' lines in config)\n");
410  fprintf(stderr, "\t-c <file> use the provided configfile instead\n");
411  fprintf(stderr, "\t-C validate configuration file and exit\n");
412  fprintf(stderr, "\t-d all enable debug output\n");
413  fprintf(stderr, "\t-L <file> path to the serialized layout during restarts\n");
414  fprintf(stderr, "\t-v display version and exit\n");
415  fprintf(stderr, "\t-V enable verbose mode\n");
416  fprintf(stderr, "\n");
417  fprintf(stderr, "\t--force-xinerama\n"
418  "\tUse Xinerama instead of RandR.\n"
419  "\tThis option should only be used if you are stuck with the\n"
420  "\told nVidia closed source driver (older than 302.17), which does\n"
421  "\tnot support RandR.\n");
422  fprintf(stderr, "\n");
423  fprintf(stderr, "\t--get-socketpath\n"
424  "\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
425  fprintf(stderr, "\n");
426  fprintf(stderr, "\t--shmlog-size <limit>\n"
427  "\tLimits the size of the i3 SHM log to <limit> bytes. Setting this\n"
428  "\tto 0 disables SHM logging entirely.\n"
429  "\tThe default is %d bytes.\n",
430  shmlog_size);
431  fprintf(stderr, "\n");
432  fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
433  "to send to a currently running i3 (like i3-msg). This allows you to\n"
434  "use nice and logical commands, such as:\n"
435  "\n"
436  "\ti3 border none\n"
437  "\ti3 floating toggle\n"
438  "\ti3 kill window\n"
439  "\n");
440  exit(EXIT_FAILURE);
441  }
442  }
443 
444  /* If the user passes more arguments, we act like i3-msg would: Just send
445  * the arguments as an IPC message to i3. This allows for nice semantic
446  * commands such as 'i3 border none'. */
447  if (!only_check_config && optind < argc) {
448  /* We enable verbose mode so that the user knows what’s going on.
449  * This should make it easier to find mistakes when the user passes
450  * arguments by mistake. */
451  set_verbosity(true);
452 
453  LOG("Additional arguments passed. Sending them as a command to i3.\n");
454  char *payload = NULL;
455  while (optind < argc) {
456  if (!payload) {
457  payload = sstrdup(argv[optind]);
458  } else {
459  char *both;
460  sasprintf(&both, "%s %s", payload, argv[optind]);
461  free(payload);
462  payload = both;
463  }
464  optind++;
465  }
466  DLOG("Command is: %s (%zd bytes)\n", payload, strlen(payload));
467  char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
468  if (!socket_path) {
469  ELOG("Could not get i3 IPC socket path\n");
470  return 1;
471  }
472 
473  int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
474  if (sockfd == -1)
475  err(EXIT_FAILURE, "Could not create socket");
476 
477  struct sockaddr_un addr;
478  memset(&addr, 0, sizeof(struct sockaddr_un));
479  addr.sun_family = AF_LOCAL;
480  strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
481  if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
482  err(EXIT_FAILURE, "Could not connect to i3");
483 
484  if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_COMMAND,
485  (uint8_t *)payload) == -1)
486  err(EXIT_FAILURE, "IPC: write()");
487 
488  uint32_t reply_length;
489  uint32_t reply_type;
490  uint8_t *reply;
491  int ret;
492  if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
493  if (ret == -1)
494  err(EXIT_FAILURE, "IPC: read()");
495  return 1;
496  }
497  if (reply_type != I3_IPC_MESSAGE_TYPE_COMMAND)
498  errx(EXIT_FAILURE, "IPC: received reply of type %d but expected %d (COMMAND)", reply_type, I3_IPC_MESSAGE_TYPE_COMMAND);
499  printf("%.*s\n", reply_length, reply);
500  return 0;
501  }
502 
503  /* Enable logging to handle the case when the user did not specify --shmlog-size */
504  init_logging();
505 
506  /* Try to enable core dumps by default when running a debug build */
507  if (is_debug_build()) {
508  struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
509  setrlimit(RLIMIT_CORE, &limit);
510 
511  /* The following code is helpful, but not required. We thus don’t pay
512  * much attention to error handling, non-linux or other edge cases. */
513  LOG("CORE DUMPS: You are running a development version of i3, so coredumps were automatically enabled (ulimit -c unlimited).\n");
514  size_t cwd_size = 1024;
515  char *cwd = smalloc(cwd_size);
516  char *cwd_ret;
517  while ((cwd_ret = getcwd(cwd, cwd_size)) == NULL && errno == ERANGE) {
518  cwd_size = cwd_size * 2;
519  cwd = srealloc(cwd, cwd_size);
520  }
521  if (cwd_ret != NULL)
522  LOG("CORE DUMPS: Your current working directory is \"%s\".\n", cwd);
523  int patternfd;
524  if ((patternfd = open("/proc/sys/kernel/core_pattern", O_RDONLY)) >= 0) {
525  memset(cwd, '\0', cwd_size);
526  if (read(patternfd, cwd, cwd_size) > 0)
527  /* a trailing newline is included in cwd */
528  LOG("CORE DUMPS: Your core_pattern is: %s", cwd);
529  close(patternfd);
530  }
531  free(cwd);
532  }
533 
534  LOG("i3 " I3_VERSION " starting\n");
535 
536  conn = xcb_connect(NULL, &conn_screen);
537  if (xcb_connection_has_error(conn))
538  errx(EXIT_FAILURE, "Cannot open display\n");
539 
540  sndisplay = sn_xcb_display_new(conn, NULL, NULL);
541 
542  /* Initialize the libev event loop. This needs to be done before loading
543  * the config file because the parser will install an ev_child watcher
544  * for the nagbar when config errors are found. */
545  main_loop = EV_DEFAULT;
546  if (main_loop == NULL)
547  die("Could not initialize libev. Bad LIBEV_FLAGS?\n");
548 
549  root_screen = xcb_aux_get_screen(conn, conn_screen);
550  root = root_screen->root;
551 
552  /* By default, we use the same depth and visual as the root window, which
553  * usually is TrueColor (24 bit depth) and the corresponding visual.
554  * However, we also check if a 32 bit depth and visual are available (for
555  * transparency) and use it if so. */
556  root_depth = root_screen->root_depth;
557  visual_id = root_screen->root_visual;
558  colormap = root_screen->default_colormap;
559 
560  DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
561 
562  xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
563  xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
564 
565  load_configuration(conn, override_configpath, false);
566  if (only_check_config) {
567  LOG("Done checking configuration file. Exiting.\n");
568  exit(0);
569  }
570 
571  if (config.ipc_socket_path == NULL) {
572  /* Fall back to a file name in /tmp/ based on the PID */
573  if ((config.ipc_socket_path = getenv("I3SOCK")) == NULL)
575  else
577  }
578 
579  xcb_void_cookie_t cookie;
580  cookie = xcb_change_window_attributes_checked(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]) {ROOT_EVENT_MASK});
581  check_error(conn, cookie, "Another window manager seems to be running");
582 
583  xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
584  if (greply == NULL) {
585  ELOG("Could not get geometry of the root window, exiting\n");
586  return 1;
587  }
588  DLOG("root geometry reply: (%d, %d) %d x %d\n", greply->x, greply->y, greply->width, greply->height);
589 
590 /* Place requests for the atoms we need as soon as possible */
591 #define xmacro(atom) \
592  xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
593 #include "atoms.xmacro"
594 #undef xmacro
595 
596  /* Initialize the Xlib connection */
597  xlibdpy = xkbdpy = XOpenDisplay(NULL);
598 
599  /* Try to load the X cursors and initialize the XKB extension */
600  if (xlibdpy == NULL) {
601  ELOG("ERROR: XOpenDisplay() failed, disabling libXcursor/XKB support\n");
602  xcursor_supported = false;
603  xkb_supported = false;
604  } else if (fcntl(ConnectionNumber(xlibdpy), F_SETFD, FD_CLOEXEC) == -1) {
605  ELOG("Could not set FD_CLOEXEC on xkbdpy\n");
606  return 1;
607  } else {
609  /*init_xkb();*/
610  }
611 
612  /* Set a cursor for the root window (otherwise the root window will show no
613  cursor until the first client is launched). */
614  if (xcursor_supported)
616  else
618 
619  if (xkb_supported) {
620  int errBase,
621  major = XkbMajorVersion,
622  minor = XkbMinorVersion;
623 
624  if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
625  fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
626  return 1;
627  }
628 
629  int i1;
630  if (!XkbQueryExtension(xkbdpy, &i1, &xkb_event_base, &errBase, &major, &minor)) {
631  fprintf(stderr, "XKB not supported by X-server\n");
632  xkb_supported = false;
633  }
634  /* end of ugliness */
635 
636  if (xkb_supported && !XkbSelectEvents(xkbdpy, XkbUseCoreKbd, XkbMapNotifyMask | XkbStateNotifyMask, XkbMapNotifyMask | XkbStateNotifyMask)) {
637  fprintf(stderr, "Could not set XKB event mask\n");
638  return 1;
639  }
640  }
641 
642  restore_connect();
643 
644 /* Setup NetWM atoms */
645 #define xmacro(name) \
646  do { \
647  xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
648  if (!reply) { \
649  ELOG("Could not get atom " #name "\n"); \
650  exit(-1); \
651  } \
652  A_##name = reply->atom; \
653  free(reply); \
654  } while (0);
655 #include "atoms.xmacro"
656 #undef xmacro
657 
659 
661 
662  keysyms = xcb_key_symbols_alloc(conn);
663 
665 
667  grab_all_keys(conn, false);
668 
669  bool needs_tree_init = true;
670  if (layout_path) {
671  LOG("Trying to restore the layout from %s...", layout_path);
672  needs_tree_init = !tree_restore(layout_path, greply);
673  if (delete_layout_path) {
674  unlink(layout_path);
675  const char *dir = dirname(layout_path);
676  /* possibly fails with ENOTEMPTY if there are files (or
677  * sockets) left. */
678  rmdir(dir);
679  }
680  free(layout_path);
681  }
682  if (needs_tree_init)
683  tree_init(greply);
684 
685  free(greply);
686 
687  /* Setup fake outputs for testing */
688  if (fake_outputs == NULL && config.fake_outputs != NULL)
689  fake_outputs = config.fake_outputs;
690 
691  if (fake_outputs != NULL) {
692  fake_outputs_init(fake_outputs);
693  FREE(fake_outputs);
694  config.fake_outputs = NULL;
695  } else if (force_xinerama || config.force_xinerama) {
696  /* Force Xinerama (for drivers which don't support RandR yet, esp. the
697  * nVidia binary graphics driver), when specified either in the config
698  * file or on command-line */
699  xinerama_init();
700  } else {
701  DLOG("Checking for XRandR...\n");
703  }
704 
706 
707  xcb_query_pointer_reply_t *pointerreply;
708  Output *output = NULL;
709  if (!(pointerreply = xcb_query_pointer_reply(conn, pointercookie, NULL))) {
710  ELOG("Could not query pointer position, using first screen\n");
711  } else {
712  DLOG("Pointer at %d, %d\n", pointerreply->root_x, pointerreply->root_y);
713  output = get_output_containing(pointerreply->root_x, pointerreply->root_y);
714  if (!output) {
715  ELOG("ERROR: No screen at (%d, %d), starting on the first screen\n",
716  pointerreply->root_x, pointerreply->root_y);
717  output = get_first_output();
718  }
719 
721  }
722 
723  tree_render();
724 
725  /* Create the UNIX domain socket for IPC */
726  int ipc_socket = ipc_create_socket(config.ipc_socket_path);
727  if (ipc_socket == -1) {
728  ELOG("Could not create the IPC socket, IPC disabled\n");
729  } else {
730  struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
731  ev_io_init(ipc_io, ipc_new_client, ipc_socket, EV_READ);
732  ev_io_start(main_loop, ipc_io);
733  }
734 
735  /* Also handle the UNIX domain sockets passed via socket activation. The
736  * parameter 1 means "remove the environment variables", we don’t want to
737  * pass these to child processes. */
739  if (listen_fds < 0)
740  ELOG("socket activation: Error in sd_listen_fds\n");
741  else if (listen_fds == 0)
742  DLOG("socket activation: no sockets passed\n");
743  else {
744  int flags;
745  for (int fd = SD_LISTEN_FDS_START;
747  fd++) {
748  DLOG("socket activation: also listening on fd %d\n", fd);
749 
750  /* sd_listen_fds() enables FD_CLOEXEC by default.
751  * However, we need to keep the file descriptors open for in-place
752  * restarting, therefore we explicitly disable FD_CLOEXEC. */
753  if ((flags = fcntl(fd, F_GETFD)) < 0 ||
754  fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
755  ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd);
756  }
757 
758  struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
759  ev_io_init(ipc_io, ipc_new_client, fd, EV_READ);
760  ev_io_start(main_loop, ipc_io);
761  }
762  }
763 
764  /* Set up i3 specific atoms like I3_SOCKET_PATH and I3_CONFIG_PATH */
765  x_set_i3_atoms();
767 
768  /* Set the _NET_CURRENT_DESKTOP property. */
770 
771  struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io));
772  struct ev_io *xkb = scalloc(sizeof(struct ev_io));
773  xcb_check = scalloc(sizeof(struct ev_check));
774  struct ev_prepare *xcb_prepare = scalloc(sizeof(struct ev_prepare));
775 
776  ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
777  ev_io_start(main_loop, xcb_watcher);
778 
779  if (xkb_supported) {
780  ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
781  ev_io_start(main_loop, xkb);
782 
783  /* Flush the buffer so that libev can properly get new events */
784  XFlush(xkbdpy);
785  }
786 
787  ev_check_init(xcb_check, xcb_check_cb);
788  ev_check_start(main_loop, xcb_check);
789 
790  ev_prepare_init(xcb_prepare, xcb_prepare_cb);
791  ev_prepare_start(main_loop, xcb_prepare);
792 
793  xcb_flush(conn);
794 
795  /* What follows is a fugly consequence of X11 protocol race conditions like
796  * the following: In an i3 in-place restart, i3 will reparent all windows
797  * to the root window, then exec() itself. In the new process, it calls
798  * manage_existing_windows. However, in case any application sent a
799  * generated UnmapNotify message to the WM (as GIMP does), this message
800  * will be handled by i3 *after* managing the window, thus i3 thinks the
801  * window just closed itself. In reality, the message was sent in the time
802  * period where i3 wasn’t running yet.
803  *
804  * To prevent this, we grab the server (disables processing of any other
805  * connections), then discard all pending events (since we didn’t do
806  * anything, there cannot be any meaningful responses), then ungrab the
807  * server. */
808  xcb_grab_server(conn);
809  {
810  xcb_aux_sync(conn);
811  xcb_generic_event_t *event;
812  while ((event = xcb_poll_for_event(conn)) != NULL) {
813  if (event->response_type == 0) {
814  free(event);
815  continue;
816  }
817 
818  /* Strip off the highest bit (set if the event is generated) */
819  int type = (event->response_type & 0x7F);
820 
821  /* We still need to handle MapRequests which are sent in the
822  * timespan starting from when we register as a window manager and
823  * this piece of code which drops events. */
824  if (type == XCB_MAP_REQUEST)
825  handle_event(type, event);
826 
827  free(event);
828  }
830  }
831  xcb_ungrab_server(conn);
832 
833  if (autostart) {
834  LOG("This is not an in-place restart, copying root window contents to a pixmap\n");
835  xcb_screen_t *root = xcb_aux_get_screen(conn, conn_screen);
836  uint16_t width = root->width_in_pixels;
837  uint16_t height = root->height_in_pixels;
838  xcb_pixmap_t pixmap = xcb_generate_id(conn);
839  xcb_gcontext_t gc = xcb_generate_id(conn);
840 
841  xcb_create_pixmap(conn, root->root_depth, pixmap, root->root, width, height);
842 
843  xcb_create_gc(conn, gc, root->root,
844  XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FILL_STYLE | XCB_GC_SUBWINDOW_MODE,
845  (uint32_t[]) {XCB_GX_COPY, ~0, XCB_FILL_STYLE_SOLID, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS});
846 
847  xcb_copy_area(conn, root->root, pixmap, gc, 0, 0, 0, 0, width, height);
848  xcb_change_window_attributes_checked(conn, root->root, XCB_CW_BACK_PIXMAP, (uint32_t[]) {pixmap});
849  xcb_flush(conn);
850  xcb_free_gc(conn, gc);
851  xcb_free_pixmap(conn, pixmap);
852  }
853 
854  struct sigaction action;
855 
856  action.sa_sigaction = handle_signal;
857  action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
858  sigemptyset(&action.sa_mask);
859 
860  if (!disable_signalhandler)
862  else {
863  /* Catch all signals with default action "Core", see signal(7) */
864  if (sigaction(SIGQUIT, &action, NULL) == -1 ||
865  sigaction(SIGILL, &action, NULL) == -1 ||
866  sigaction(SIGABRT, &action, NULL) == -1 ||
867  sigaction(SIGFPE, &action, NULL) == -1 ||
868  sigaction(SIGSEGV, &action, NULL) == -1)
869  ELOG("Could not setup signal handler");
870  }
871 
872  /* Catch all signals with default action "Term", see signal(7) */
873  if (sigaction(SIGHUP, &action, NULL) == -1 ||
874  sigaction(SIGINT, &action, NULL) == -1 ||
875  sigaction(SIGALRM, &action, NULL) == -1 ||
876  sigaction(SIGUSR1, &action, NULL) == -1 ||
877  sigaction(SIGUSR2, &action, NULL) == -1)
878  ELOG("Could not setup signal handler");
879 
880  /* Ignore SIGPIPE to survive errors when an IPC client disconnects
881  * while we are sending him a message */
882  signal(SIGPIPE, SIG_IGN);
883 
884  /* Autostarting exec-lines */
885  if (autostart) {
886  struct Autostart *exec;
888  LOG("auto-starting %s\n", exec->command);
890  }
891  }
892 
893  /* Autostarting exec_always-lines */
894  struct Autostart *exec_always;
896  LOG("auto-starting (always!) %s\n", exec_always->command);
897  start_application(exec_always->command, exec_always->no_startup_id);
898  }
899 
900  /* Start i3bar processes for all configured bars */
901  Barconfig *barconfig;
902  TAILQ_FOREACH (barconfig, &barconfigs, configs) {
903  char *command = NULL;
904  sasprintf(&command, "%s --bar_id=%s --socket=\"%s\"",
905  barconfig->i3bar_command ? barconfig->i3bar_command : "i3bar",
906  barconfig->id, current_socketpath);
907  LOG("Starting bar process: %s\n", command);
908  start_application(command, true);
909  free(command);
910  }
911 
912  /* Make sure to destroy the event loop to invoke the cleeanup callbacks
913  * when calling exit() */
914  atexit(i3_exit);
915 
916  ev_loop(main_loop, 0);
917 }
#define SD_LISTEN_FDS_START
Definition: sd-daemon.h:102
struct reservedpx __attribute__
bool is_debug_build() __attribute__((const ))
Returns true if this version of i3 is a debug build (anything which is not a release version)...
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
int sd_listen_fds(int unset_environment)
Definition: sd-daemon.c:47
#define XCB_NUM_LOCK
Definition: xcb.h:27
void tree_render(void)
Renders the tree, that is rendering all outputs using render_con() and pushing the changes to X11 usi...
Definition: tree.c:507
int listen_fds
The number of file descriptors passed via socket activation.
Definition: main.c:33
char * get_process_filename(const char *prefix)
Returns the name of a temporary file with the specified prefix.
uint32_t height
Definition: data.h:33
Config config
Definition: config.c:19
xcb_connection_t * conn
Definition: main.c:47
#define ROOT_EVENT_MASK
Definition: xcb.h:47
SnDisplay * sndisplay
Definition: main.c:52
xcb_visualid_t visual_id
Definition: main.c:66
char ** start_argv
Definition: main.c:45
#define LOG(fmt,...)
Definition: libi3.h:76
void load_configuration(xcb_connection_t *conn, const char *override_configpath, bool reload)
Reads the configuration from ~/.i3/config or /etc/i3/config if not found.
Definition: config.c:129
void xinerama_init(void)
We have just established a connection to the X server and need the initial Xinerama information to se...
Definition: xinerama.c:95
void translate_keysyms(void)
Translates keysymbols to keycodes for all bindings which use keysyms.
Definition: bindings.c:242
Con * con_descend_focused(Con *con)
Returns the focused con inside this client, descending the tree as far as possible.
Definition: con.c:983
char * fake_outputs
Overwrites output detection (for testing), see src/fake_outputs.c.
Definition: config.h:155
xcb_screen_t * root_screen
Definition: main.c:59
static void xcb_got_event(EV_P_ struct ev_io *w, int revents)
Definition: main.c:109
struct ev_loop * main_loop
Definition: main.c:69
uint32_t width
Definition: data.h:32
xcb_timestamp_t last_timestamp
The last timestamp we got from X11 (timestamps are included in some events and are used for some thin...
Definition: main.c:57
char * shmlogname
Definition: log.c:44
int xkb_current_group
Definition: main.c:41
An Output is a physical output on your graphics driver.
Definition: data.h:301
int ipc_recv_message(int sockfd, uint32_t *message_type, uint32_t *reply_length, uint8_t **reply)
Reads a message from the given socket file descriptor and stores its length (reply_length) as well as...
Display * xkbdpy
Definition: main.c:74
void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch)
Grab the bound keys (tell X to send us keypress events for those keycodes)
Definition: bindings.c:105
void display_running_version(void)
Connects to i3 to find out the currently running version.
bool xcursor_supported
Definition: main.c:96
void set_verbosity(bool _verbose)
Set verbosity of i3.
Definition: log.c:185
static void handle_signal(int sig, siginfo_t *info, void *data)
Definition: main.c:261
#define DLOG(fmt,...)
Definition: libi3.h:86
void manage_existing_windows(xcb_window_t root)
Go through all existing windows (if the window manager is restarted) and manage them.
Definition: manage.c:21
char * root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, int screen)
Try to get the contents of the given atom (for example I3_SOCKET_PATH) from the X11 root window and r...
static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents)
Definition: main.c:117
static xcb_pixmap_t pixmap
Definition: sighandler.c:28
xcb_colormap_t colormap
Definition: main.c:67
int sasprintf(char **strp, const char *fmt,...)
Safe-wrapper around asprintf which exits if it returns -1 (meaning that there is no more memory avail...
int ipc_create_socket(const char *filename)
Creates the UNIX domain socket at the given path, sets it to non-blocking mode, bind()s and listen()s...
Definition: ipc.c:1007
uint8_t root_depth
Definition: main.c:65
bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry)
Loads tree from ~/.i3/_restart.json (used for in-place restarts).
Definition: tree.c:68
#define die(...)
Definition: util.h:17
int shmlog_size
Definition: log.c:47
Con * focused
Definition: tree.c:15
Con * con
Pointer to the Con which represents this output.
Definition: data.h:319
void ewmh_update_workarea(void)
i3 currently does not support _NET_WORKAREA, because it does not correspond to i3’s concept of worksp...
Definition: ewmh.c:70
char * id
Automatically generated ID for this bar config.
Definition: config.h:226
void main_set_x11_cb(bool enable)
Enable or disable the main X11 event handling function.
Definition: main.c:157
bool event_is_ignored(const int sequence, const int response_type)
Checks if the given sequence is ignored and returns true if so.
Definition: handlers.c:52
int randr_base
Definition: handlers.c:23
void ewmh_update_current_desktop(void)
Updates _NET_CURRENT_DESKTOP with the current desktop number.
Definition: ewmh.c:21
struct autostarts_head autostarts
Definition: main.c:83
char * ipc_socket_path
Definition: config.h:94
bool no_startup_id
no_startup_id flag for start_application().
Definition: data.h:289
bool only_check_config
Definition: main.c:102
void con_focus(Con *con)
Sets input focus to the given container.
Definition: con.c:213
void xcursor_set_root_cursor(int cursor_id)
Sets the cursor of the root window to the &#39;pointer&#39; cursor.
Definition: xcursor.c:57
void setup_signal_handler(void)
Setup signal handlers to safely handle SIGSEGV and SIGFPE.
Definition: sighandler.c:311
int ipc_send_message(int sockfd, const uint32_t message_size, const uint32_t message_type, const uint8_t *payload)
Formats a message (payload) of the given size and type and sends it to i3 via the given socket file d...
Output * get_first_output(void)
Returns the first output which is active.
Definition: randr.c:65
static void i3_exit(void)
Definition: main.c:240
struct assignments_head assignments
Definition: main.c:89
void fake_outputs_init(const char *output_spec)
Creates outputs according to the given specification.
Definition: fake_outputs.c:37
const int default_shmlog_size
Definition: main.c:77
void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_message)
Checks a generic cookie for errors and quits with the given message if there was an error...
Definition: util.c:153
void ungrab_all_keys(xcb_connection_t *conn)
Ungrabs all keys, to be called before re-grabbing the keys because of a mapping_notify event or a con...
Definition: config.c:28
char * i3bar_command
Command that should be run to execute i3bar, give a full path if i3bar is not in your $PATH...
Definition: config.h:267
void ewmh_setup_hints(void)
Set up the EWMH hints on the root window.
Definition: ewmh.c:110
void xcursor_load_cursors(void)
Definition: xcursor.c:28
#define ELOG(fmt,...)
Definition: libi3.h:81
void randr_init(int *event_base)
We have just established a connection to the X server and need the initial XRandR information to setu...
Definition: randr.c:822
unsigned int xcb_numlock_mask
Definition: xcb.c:14
A &#39;Con&#39; represents everything from the X11 root window down to a single X11 window.
Definition: data.h:479
void xcb_set_root_cursor(int cursor)
Set the cursor of the root window to the given cursor id.
Definition: xcb.c:194
Display * xlibdpy
Definition: main.c:74
void * scalloc(size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
struct bindings_head * bindings
Definition: main.c:80
char * current_socketpath
Definition: ipc.c:23
bool xkb_supported
Definition: main.c:97
uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols)
All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol...
void scratchpad_fix_resolution(void)
When starting i3 initially (and after each change to the connected outputs), this function fixes the ...
Definition: scratchpad.c:251
bool force_xinerama
By default, use the RandR API for multi-monitor setups.
Definition: config.h:152
Output * get_output_containing(unsigned int x, unsigned int y)
Returns the active (!) output which contains the coordinates x, y or NULL if there is no output which...
Definition: randr.c:80
xcb_window_t root
Definition: main.c:60
void tree_init(xcb_get_geometry_reply_t *geometry)
Initializes the tree by creating the root node, adding all RandR outputs to the tree (that means rand...
Definition: tree.c:115
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:311
char * command
Command, like in command mode.
Definition: data.h:286
static void xcb_check_cb(EV_P_ ev_check *w, int revents)
Definition: main.c:126
void ipc_new_client(EV_P_ struct ev_io *w, int revents)
Handler for activity on the listening socket, meaning that a new client has just connected and we sho...
Definition: ipc.c:973
struct barconfig_head barconfigs
Definition: config.c:21
void init_logging(void)
Initializes logging by creating an error logfile in /tmp (or XDG_RUNTIME_DIR, see get_process_filenam...
Definition: log.c:81
int main(int argc, char *argv[])
Definition: main.c:268
Con * output_get_content(Con *output)
Returns the output container below the given output container.
Definition: output.c:18
void start_application(const char *command, bool no_startup_id)
Starts the given application by passing it through a shell.
Definition: startup.c:133
void * smalloc(size_t size)
Safe-wrapper around malloc which exits if malloc returns NULL (meaning that there is no more memory a...
void x_set_i3_atoms(void)
Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
Definition: x.c:1126
xcb_key_symbols_t * keysyms
Definition: main.c:71
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:334
void restore_connect(void)
Opens a separate connection to X11 for placeholder windows when restoring layouts.
static struct ev_check * xcb_check
Definition: main.c:37
void * srealloc(void *ptr, size_t size)
Safe-wrapper around realloc which exits if realloc returns NULL (meaning that there is no more memory...
Holds the status bar configuration (i3bar).
Definition: config.h:223
struct rlimit original_rlimit_core
The original value of RLIMIT_CORE when i3 was started.
Definition: main.c:30
#define FREE(pointer)
Definition: util.h:46
struct autostarts_always_head autostarts_always
Definition: main.c:86
void property_handlers_init(void)
Sets the appropriate atoms for the property handlers after the atoms were received from X11...
Definition: handlers.c:1073
Holds a command specified by either an:
Definition: data.h:284
static int xkb_event_base
Definition: main.c:39
static void xkb_got_event(EV_P_ struct ev_io *w, int revents)
Definition: main.c:174
struct ws_assignments_head ws_assignments
Definition: main.c:93
void set_debug_logging(const bool _debug_logging)
Set debug logging.
Definition: log.c:201
void handle_event(int type, xcb_generic_event_t *event)
Takes an xcb_generic_event_t and calls the appropriate handler, based on the event type...
Definition: handlers.c:1117
int conn_screen
Definition: main.c:49