void handler_propertynotify_client(XPropertyEvent *ev) { struct client *c; if (!(c = find_client_by_window(mons, ev->window))) return; if (ev->atom == XA_WM_NAME || ev->atom == netatom(NetWMName)) { client_update_title(c); /* TODO: redraw the bar */ } else if (ev->atom == XA_WM_TRANSIENT_FOR) { /* TODO */ DBG("transient\n"); } else if (ev->atom == XA_WM_NORMAL_HINTS) { /* TODO */ DBG("normal hints\n"); } else if (ev->atom == XA_WM_HINTS) { /* TODO: check for fullscreen and floating */ client_update_wm_hints(c, c == c->mon->sel); DBG("hints\n"); } else if (ev->atom == netatom(NetWMWindowType)) { /* TODO */ client_update_window_type(c); DBG("window type\n"); } }
Client* manage_client(Window win) { if (get_client_from_window(win)) return NULL; // init client Client* client = create_client(); Monitor* m = get_current_monitor(); // set to window properties client->window = win; client_update_title(client); // apply rules int manage = 1; rules_apply(client, &manage); if (!manage) { destroy_client(client); // map it... just to be sure XMapWindow(gDisplay, win); return NULL; } unsigned int border, depth; Window root_win; int x, y; unsigned int w, h; XGetGeometry(gDisplay, win, &root_win, &x, &y, &w, &h, &border, &depth); // treat wanted coordinates as floating coords XRectangle size = client->float_size; size.width = w; size.height = h; size.x = m->rect.x + m->rect.width/2 - size.width/2; size.y = m->rect.y + m->rect.height/2 - size.height/2 + bar_height; client->float_size = size; client->last_size = size; XMoveResizeWindow(gDisplay, client->window, size.x, size.y, size.width, size.height); // actually manage it g_array_append_val(g_clients, client); XSetWindowBorderWidth(gDisplay, win, window_border_width); // insert to layout if (!client->tag) client->tag = m->tag; // get events from window client_update_wm_hints(client); XSelectInput(gDisplay, win, CLIENT_EVENT_MASK); window_grab_button(win); frame_insert_window(client->tag->frame, win); monitor_apply_layout(find_monitor_with_tag(client->tag)); return client; }
void propertynotify(XEvent* event) { // printf("name is: PropertyNotify\n"); XPropertyEvent *ev = &event->xproperty; HSClient* client; if (ev->state == PropertyNewValue) { if (is_ipc_connectable(event->xproperty.window)) { ipc_handle_connection(event->xproperty.window); } else if((client = get_client_from_window(ev->window))) { switch (ev->atom) { case XA_WM_HINTS: client_update_wm_hints(client); break; case XA_WM_NAME: client_update_title(client); break; default: break; } } } }
void propertynotify(XEvent* event) { // printf("name is: PropertyNotify\n"); XPropertyEvent *ev = &event->xproperty; HSClient* client; if (ev->state == PropertyNewValue) { if (is_ipc_connectable(event->xproperty.window)) { ipc_handle_connection(event->xproperty.window); } else if((client = get_client_from_window(ev->window))) { if (ev->atom == XA_WM_HINTS) { client_update_wm_hints(client); } else if (ev->atom == XA_WM_NORMAL_HINTS) { updatesizehints(client); HSMonitor* m = find_monitor_with_tag(client->tag); if (m) monitor_apply_layout(m); } else if (ev->atom == XA_WM_NAME || ev->atom == g_netatom[NetWmName]) { client_update_title(client); } } } }
void propertynotify(XEvent* event) { XPropertyEvent *ev = &event->xproperty; Client* client; if((client = wintosystrayicon(ev->window))) { if(ev->atom == XA_WM_NORMAL_HINTS) updatesystrayicongeom(client, client->last_size.width, client->last_size.height); resizebarwin(get_current_monitor()); updatesystray(); } if((ev->window == gRoot) && (ev->atom == XA_WM_NAME)) update_status(); if (ev->state == PropertyNewValue && (client = get_client_from_window(ev->window))) { if (ev->atom == XA_WM_HINTS) client_update_wm_hints(client); else if (ev->atom == XA_WM_NAME) client_update_title(client); } draw_bars(); }
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; }