// heavily inspired by dwm.c void client_update_wm_hints(HSClient* client) { XWMHints* wmh = XGetWMHints(g_display, client->window); if (!wmh) { return; } Window focused_window = frame_focused_window(g_cur_frame); if ((focused_window == client->window) && wmh->flags & XUrgencyHint) { // remove urgency hint if window is focused wmh->flags &= ~XUrgencyHint; XSetWMHints(g_display, client->window, wmh); } else { bool newval = (wmh->flags & XUrgencyHint) ? true : false; if (newval != client->urgent) { client->urgent = newval; char winid_str[STRING_BUF_SIZE]; snprintf(winid_str, STRING_BUF_SIZE, "0x%lx", client->window); client_setup_border(client, focused_window == client->window); hook_emit_list("urgent", client->urgent ? "on":"off", winid_str, NULL); tag_set_flags_dirty(); } } if (wmh->flags & InputHint) { client->neverfocus = !wmh->input; } else { client->neverfocus = false; } XFree(wmh); }
void set_floating(const Arg *arg){ Window win = frame_focused_window(g_cur_frame); if (!win) return; Client *client = get_client_from_window(win); if (!client) return; client_set_floating(client, !client->floating); }
unsigned long get_window_border_color(HSClient* client) { Window win = client->window; unsigned long current_border_color = (win == frame_focused_window(g_cur_frame) ? g_window_border_active_color : g_window_border_normal_color); if (client->urgent) current_border_color = g_window_border_urgent_color; return current_border_color; }
void client_close(const Arg *arg) { XEvent ev; // if there is no focus, then there is nothing to do if (!g_cur_frame) return; Window win = frame_focused_window(g_cur_frame); if (!win) return; ev.type = ClientMessage; ev.xclient.window = win; ev.xclient.message_type = g_wmatom[WMProtocols]; ev.xclient.format = 32; ev.xclient.data.l[0] = g_wmatom[WMDelete]; ev.xclient.data.l[1] = CurrentTime; XSendEvent(gDisplay, win, False, NoEventMask, &ev); }
void enternotify(XEvent* event) { XCrossingEvent *ce = &event->xcrossing; HSDebug("name is: EnterNotify, focus = %d\n", event->xcrossing.focus); if (!mouse_is_dragging() && *g_focus_follows_mouse && false == ce->focus) { HSClient* c = get_client_from_window(ce->window); HSFrame* target; if (c && c->tag->floating == false && (target = find_frame_with_window(c->tag->frame, ce->window)) && target->content.clients.layout == LAYOUT_MAX && frame_focused_window(target) != ce->window) { // don't allow focus_follows_mouse if another window would be // hidden during that focus change (which only occurs in max layout) } else { focus_window(ce->window, false, true); } } }
void client_update_wm_hints(Client* client) { XWMHints* wmh = XGetWMHints(gDisplay, client->window); if (!wmh) return; if ((frame_focused_window(g_cur_frame) == client->window) && wmh->flags & XUrgencyHint) { // remove urgency hint if window is focused wmh->flags &= ~XUrgencyHint; XSetWMHints(gDisplay, client->window, wmh); } else { bool newval = (wmh->flags & XUrgencyHint) ? true : false; if (newval != client->urgent) { client->urgent = newval; client->tag->urgent = client->urgent; } } if(wmh->flags & InputHint) client->neverfocus = !wmh->input; else client->neverfocus = false; XFree(wmh); }
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); }
/** * \brief Resolve a window description to a client or a window id * * \param str Describes the window: "" means the focused one, "urgent" * resolves to a arbitrary urgent window, "0x..." just * resolves to the given window. * \param ret_client The client pointer is stored there if ret_client is * given and the specified window is managed. * \return The resolved window id is stored there if the according * window has been found */ Window string_to_client(char* str, HSClient** ret_client) { Window win = 0; if (!strcmp(str, "")) { win = frame_focused_window(g_cur_frame); if (ret_client) { *ret_client = get_client_from_window(win); } } else if (!strcmp(str, "urgent")) { HSClient* client = get_urgent_client(); if (client) { win = client->window; } if (ret_client) { *ret_client = client; } } else if (1 == sscanf(str, "0x%lx", (long unsigned int*)&win)) { if (ret_client) { *ret_client = get_client_from_window(win); } } return win; }
void client_set_urgent_force(HSClient* client, bool state) { char winid_str[STRING_BUF_SIZE]; snprintf(winid_str, STRING_BUF_SIZE, "0x%lx", client->window); hook_emit_list("urgent", state ? "on" : "off", winid_str, NULL); client->urgent = state; client_setup_border(client, client->window == frame_focused_window(g_cur_frame)); XWMHints *wmh; if(!(wmh = XGetWMHints(g_display, client->window))) return; if (state) { wmh->flags |= XUrgencyHint; } else { wmh->flags &= ~XUrgencyHint; } XSetWMHints(g_display, client->window, wmh); XFree(wmh); // report changes to tags tag_set_flags_dirty(); }
HSClient* get_current_client() { Window win = frame_focused_window(g_cur_frame); if (!win) return NULL; return get_client_from_window(win); }