int mouse_unbind_all() { g_list_free_full(g_mouse_binds, mouse_binding_free); g_mouse_binds = NULL; HSClient* client = get_current_client(); if (client) { grab_client_buttons(client, true); } return 0; }
void window_unfocus(Window window) { HSDebug("window_unfocus NORMAL\n"); window_update_border(window, g_window_border_normal_color); HSClient* c = get_client_from_window(window); if (c) { if (c->urgent) { HSDebug("window_unfocus URGENT\n"); window_update_border(window, g_window_border_urgent_color); } grab_client_buttons(c, false); } }
void window_focus(Window window) { HSClient* client = get_client_from_window(window); assert(client != NULL); // set keyboard focus if (!client->neverfocus) { XSetInputFocus(g_display, window, RevertToPointerRoot, CurrentTime); } else client_sendevent(client, g_wmatom[WMTakeFocus]); if (window != lastfocus) { /* FIXME: this is a workaround because window_focus always is called * twice. see BUGS for more information * * only emit the hook if the focus *really* changes */ // unfocus last one window_unfocus(lastfocus); hsobject_link(g_client_object, &client->object, "focus"); ewmh_update_active_window(window); tag_update_each_focus_layer(); char* title = client ? client->title->str : "?"; char winid_str[STRING_BUF_SIZE]; snprintf(winid_str, STRING_BUF_SIZE, "0x%x", (unsigned int)window); hook_emit_list("focus_changed", winid_str, title, NULL); } // change window-colors HSDebug("window_focus ACTIVE\n"); window_update_border(window, g_window_border_active_color); lastfocus = window; /* do some specials for the max layout */ bool is_max_layout = frame_focused_window(g_cur_frame) == window && g_cur_frame->content.clients.layout == LAYOUT_MAX && get_current_monitor()->tag->floating == false; if (*g_raise_on_focus || is_max_layout) { client_raise(client); } tag_update_focus_layer(get_current_monitor()->tag); grab_client_buttons(get_client_from_window(window), true); client_set_urgent(client, false); }
int mouse_bind_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } unsigned int modifiers = 0; char* string = argv[1]; if (!string2modifiers(string, &modifiers)) { g_string_append_printf(output, "%s: Modifier \"%s\" does not exist\n", argv[0], string); return HERBST_INVALID_ARGUMENT; } // last one is the mouse button const char* last_token = strlasttoken(string, KEY_COMBI_SEPARATORS); unsigned int button = string2button(last_token); if (button == 0) { g_string_append_printf(output, "%s: Unknown mouse button \"%s\"\n", argv[0], last_token); return HERBST_INVALID_ARGUMENT; } MouseFunction function = string2mousefunction(argv[2]); if (!function) { g_string_append_printf(output, "%s: Unknown mouse action \"%s\"\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } // actually create a binding MouseBinding* mb = g_new(MouseBinding, 1); mb->button = button; mb->modifiers = modifiers; mb->action = function; mb->argc = argc - 3; mb->argv = argv_duplicate(argc - 3, argv + 3);; g_mouse_binds = g_list_prepend(g_mouse_binds, mb); HSClient* client = get_current_client(); if (client) { grab_client_buttons(client, true); } return 0; }
HSClient* manage_client(Window win) { if (is_herbstluft_window(g_display, win)) { // ignore our own window return NULL; } if (get_client_from_window(win)) { return NULL; } // init client HSClient* client = create_client(); client->pid = window_pid(g_display, win); HSMonitor* m = get_current_monitor(); // set to window properties client->window = win; client_update_title(client); unsigned int border, depth; Window root_win; int x, y; unsigned int w, h; XGetGeometry(g_display, win, &root_win, &x, &y, &w, &h, &border, &depth); // treat wanted coordinates as floating coords client->float_size.x = x; client->float_size.y = y; client->float_size.width = w; client->float_size.height = h; // apply rules HSClientChanges changes; client_changes_init(&changes, client); rules_apply(client, &changes); if (changes.tag_name) { client->tag = find_tag(changes.tag_name->str); } if (!changes.manage) { client_changes_free_members(&changes); client_destroy(client); // map it... just to be sure XMapWindow(g_display, win); return NULL; } // actually manage it g_hash_table_insert(g_clients, &(client->window), client); client->window_str = g_string_sized_new(10); g_string_printf(client->window_str, "0x%lx", win); hsobject_link(g_client_object, &client->object, client->window_str->str); // insert to layout if (!client->tag) { client->tag = m->tag; } // get events from window XSelectInput(g_display, win, CLIENT_EVENT_MASK); // insert window to the stack client->slice = slice_create_client(client); stack_insert_slice(client->tag->stack, client->slice); // insert window to the tag frame_insert_window(lookup_frame(client->tag->frame, changes.tree_index->str), win); client_update_wm_hints(client); if (changes.focus) { // give focus to window if wanted // TODO: make this faster! // WARNING: this solution needs O(C + exp(D)) time where W is the count // of clients on this tag and D is the depth of the binary layout tree frame_focus_window(client->tag->frame, win); } HSAttribute attributes[] = { ATTRIBUTE_STRING( "winid", client->window_str, ATTR_READ_ONLY), ATTRIBUTE_STRING( "title", client->title, ATTR_READ_ONLY), ATTRIBUTE_BOOL( "fullscreen", client->fullscreen, client_attr_fullscreen), ATTRIBUTE_BOOL( "pseudotile", client->pseudotile, client_attr_pseudotile), ATTRIBUTE_BOOL( "ewmhrequests", client->ewmhrequests, ATTR_ACCEPT_ALL), ATTRIBUTE_BOOL( "ewmhnotify", client->ewmhnotify, ATTR_ACCEPT_ALL), ATTRIBUTE_BOOL( "sizehints", client->sizehints, ATTR_ACCEPT_ALL), ATTRIBUTE_BOOL( "urgent", client->urgent, client_attr_urgent), ATTRIBUTE_LAST, }; hsobject_set_attributes(&client->object, attributes); ewmh_window_update_tag(client->window, client->tag); tag_set_flags_dirty(); client_set_fullscreen(client, changes.fullscreen); ewmh_update_window_state(client); // add client after setting the correct tag for the new client // this ensures a panel can read the tag property correctly at this point ewmh_add_client(client->window); HSMonitor* monitor = find_monitor_with_tag(client->tag); if (monitor) { if (monitor != get_current_monitor() && changes.focus && changes.switchtag) { monitor_set_tag(get_current_monitor(), client->tag); } // TODO: monitor_apply_layout() maybe is called twice here if it // already is called by monitor_set_tag() monitor_apply_layout(monitor); } else { if (changes.focus && changes.switchtag) { monitor_set_tag(get_current_monitor(), client->tag); } } client_changes_free_members(&changes); grab_client_buttons(client, false); return client; }