/* The GPLv3 License (GPLv3) Copyright (c) 2022 Akos Horvath This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "handler.h" #include "wm.h" #include "client.h" /* global configuration variables */ // TODO: active layout not working static int wm_xerror_handler(Wm *wm, Display *display, XErrorEvent *e) { printf("wm: Error occured. id: %d req_code: %d\n", e->error_code, e->request_code); char etext[200]; XGetErrorText(wm->display, e->error_code, etext, 200); printf("%s\n", etext); if (e->error_code == BadAccess) { wm->other_wm = true; } return 0; } static int wm_other_wm_handler(Display *display, XErrorEvent *e) { return 0; } // maybe need to handle non-normal windows too void wm_create_handler(Wm *wm, XCreateWindowEvent e) { DEBUG_PRINT("CreateNotify event\n"); // Client *nc; // Client *c; // Client t; // unsigned char *prop_ret; // unsigned long nitems_ret; // Atom type; // bool is_normal = false; // t.window = e.window; // t.m = wm->smon; // t.ws = wm->smon->selws; // t.hidden = true; // //wm_client_is_dock(&t); // /* // _NET_WM_WINDOW_TYPE_NORMAL indicates that this is a normal, // top-level window, [...] windows without _NET_WM_WINDOW_TYPE, // must be taken as this type [...] // https://specifications.freedesktop.org/wm-spec // */ // if (type == None) // is_normal = true; // // if (!is_normal) { // DEBUG_PRINT("Create handler: window %d is not normal, returning", // (int)e.window) // return; // } // nc = malloc(sizeof(Client*)); // *nc = t; // if (wm->smon->clients == NULL) { // wm->smon->clients = nc; // nc->prev = NULL; // } else { // c = wm_get_last_client(*nc->m); // //c = &wm_root; // c->next = nc; // nc->prev = c; // nc->next = NULL; // } // // XSelectInput(wm->display, nc->window, FocusChangeMask | EnterWindowMask); // DEBUG_PRINT("%d window created,", nc->window); // DEBUG_PRINT("client ws: %d\n", nc->ws); // // wm_client_is_dock(nc); // wm_mstack(nc->m); //wm_client_focus(c); } void wm_destroy_handler(Wm *wm, XDestroyWindowEvent e) { DEBUG_PRINT("DestroyNotify event\n"); Client *c; c = wm_client_find(wm, e.window); if (!c) return; wm_client_free(wm, c); } void wm_reparent_handler(XReparentEvent e) { DEBUG_PRINT("ReparentNotify event\n"); } void wm_keyrelease_handler(XKeyReleasedEvent e) { DEBUG_PRINT("KeyReleased event, code: %d\n", e.keycode) } void wm_keypress_handler(Wm *wm, XKeyPressedEvent e) { DEBUG_PRINT("KeyPressed event, code: %d\n", e.keycode) Client *c; Keybind k; DEBUG_PRINT("wm->cfg_kb_count: %d\n", wm->cfg_kb_count); for (int i = 0; i < wm->cfg_kb_count; i++) { k = wm->cfg_keybinds[i]; if (k.mask == e.state && k.keysym == XLookupKeysym(&e, 0)) { (*k.func)(wm, &k.args); } } } void wm_maprequest_handler(Wm *wm, XMapRequestEvent e) { DEBUG_PRINT("MapRequest event\n"); if (e.window == wm->root.window) { fprintf(stderr, "%s e.window was root, returning\n", __func__); return; } Client *c; if (wm_window_is_dock(wm, e.window)) { DEBUG_PRINT("%s: window is dock, mapping window\n", __func__) wm->dock = e.window; XMapWindow(wm->display, e.window); return; } c = wm_client_find(wm, e.window); if (c) { DEBUG_PRINT("%s: client found, mapping window\n", __func__) XMapWindow(wm->display, e.window); c->hidden = false; return; } DEBUG_PRINT("%s: client not found, creating client\n", __func__) c = wm_client_create(wm, e.window); RETURN_IF_NULL(c); wm_client_handle_window_types(wm, c, e); wm_layout(wm, c->m); } void wm_motion_handler(Wm *wm, XMotionEvent e) { Client *c; c = wm_client_find(wm, e.window); RETURN_IF_NULL(c) if(!wm_client_is_focused(wm, c) && wm->cfg_focus_on_motion) wm_client_focus(wm, c); } // TODO void wm_configure_handler(Wm *wm, XConfigureRequestEvent e) { DEBUG_PRINT("ConfigureRequest event\n"); Client *c; XWindowChanges wc; wc.x = e.x; wc.y = e.y; wc.width = e.width; wc.height = e.height; wc.border_width = e.border_width; wc.sibling = e.above; wc.stack_mode = e.detail; XConfigureWindow(wm->display, e.window, e.value_mask, &wc); XSync(wm->display, False); }