summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Marc Horowitz <marc@mit.edu>1992-05-07 18:37:55 +0000
committerGravatar Marc Horowitz <marc@mit.edu>1992-05-07 18:37:55 +0000
commit179851e1e1d30d7decb76a78025b5ac7d47640b6 (patch)
tree7a5dc7c51ec56a749980b9cd1a665492971a04dd
parent1ccde9351c3c5d680ab2a09b55175fa5e55ba395 (diff)
WM_DELETE_WINDOW support and unlink_gram support
-rw-r--r--zwgc/X_driver.c2
-rw-r--r--zwgc/X_gram.c15
-rw-r--r--zwgc/xcut.c38
-rw-r--r--zwgc/xrevstack.c30
-rw-r--r--zwgc/xselect.c6
-rw-r--r--zwgc/xselect.h6
6 files changed, 89 insertions, 8 deletions
diff --git a/zwgc/X_driver.c b/zwgc/X_driver.c
index ec71034..6a472e6 100644
--- a/zwgc/X_driver.c
+++ b/zwgc/X_driver.c
@@ -374,7 +374,7 @@ int X_driver_init(drivername, notfirst, pargc, argv)
xshowinit();
x_gram_init(dpy);
- xselInitAtoms(dpy);
+ xicccmInitAtoms(dpy);
mux_add_input_source(ConnectionNumber(dpy), x_get_input, dpy);
diff --git a/zwgc/X_gram.c b/zwgc/X_gram.c
index 70cf71f..93e7e3f 100644
--- a/zwgc/X_gram.c
+++ b/zwgc/X_gram.c
@@ -29,6 +29,7 @@ static char rcsid_X_gram_c[] = "$Id$";
#include "new_string.h"
#include "xrevstack.h"
#include "xerror.h"
+#include "xselect.h"
extern XContext desc_context;
extern char *app_instance;
@@ -49,6 +50,7 @@ static int reset_saver;
static int border_width = 1;
static int cursor_code = XC_sailboat;
static int set_transient;
+static int enable_delete;
static char *title_name,*icon_name;
static Cursor cursor;
static Window group_leader; /* In order to have transient windows,
@@ -71,10 +73,11 @@ static unsigned long xattributes_mask;
* and for individual zgrams:
*
* WM_TRANSIENT_FOR XSetTransientForHint(dpy,w,main_window);
+ * WM_PROTOCOLS XSetWMProtocols(dpy,w,protocols,cnt);
*/
/* set all properties defined in ICCCM. If main_window == 0,
- * XSetTransientForHint is not called.
+ * per-zgram initialization is not done.
*/
/*ARGSUSED*/
@@ -94,8 +97,12 @@ void x_set_icccm_hints(dpy,w,name,icon_name,psizehints,pwmhints,main_window)
XSetClassHint(dpy,w,&classhint);
/* in order for some wm's to iconify, the window shouldn't be transient.
e.g. Motif wm */
- if (set_transient && main_window)
- XSetTransientForHint(dpy,w,main_window);
+ if (main_window != None) {
+ if (set_transient)
+ XSetTransientForHint(dpy,w,main_window);
+ if (enable_delete)
+ XSetWMProtocols(dpy,w,&XA_WM_DELETE_WINDOW,1);
+ }
}
void x_gram_init(dpy)
@@ -130,6 +137,8 @@ void x_gram_init(dpy)
reset_saver = get_bool_resource("resetSaver", "ResetSaver", 1);
/* The default here should be 1, but mwm sucks */
set_transient = get_bool_resource("transient", "Transient", 0);
+ /* This should go away, or become default 1, after a release cycle */
+ enable_delete = get_bool_resource("enableDelete", "EnableDelete", 0);
temp = get_string_resource("borderWidth", "BorderWidth");
/* <<<>>> */
diff --git a/zwgc/xcut.c b/zwgc/xcut.c
index d9132a9..50893d6 100644
--- a/zwgc/xcut.c
+++ b/zwgc/xcut.c
@@ -169,6 +169,10 @@ void xdestroygram(dpy,w,desc_context,gram)
free(gram->text);
free(gram->blocks);
free(gram);
+
+ if (bottom_gram == NULL && unlinked == NULL) {
+ /* flush colormap here */
+ }
}
void xcut(dpy,event,desc_context)
@@ -191,6 +195,13 @@ void xcut(dpy,event,desc_context)
* Dispatch on the event type:
*/
switch(event->type) {
+ case ClientMessage:
+ if ((event->xclient.message_type == XA_WM_PROTOCOLS) &&
+ (event->xclient.format == 32) &&
+ (event->xclient.data.l[0] == XA_WM_DELETE_WINDOW))
+ xdestroygram(dpy,w,desc_context,gram);
+ break;
+
case MapNotify:
/* I don't like using the local time, but MapNotify events don't
* come with a timestamp, and there's no way to query the server
@@ -203,6 +214,10 @@ void xcut(dpy,event,desc_context)
}
break;
+ case UnmapNotify:
+ unlink_gram(gram);
+ break;
+
case LeaveNotify:
if (current_pressop == PRESSOP_KILL ||
current_pressop == PRESSOP_NUKE)
@@ -271,18 +286,37 @@ void xcut(dpy,event,desc_context)
XWindowAttributes wa;
int gx,gy;
Window temp;
+ x_gram *next;
+
+ for (gram = bottom_gram ; gram ; gram = next) {
+ XGetWindowAttributes(dpy,gram->w,&wa);
+ XTranslateCoordinates(dpy,gram->w,wa.root,0,0,&gx,&gy,
+ &temp);
- for (gram = bottom_gram ; gram ; gram = gram->above) {
+ next = gram->above;
+
+ if ((wa.map_state == IsViewable) &&
+ (gx <= event->xbutton.x_root) &&
+ (event->xbutton.x_root < gx+wa.width) &&
+ (gy <= event->xbutton.y_root) &&
+ (event->xbutton.y_root < gy+wa.height)) {
+ xdestroygram(dpy,gram->w,desc_context,gram);
+ }
+ }
+ for (gram = unlinked ; gram ; gram = next) {
XGetWindowAttributes(dpy,gram->w,&wa);
XTranslateCoordinates(dpy,gram->w,wa.root,0,0,&gx,&gy,
&temp);
+ next = gram->above;
+
if ((wa.map_state == IsViewable) &&
(gx <= event->xbutton.x_root) &&
(event->xbutton.x_root < gx+wa.width) &&
(gy <= event->xbutton.y_root) &&
- (event->xbutton.y_root < gy+wa.height))
+ (event->xbutton.y_root < gy+wa.height)) {
xdestroygram(dpy,gram->w,desc_context,gram);
+ }
}
}
current_pressop = PRESSOP_NONE;
diff --git a/zwgc/xrevstack.c b/zwgc/xrevstack.c
index e21d6a1..ae22da7 100644
--- a/zwgc/xrevstack.c
+++ b/zwgc/xrevstack.c
@@ -23,6 +23,7 @@ static char rcsid_xrevstack_c[] = "$Id$";
#include <stdio.h>
x_gram *bottom_gram = NULL;
+x_gram *unlinked = NULL;
int reverse_stack = 0;
void add_to_bottom(gram)
@@ -60,11 +61,40 @@ void delete_gram(gram)
} else {
bottom_gram = NULL;
}
+ } else if (gram == unlinked) {
+ if (gram->above) {
+ unlinked = gram->above;
+ unlinked->below = NULL;
+ } else {
+ unlinked = NULL;
+ }
} else {
if (gram->above)
gram->above->below = gram->below;
gram->below->above = gram->above;
}
+
+ /* fix up above & below pointers so that calling delete_gram
+ again is safe */
+ gram->below = gram;
+ gram->above = gram;
+}
+
+void unlink_gram(gram)
+ x_gram *gram;
+{
+ delete_gram(gram);
+
+ if (unlinked) {
+ unlinked->below = gram;
+ gram->below = NULL;
+ gram->above = unlinked;
+ unlinked = gram;
+ } else {
+ gram->above = NULL;
+ gram->below = NULL;
+ unlinked = gram;
+ }
}
#endif
diff --git a/zwgc/xselect.c b/zwgc/xselect.c
index f691514..59ed16c 100644
--- a/zwgc/xselect.c
+++ b/zwgc/xselect.c
@@ -19,6 +19,7 @@ static char rcsid_xselect_c[] = "$Id$";
#include <zephyr/mit-copyright.h>
/* xselect.c - ICCCM compliant cut-and-paste */
+/* also includes some other ICCCMisms, such as the WM_PROTOCOL handling */
#include <stdio.h>
#include <X11/Xlib.h>
@@ -31,12 +32,15 @@ extern char *getSelectedText();
static Time ownership_start = CurrentTime;
static Time ownership_end = CurrentTime;
+Atom XA_WM_PROTOCOLS,XA_WM_DELETE_WINDOW;
static Atom ZA_TARGETS,ZA_MULTIPLE,ZA_TIMESTAMP,ZA_ATOM_PAIR;
static struct _ZAtom {
Atom *patom;
char *name;
} ZAtom[] = {
+ {&XA_WM_PROTOCOLS,"WM_PROTOCOLS"},
+ {&XA_WM_DELETE_WINDOW,"WM_DELETE_WINDOW"},
{&ZA_TARGETS,"TARGETS"},
{&ZA_MULTIPLE,"MULTIPLE"},
{&ZA_TIMESTAMP,"TIMESTAMP"},
@@ -130,7 +134,7 @@ static void xselSetProperties(dpy,w,property,target,selreq)
/* global functions */
-void xselInitAtoms(dpy)
+void xicccmInitAtoms(dpy)
Display *dpy;
{
int i;
diff --git a/zwgc/xselect.h b/zwgc/xselect.h
index 96f495e..5eed8c7 100644
--- a/zwgc/xselect.h
+++ b/zwgc/xselect.h
@@ -19,10 +19,14 @@
#ifndef _XSELECT_H_
#define _XSELECT_H_
-extern void xselInitAtoms();
+extern void xicccmInitAtoms();
extern int xselGetOwnership();
extern int xselProcessSelection();
extern void xselOwnershipLost();
extern void xselGiveUpOwnership();
+extern int xwmprotoDelete();
+
+extern Atom XA_WM_PROTOCOLS,XA_WM_DELETE_WINDOW;
+
#endif