Skip to content

Commit

Permalink
Fixed crash on deselection of deleted client.
Browse files Browse the repository at this point in the history
Added current_client pointer to JBWMClient.
  • Loading branch information
alisabedard committed Mar 3, 2020
1 parent b80ef67 commit 07cf843
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 72 deletions.
1 change: 1 addition & 0 deletions JBWMClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
struct JBWMScreen;
struct JBWMClient {
struct JBWMClient ** head; // store to avoid call overhead
struct JBWMClient ** current_client;
struct JBWMClient * next;
struct JBWMScreen * screen;
struct JBWMClientTitleBar tb;
Expand Down
10 changes: 4 additions & 6 deletions button_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
#include "log.h"
#include "title_bar.h"
#include "wm_state.h"
static void handle_title_bar_button(XButtonEvent * e,
struct JBWMClient * c, struct JBWMClient ** current_client)
static void handle_title_bar_button(XButtonEvent * e, struct JBWMClient * c)
{
JBWM_LOG("e->window: %d, c->title_bar: %d, e->subwindow: %d",
(int)e->window, (int)c->tb.win, (int)e->subwindow);
Expand All @@ -24,13 +23,12 @@ static void handle_title_bar_button(XButtonEvent * e,
else if (e->subwindow == c->tb.shade && !o->no_shade)
jbwm_toggle_shade(c);
else if (e->subwindow == c->tb.stick)
jbwm_toggle_sticky(c, current_client);
jbwm_toggle_sticky(c);
else
jbwm_drag(c, false);
}
__attribute__((nonnull))
void jbwm_handle_button_event(XButtonEvent * e,
struct JBWMClient * c, struct JBWMClient ** current_client)
void jbwm_handle_button_event(XButtonEvent * e, struct JBWMClient * c)
{
JBWM_LOG("jbwm_handle_button_event");
const bool fs = c->opt.fullscreen;
Expand All @@ -40,7 +38,7 @@ void jbwm_handle_button_event(XButtonEvent * e,
if (fs)
XRaiseWindow(d, c->parent);
else
handle_title_bar_button(e, c, current_client);
handle_title_bar_button(e, c);
break;
case Button2:
XLowerWindow(d, c->parent);
Expand Down
3 changes: 1 addition & 2 deletions button_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#define JBWM_BUTTON_EVENT_H
#include <X11/Xlib.h>
struct JBWMClient;
void jbwm_handle_button_event(XButtonEvent * e,
struct JBWMClient * c, struct JBWMClient ** current_client)
void jbwm_handle_button_event(XButtonEvent * e, struct JBWMClient * c)
__attribute__((nonnull));
#endif /* JBWM_BUTTON_EVENT_H */
33 changes: 15 additions & 18 deletions client.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,17 @@
#include "wm_state.h"
#include <X11/Xatom.h>
#include <X11/Xutil.h>
/* Relink client linked list to exclude c */
void jbwm_relink_client_list(struct JBWMClient * c,
struct JBWMClient ** head_client)
/* Relink c's linked list to exclude c.
* Note: As *c and *i may alias each other, use of 'restrict'
* in relink would be invalid. */
static void relink(const struct JBWMClient * c, struct JBWMClient * i)
{
struct JBWMClient *i, *prev;
for (i=*head_client, prev=NULL; i; prev=i, i=i->next) {
if (i==c) {
if (i==*head_client) { // prev == NULL in this case
*head_client=i->next;
} else {
prev->next=i->next;
}
break;
}
}
if (*(c->current_client) == c)
*(c->current_client) = NULL; // flag as invalid
if (i == c) /* c is head client. */
*(c->head) = c->next; /* removed first client. */
if (i && i->next)
relink(c, i->next != c ? i->next : (i->next = c->next));
}
void jbwm_set_client_vdesk(struct JBWMClient * restrict c, uint8_t desktop)
{
Expand All @@ -55,12 +51,11 @@ struct JBWMClient * jbwm_find_client(
return head;
}

void jbwm_toggle_sticky(struct JBWMClient * restrict c,
struct JBWMClient ** current_client)
void jbwm_toggle_sticky(struct JBWMClient * restrict c)
{
if(c){
c->opt.sticky ^= true; /* toggle */
jbwm_select_client(c,current_client);
jbwm_select_client(c);
jbwm_update_title_bar(c);
{
Display *d;
Expand All @@ -85,7 +80,9 @@ void jbwm_client_free(struct JBWMClient * c, struct JBWMClient ** head_client)
XRemoveFromSaveSet(d, w);
if(parent)
XDestroyWindow(d, parent);
jbwm_relink_client_list(c, head_client);
relink(c, *head_client);
c->screen=NULL;
c->head=NULL;
free(c);
}
void jbwm_hide_client(const struct JBWMClient * restrict c)
Expand Down
6 changes: 1 addition & 5 deletions client.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@ void jbwm_client_free(struct JBWMClient * c,
/* Get the client with input focus. */
//struct JBWMClient * jbwm_get_current_client(void);
void jbwm_hide_client(const struct JBWMClient * restrict c);
/* Relink client linked list to exclude c */
void jbwm_relink_client_list(struct JBWMClient * c,
struct JBWMClient ** head_client);
/* Move the client to the specified virtual desktop */
void jbwm_set_client_vdesk(struct JBWMClient * restrict c, uint8_t desktop);
void jbwm_toggle_sticky(struct JBWMClient * restrict c,
struct JBWMClient ** current_client);
void jbwm_toggle_sticky(struct JBWMClient * restrict c);
void jbwm_restore_client(const struct JBWMClient * restrict c);
__attribute__((pure))
/* Return the client that has specified window as either window or parent.
Expand Down
11 changes: 5 additions & 6 deletions events.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,10 @@ static void jbwm_handle_ConfigureRequest(XEvent * ev, struct JBWMClient * c)
if (c)
jbwm_move_resize(c);
}
static void jbwm_handle_EnterNotify(XEvent * ev, struct JBWMClient * c,
struct JBWMClient ** current_client)
static void jbwm_handle_EnterNotify(XEvent * ev, struct JBWMClient * c)
{
if (c && ev->xcrossing.window == c->parent)
jbwm_select_client(c, current_client);
jbwm_select_client(c);
}
static void jbwm_handle_Expose(XEvent * ev, struct JBWMClient * c)
{
Expand Down Expand Up @@ -130,10 +129,10 @@ void jbwm_events_loop(struct JBWMScreen * s, struct JBWMClient ** head_client,
break;
case ButtonPress:
if(c)
jbwm_handle_button_event(&ev.xbutton, c, current_client);
jbwm_handle_button_event(&ev.xbutton, c);
break;
case EnterNotify:
jbwm_handle_EnterNotify(&ev, c, current_client);
jbwm_handle_EnterNotify(&ev, c);
break;
case Expose:
jbwm_handle_Expose(&ev,c);
Expand All @@ -156,7 +155,7 @@ void jbwm_events_loop(struct JBWMScreen * s, struct JBWMClient ** head_client,
jbwm_handle_ColormapNotify(&ev,c);
break;
case ClientMessage:
jbwm_ewmh_handle_client_message(&ev.xclient, c, current_client);
jbwm_ewmh_handle_client_message(&ev.xclient, c);
break;
#ifdef DEBUG
default:
Expand Down
14 changes: 7 additions & 7 deletions ewmh_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ static void handle_moveresize(XClientMessageEvent * e)
l[0]: bits 0-7 idicate gravity,
l[0]: bits 8-11 use x, y, width, height, respectively
l[0]: bits 12-15 indicate the source,
*/
*/
enum {
SRC_SHIFT = 12, SRC_MASK = 3, VM_SHIFT = 8, VM_MASK = 0xf,
USER_ACTION = 2
Expand All @@ -36,10 +36,10 @@ static void handle_moveresize(XClientMessageEvent * e)
}
// returns true if handled, false if not
static bool client_specific_message(XClientMessageEvent * e,
struct JBWMClient * restrict c, struct JBWMClient ** current_client,
const Atom t)
struct JBWMClient * restrict c, const Atom t)
{
Display * d = e->display;
Display * d;
d = e->display;
jbwm_print_atom(d, t, __FILE__, __LINE__);
if (t == jbwm_atoms[JBWM_NET_WM_DESKTOP])
jbwm_set_client_vdesk(c, e->data.l[0]);
Expand All @@ -50,7 +50,7 @@ static bool client_specific_message(XClientMessageEvent * e,
} else if (t == jbwm_atoms[JBWM_NET_WM_STATE])
jbwm_ewmh_handle_wm_state_changes(e, c);
else if (t == jbwm_atoms[JBWM_NET_ACTIVE_WINDOW])
jbwm_select_client(c, current_client);
jbwm_select_client(c);
else if (t == jbwm_atoms[JBWM_NET_CLOSE_WINDOW])
jbwm_send_wm_delete(c);
else
Expand All @@ -71,11 +71,11 @@ static void debug_client_message(XClientMessageEvent * e)
#define debug_client_message(e)
#endif//JBWM_DEBUG_EWMH_STATE&&DEBUG
void jbwm_ewmh_handle_client_message(XClientMessageEvent * e,
struct JBWMClient * c, struct JBWMClient ** current_client)
struct JBWMClient * c)
{
const Atom t = e->message_type;
debug_client_message(e);
if(client_specific_message(e, c, current_client, t))
if(client_specific_message(e, c, t))
return;
if (t == jbwm_atoms[JBWM_NET_CURRENT_DESKTOP]) {
jbwm_set_vdesk(c->screen, *(c->head), e->data.l[0]);
Expand Down
2 changes: 1 addition & 1 deletion ewmh_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
#include <X11/Xlib.h>
struct JBWMClient;
void jbwm_ewmh_handle_client_message(XClientMessageEvent * e,
struct JBWMClient * c, struct JBWMClient ** current_client);
struct JBWMClient * c);
#endif//!JBWM_EWMH_CLIENT_H
5 changes: 2 additions & 3 deletions jbwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,15 @@ static Window * get_windows(Display * dpy, const Window root,
return w;
}
static void setup_clients(Display * d, struct JBWMScreen * s,
struct JBWMClient ** head_client,
struct JBWMClient ** current_client)
struct JBWMClient ** head_client, struct JBWMClient ** current_client)
{
uint16_t n;
Window * w = get_windows(d, RootWindow(d, s->id), &n);
JBWM_LOG("Started with %d clients", n);
if (w) { // Avoid segmentation fault on empty list.
while(n--)
if(check_redirect(d,w[n]))
jbwm_new_client(s,head_client, current_client,w[n]);
jbwm_new_client(s, head_client, current_client, w[n]);
XFree(w);
}
}
Expand Down
9 changes: 4 additions & 5 deletions key_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static void handle_client_key_event(struct JBWMClient ** current_client,
(c->opt.max_vert ? jbwm_set_not_vert : jbwm_set_vert)(c);
break;
case JBWM_KEY_STICK:
jbwm_toggle_sticky(c, current_client);
jbwm_toggle_sticky(c);
break;
case JBWM_KEY_MOVE:
jbwm_drag(c, false);
Expand All @@ -162,11 +162,10 @@ static void handle_client_key_event(struct JBWMClient ** current_client,
break;
}
}
static void warp_to(struct JBWMClient * restrict c,
struct JBWMClient ** current_client){
static void warp_to(struct JBWMClient * restrict c) {
point(c, 0, 0);
point(c, c->size.width-1, c->size.height-1);
jbwm_select_client(c, current_client);
jbwm_select_client(c);
}
static void next(struct JBWMClient * c,
struct JBWMClient ** current_client, uint8_t const v){
Expand All @@ -178,7 +177,7 @@ static void next(struct JBWMClient * c,
if(c->vdesk != v)
next(c, current_client, v);
else
warp_to(c, current_client);
warp_to(c);
}
}
static void cond_set_vdesk(struct JBWMClient * c,
Expand Down
16 changes: 9 additions & 7 deletions new.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ static uint8_t wm_desktop(Display * d, const Window w, int32_t vdesk)
JBWM_LOG("wm_desktop(w: %d): vdesk is %d\n", (int) w, vdesk);
return vdesk;
}
static inline uint8_t get_vdesk(struct JBWMClient * restrict c)
static inline uint8_t get_vdesk(struct JBWMClient * c)
{
return wm_desktop(c->screen->display, c->window, c->screen->vdesk);
}
__attribute__((nonnull))
static Window get_parent(struct JBWMClient * restrict c)
static Window get_parent(struct JBWMClient * c)
{
enum {
CFP = CopyFromParent,
Expand All @@ -61,7 +61,7 @@ static inline void reparent_window(Display * d, Window parent, Window window)
XReparentWindow(d, window, parent, 0, 0);
XMapWindow(d, window);
}
static void reparent(struct JBWMClient * restrict c)
static void reparent(struct JBWMClient * c)
{
JBWM_LOG("reparent()");
jbwm_new_shaped_client(c);
Expand All @@ -73,7 +73,7 @@ static void reparent(struct JBWMClient * restrict c)
static struct JBWMClient * get_JBWMClient(const Window w,
struct JBWMScreen * s, struct JBWMClient ** head_client)
{
struct JBWMClient * restrict c = calloc(1, sizeof(struct JBWMClient));
struct JBWMClient * c = calloc(1, sizeof(struct JBWMClient));
c->screen=s;
c->window=w;
c->head=head_client;
Expand All @@ -92,12 +92,14 @@ static void do_grabs(Display * d, const Window w)
}
void jbwm_new_client(struct JBWMScreen * s,
struct JBWMClient ** head_client,
struct JBWMClient ** current_client, const Window w)
struct JBWMClient ** current_client,
const Window w)
{
struct JBWMClient * restrict c = get_JBWMClient(w, s, head_client);
struct JBWMClient * c = get_JBWMClient(w, s, head_client);
JBWM_LOG("jbwm_new_client(..., w: %d)", (int)w);
/* Prepend client. */
c->next=*head_client;
c->current_client = current_client;
*head_client=c;
do_grabs(s->display, w);
jbwm_set_client_geometry(c);
Expand All @@ -106,7 +108,7 @@ void jbwm_new_client(struct JBWMScreen * s,
c->vdesk = get_vdesk(c);
jbwm_snap_client(c);
jbwm_restore_client(c);
jbwm_select_client(c, current_client);
jbwm_select_client(c);
if(c->screen->vdesk!=c->vdesk)
jbwm_hide_client(c);
}
22 changes: 12 additions & 10 deletions select.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ static void set_active_window_property(struct JBWMClient * c)
jbwm_atoms[JBWM_NET_ACTIVE_WINDOW], XA_WINDOW, 32,
PropModeReplace, (unsigned char *)&w, 1);
}
void jbwm_select_client(struct JBWMClient * c,
struct JBWMClient ** current_client)
void jbwm_select_client(struct JBWMClient * c)
{
if (!c)
return;
if (*current_client)
set_state_not_focused(*current_client);
set_border(c);
set_focused(c);
set_active_window_property(c);
*current_client=c;
struct JBWMClient ** current, * prev;
current = c->current_client;
prev = *current;
set_border(c);
set_focused(c);
set_active_window_property(c);
*current = c;
if (prev != c) {
if (prev)
set_state_not_focused(prev);
}
}

3 changes: 1 addition & 2 deletions select.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
#define JBWM_SELECT_H
struct JBWMClient;
// Set client as that receiving focus
void jbwm_select_client(struct JBWMClient * c,
struct JBWMClient **current_client);
void jbwm_select_client(struct JBWMClient * c);
#endif//!JBWM_SELECT_H

0 comments on commit 07cf843

Please sign in to comment.