void set_fullscreen(struct client *c, bool fullscreen) { client_set_fullscreen(c, fullscreen); if (!fullscreen) monitor_arrange(c->mon); }
//------ void ewmh_handle_client_message(XEvent* event) { XWindowAttributes wa; XSetWindowAttributes swa; XClientMessageEvent* me = &(event->xclient); Client* client; if(systray_visible && me->window == gSystray->window && me->message_type == g_netatom[NetSystemTrayOP]) { // add systray icons if(me->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { if(!(client = (Client *)calloc(1, sizeof(Client)))) die("FATAL", "Could not malloc() %u bytes", sizeof(Client)); client->window = me->data.l[2]; client->next = gSystray->icon; gSystray->icon = client; XGetWindowAttributes(gDisplay, client->window, &wa); client->last_size.x = client->last_size.y = 0; client->last_size.width = wa.width; client->last_size.height = wa.height; client->float_size = client->last_size; client->floating = True; /* reuse tags field as mapped status */ client->tag = g_array_index(g_tags, Tag*, 1); updatesystrayicongeom(client, wa.width, wa.height); XAddToSaveSet(gDisplay, client->window); XSelectInput(gDisplay, client->window, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); XReparentWindow(gDisplay, client->window, gSystray->window, 0, 0); /* use parents background pixmap */ swa.background_pixmap = ParentRelative; swa.background_pixel = dc.colors[0][ColBG]; XChangeWindowAttributes(gDisplay, client->window, CWBackPixmap|CWBackPixel, &swa); updatesystray(); resizebarwin(get_current_monitor()); //update_bars(); //setclientstate(c, NormalState); long data[] = {NormalState, None}; XChangeProperty(gDisplay, client->window, g_wmatom[WMState], g_wmatom[WMState], 32, PropModeReplace, (unsigned char*)data, 2); } return; } client = get_client_from_window(me->window); if (!client) return; if(me->message_type == g_netatom[NetWmState]){ /* me->data.l[1] and [2] describe the properties to alter */ for (int prop = 1; prop <= 2; prop++) { if (me->data.l[prop] == 0) continue; if (!(g_netatom[NetWmStateFullscreen] == me->data.l[prop])) continue; bool new_value[] = { [ _NET_WM_STATE_REMOVE ] = false, [ _NET_WM_STATE_ADD ] = true, [ _NET_WM_STATE_TOGGLE ] = !client->fullscreen, }; int action = me->data.l[0]; client_set_fullscreen(client, new_value[action]); } } }
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; }