int main(int argc, char *argv[]) { struct sigaction act; if(!(display = XOpenDisplay(DISPLAY))){ LOG("BARE: cannot open display! Ending session.\n"); return -1; } if((root = DefaultRootWindow(display))) { XSetWindowBackground(display, root, BlackPixel(display, XDefaultScreen(display))); XClearWindow(display, root); } else { LOG("BARE: cannot get root window! Ending session.\n"); return -1; } if((screen = DefaultScreenOfDisplay(display))) { SCREEN_WIDTH = XWidthOfScreen(screen); SCREEN_HEIGHT = XHeightOfScreen(screen); LOG("Screen: %d x %d\n", SCREEN_WIDTH, SCREEN_HEIGHT); } else { LOG("BARE: cannot get screen! Ending session.\n"); return -1; } selected = root; fontstruct = XLoadQueryFont(display, FONT); if (!fontstruct) { LOG("Couldn't find font \"%s\", loading default\n", FONT); fontstruct = XLoadQueryFont(display, "-*-fixed-medium-r-*-*-12-*-*-*-*-*-iso8859-1"); if (!fontstruct) { LOG("Couldn't load default fixed font. Something is seriouslly wrong. Ending session.\n"); return -1; } } XDefineCursor(display, selected, (XCreateFontCursor(display, CURSOR))); grab_keyboard(); XSelectInput(display, root, SubstructureNotifyMask | SubstructureRedirectMask | KeyPressMask); BARE_colormap = DefaultColormap(display, 0); init_gc(); message("Welcome to Bare WM v%s", VERSION); act.sa_handler = sighandler; sigemptyset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP | SA_RESTART ; sigaction(SIGCHLD, &act, NULL); main_loop(); XFree(BARE_GC); XFree(BARE_SELECTEDFG_GC); XCloseDisplay(display); return 0; }
/** * win: The window that changed state * event: The event that triggered it * data: ignored * * Depending on the state it will grab the keyboard or ungrab it. * * Returns FALSE **/ static gboolean window_state_changed (GtkWidget *win, GdkEventWindowState *event, gpointer data) { GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (win)); if (state & GDK_WINDOW_STATE_WITHDRAWN || state & GDK_WINDOW_STATE_ICONIFIED || state & GDK_WINDOW_STATE_FULLSCREEN || state & GDK_WINDOW_STATE_MAXIMIZED) ungrab_keyboard (win, (GdkEvent*)event, data); else grab_keyboard (win, (GdkEvent*)event, data); return FALSE; }
static bool grab_inputs(xcb_connection_t *conn, xcb_screen_t *screen) { const struct timespec req = { .tv_sec = 0, .tv_nsec = 50000, }; int tries; for (tries = 1000; tries > 0; tries--) { if (grab_keyboard(conn, screen)) { break; } nanosleep(&req, NULL); } for (tries = 1000; tries > 0; tries--) { if (grab_pointer(conn, screen)) { break; } nanosleep(&req, NULL); } return (tries > 0); } typedef struct { xcb_connection_t *conn; struct xkb_context *ctx; struct xkb_keymap *keymap; struct xkb_state *state; struct xkb_compose_state *compose_state; struct xkb_compose_table *compose_table; uint8_t first_xkb_event; int32_t device_id; } Keyboard; static void update_keymap(Keyboard *keyboard) { keyboard->keymap = xkb_x11_keymap_new_from_device(keyboard->ctx, keyboard->conn, keyboard->device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!keyboard->keymap) { fprintf(stderr, "Failed to create keymap.\n"); exit(EXIT_FAILURE); } keyboard->state = xkb_x11_state_new_from_device(keyboard->keymap, keyboard->conn, keyboard->device_id); if (!keyboard->state) { fprintf(stderr, "Failed to create keyboard state.\n"); exit(EXIT_FAILURE); } }
static gboolean actions_interactive_begin_act(ObActionsAct *act, guint state) { if (grab_keyboard()) { interactive_act = act; actions_act_ref(interactive_act); interactive_initial_state = state; /* if using focus_delay, stop the timer now so that focus doesn't go moving on us, which would kill the action */ event_halt_focus_delay(); return TRUE; } else return FALSE; }
static gboolean menu_frame_show(ObMenuFrame *self) { GList *it; /* determine if the underlying menu is already visible */ for (it = menu_frame_visible; it; it = g_list_next(it)) { ObMenuFrame *f = it->data; if (f->menu == self->menu) break; } if (!it) { if (self->menu->update_func) if (!self->menu->update_func(self, self->menu->data)) return FALSE; } if (menu_frame_visible == NULL) { /* no menus shown yet */ /* grab the pointer in such a way as to pass through "owner events" so that we can get enter/leave notifies in the menu. */ if (!grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER)) return FALSE; if (!grab_keyboard()) { ungrab_pointer(); return FALSE; } } menu_frame_update(self); menu_frame_visible = g_list_prepend(menu_frame_visible, self); if (self->menu->show_func) self->menu->show_func(self, self->menu->data); return TRUE; }
void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) { ObCursor cur; gboolean mv = (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE) || cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD)); gint up = 1; gint left = 1; if (moveresize_in_progress || !c->frame->visible || !(mv ? (c->functions & OB_CLIENT_FUNC_MOVE) : (c->functions & OB_CLIENT_FUNC_RESIZE))) return; if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT)) { cur = OB_CURSOR_NORTHWEST; up = left = -1; } else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP)) { cur = OB_CURSOR_NORTH; up = -1; } else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT)) { cur = OB_CURSOR_NORTHEAST; up = -1; } else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT)) cur = OB_CURSOR_EAST; else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)) cur = OB_CURSOR_SOUTHEAST; else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOM)) cur = OB_CURSOR_SOUTH; else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)) { cur = OB_CURSOR_SOUTHWEST; left = -1; } else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT)) { cur = OB_CURSOR_WEST; left = -1; } else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) cur = OB_CURSOR_SOUTHEAST; else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE)) cur = OB_CURSOR_MOVE; else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD)) cur = OB_CURSOR_MOVE; else g_assert_not_reached(); /* keep the pointer bounded to the screen for move/resize */ if (!grab_pointer(FALSE, TRUE, cur)) return; if (!grab_keyboard()) { ungrab_pointer(); return; } frame_end_iconify_animation(c->frame); moving = mv; moveresize_client = c; start_cx = c->area.x; start_cy = c->area.y; start_cw = c->area.width; start_ch = c->area.height; /* these adjustments for the size_inc make resizing a terminal more friendly. you essentially start the resize in the middle of the increment instead of at 0, so you have to move half an increment either way instead of a full increment one and 1 px the other. */ start_x = x - (mv ? 0 : left * c->size_inc.width / 2); start_y = y - (mv ? 0 : up * c->size_inc.height / 2); corner = cnr; button = b; key_resize_edge = -1; /* default to not putting max back on cancel */ was_max_horz = was_max_vert = FALSE; /* have to change start_cx and start_cy if going to do this.. if (corner == prop_atoms.net_wm_moveresize_move_keyboard || corner == prop_atoms.net_wm_moveresize_size_keyboard) XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0, c->area.width / 2, c->area.height / 2); */ cur_x = start_cx; cur_y = start_cy; cur_w = start_cw; cur_h = start_ch; moveresize_in_progress = TRUE; waiting_for_sync = 0; #ifdef SYNC if (config_resize_redraw && !moving && obt_display_extension_sync && moveresize_client->sync_request && moveresize_client->sync_counter && !moveresize_client->not_responding) { /* Initialize values for the resize syncing, and create an alarm for the client's xsync counter */ XSyncValue val; XSyncAlarmAttributes aa; /* set the counter to an initial value */ XSyncIntToValue(&val, 0); XSyncSetCounter(obt_display, moveresize_client->sync_counter, val); /* this will be incremented when we tell the client what we're looking for */ moveresize_client->sync_counter_value = 0; /* the next sequence we're waiting for with the alarm */ XSyncIntToValue(&val, 1); /* set an alarm on the counter */ aa.trigger.counter = moveresize_client->sync_counter; aa.trigger.wait_value = val; aa.trigger.value_type = XSyncAbsolute; aa.trigger.test_type = XSyncPositiveTransition; aa.events = True; XSyncIntToValue(&aa.delta, 1); moveresize_alarm = XSyncCreateAlarm(obt_display, XSyncCACounter | XSyncCAValue | XSyncCAValueType | XSyncCATestType | XSyncCADelta | XSyncCAEvents, &aa); } #endif }