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