The following shows the diffstat and patchsets between
ed2067b..c5cea0f^
----------------------------------------------------------------
commit c5cea0fc3def891ef2def96c8667450455d4f034
Merge: ed2067b 69a8b9c
Author: Thomas Adam <[email protected]>
Date: Thu Oct 16 15:06:48 2014 +0100
Merge branch 'branch-2_6'
Conflicts:
modules/FvwmDragWell/fvwmDragWell.c
modules/FvwmForm/ReadXServer.c
modules/FvwmIconBox/FvwmIconBox.c
modules/FvwmScript/FvwmScript.c
modules/FvwmScroll/GrabWindow.c
modules/FvwmTaskBar/FvwmTaskBar.c
modules/FvwmWharf/FvwmWharf.c
modules/FvwmWinList/FvwmWinList.c
mvwm/add_window.c
mvwm/events.c
mvwm/events.h
mvwm/move_resize.c
mvwm/mvwm.c
commit 69a8b9c837c8f6298a56a818718c5d2834872099
Merge: 98a1a35 8be89d4
Author: Thomas Adam <[email protected]>
Date: Sat Sep 20 23:55:30 2014 +0100
Merge remote-tracking branch 'cvs/branch-2_6' into branch-2_6
commit 8be89d4c9b1a7af3c8c310446b0af47c3c863f15
Author: domivogt <domivogt>
Date: Sat Sep 20 20:45:14 2014 +0000
Correct typo in NEWS.
---
NEWS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index dfb4025..52a5aec 100644
--- a/NEWS
+++ b/NEWS
@@ -22,7 +22,7 @@ Changes in stable release 2.6.6 (not released yet)
width or height value. If present, the value is a percentage
of the width or height of the EWMH working area or the EWMH
dynamic working area.
- - Fvwm is much more resilient agains applications that flood the
+ - Fvwm is much more resilient against applications that flood the
window manager with repeated events.
* New module features:
commit c01e467e10bc63fc2420cc1dbe759acda7b22629
Author: domivogt <domivogt>
Date: Sat Sep 20 20:37:15 2014 +0000
* Improve ConfigureRequest merging.
---
ChangeLog | 27 +++++
NEWS | 2 +
fvwm/events.c | 342 ++++++++++++++++++++++++++++-------------------------
fvwm/events.h | 3 +-
fvwm/ewmh_events.c | 32 ++---
5 files changed, 229 insertions(+), 177 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index bdf509e..5cef98b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * fvwm/ewmh_events.c (ewmh_RestackWindow, ewmh_MoveResizeWindow):
+ * fvwm/events.c (events_handle_configure_request):
+ (test_resizing_event):
+ (_pred_merge_cr):
+ (_cr_detect_icccm_move):
+ (HandleConfigureRequest):
+ (_handle_cr_on_client):
+ (_handle_configure_request):
+ (_handle_cr_on_unmanaged):
+ (_handle_cr_on_icon):
+ (_handle_cr_on_shaped):
+ (_handle_cr_restack):
+ (_merge_cr_moveresize):
+ Dramatically improved speed of configure request merging.
+
+ * fvwm/events.c (_handle_cr_on_client, __handle_cr_on_client):
+ (_handle_configure_request, __handle_configure_request):
+ (_handle_cr_on_unmanaged, __handle_cr_on_unmanaged):
+ (_handle_cr_on_icon, __handle_cr_on_icon):
+ (_handle_cr_on_shaped, __handle_cr_on_shaped):
+ (_handle_cr_restack, __handle_cr_restack):
+ (_cr_get_static_position, __cr_get_static_position):
+ (_cr_get_grav_position, __cr_get_grav_position):
+ (_cr_detect_icccm_move, __cr_detect_icccm_move):
+ (_merge_cr_moveresize, __merge_cr_moveresize):
+ Renamed functions
+
* libs/FEvent.c (_fev_pred_weed_if_finish):
(_fev_pred_weed_if):
Use FEV_INVALIDATE_EVENT().
diff --git a/NEWS b/NEWS
index b31ba4e..dfb4025 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,8 @@ Changes in stable release 2.6.6 (not released yet)
width or height value. If present, the value is a percentage
of the width or height of the EWMH working area or the EWMH
dynamic working area.
+ - Fvwm is much more resilient agains applications that flood the
+ window manager with repeated events.
* New module features:
diff --git a/fvwm/events.c b/fvwm/events.c
index 0c25a00..110609d 100644
--- a/fvwm/events.c
+++ b/fvwm/events.c
@@ -165,6 +165,13 @@ typedef struct
long event_mask;
} _weed_window_mask_events_arg;
+typedef struct
+{
+ Window w;
+ XEvent *last_cr_event;
+ int count;
+} _merge_cr_args;
+
/* ---------------------------- forward declarations ----------------------- */
/* ---------------------------- local variables ---------------------------- */
@@ -409,8 +416,9 @@ static Bool test_resizing_event(
return rc;
}
-static inline void __handle_cr_on_unmanaged(XConfigureRequestEvent *cre)
+static inline void _handle_cr_on_unmanaged(XEvent *e)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
XWindowChanges xwc;
unsigned long xwcm;
@@ -425,9 +433,9 @@ static inline void
__handle_cr_on_unmanaged(XConfigureRequestEvent *cre)
return;
}
-static inline void __handle_cr_on_icon(
- XConfigureRequestEvent *cre, FvwmWindow *fw)
+static inline void _handle_cr_on_icon(XEvent *e, FvwmWindow *fw)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
XWindowChanges xwc;
unsigned long xwcm;
@@ -483,7 +491,7 @@ static inline void __handle_cr_on_icon(
return;
}
-static inline void __handle_cr_on_shaped(FvwmWindow *fw)
+static inline void _handle_cr_on_shaped(FvwmWindow *fw)
{
/* suppress compiler warnings w/o shape extension */
int i = 0;
@@ -505,9 +513,10 @@ static inline void __handle_cr_on_shaped(FvwmWindow *fw)
return;
}
-static inline void __handle_cr_restack(
- int *ret_do_send_event, XConfigureRequestEvent *cre, FvwmWindow *fw)
+static inline void _handle_cr_restack(
+ int *ret_do_send_event, XEvent *e, FvwmWindow *fw)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
XWindowChanges xwc;
unsigned long xwcm;
FvwmWindow *fw2 = NULL;
@@ -605,10 +614,11 @@ static inline void __handle_cr_restack(
return;
}
-static inline void __cr_get_static_position(
- rectangle *ret_g, FvwmWindow *fw, XConfigureRequestEvent *cre,
- size_borders *b)
+static inline void _cr_get_static_position(
+ rectangle *ret_g, FvwmWindow *fw, XEvent *e, size_borders *b)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
+
if (cre->value_mask & CWX)
{
ret_g->x = cre->x - b->top_left.width;
@@ -629,10 +639,10 @@ static inline void __cr_get_static_position(
return;
}
-static inline void __cr_get_grav_position(
- rectangle *ret_g, FvwmWindow *fw, XConfigureRequestEvent *cre,
- size_borders *b)
+static inline void _cr_get_grav_position(
+ rectangle *ret_g, FvwmWindow *fw, XEvent *e, size_borders *b)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
int grav_x;
int grav_y;
@@ -659,9 +669,10 @@ static inline void __cr_get_grav_position(
/* Try to detect whether the application uses the ICCCM way of moving its
* window or the traditional way, always assuming StaticGravity. */
-static inline void __cr_detect_icccm_move(
- FvwmWindow *fw, XConfigureRequestEvent *cre, size_borders *b)
+static inline void _cr_detect_icccm_move(
+ FvwmWindow *fw, XEvent *e, size_borders *b)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
rectangle grav_g;
rectangle static_g;
rectangle dg_g;
@@ -744,8 +755,8 @@ static inline void __cr_detect_icccm_move(
}
return;
}
- __cr_get_grav_position(&grav_g, fw, cre, b);
- __cr_get_static_position(&static_g, fw, cre, b);
+ _cr_get_grav_position(&grav_g, fw, e, b);
+ _cr_get_static_position(&static_g, fw, e, b);
if (static_g.x == grav_g.x)
{
/* both methods have the same result; ignore */
@@ -911,7 +922,6 @@ static inline void __cr_detect_icccm_move(
return;
}
-#define EXPERIMENTAL_ANTI_RACE_CONDITION_CODE
/* This is not a good idea because this interferes with changes in the size
* hints of the window. However, it is impossible to be completely safe here.
* For example, if the client changes the size inc, then resizes the size of
@@ -920,141 +930,157 @@ static inline void __cr_detect_icccm_move(
* wrong one in the ConfigureRequest calculations. */
/* dv (31 Mar 2002): The code now handles these situations, so enable it
* again. */
-#ifdef EXPERIMENTAL_ANTI_RACE_CONDITION_CODE
-static inline int __merge_cr_moveresize(
- const evh_args_t *ea, XConfigureRequestEvent *cre, FvwmWindow *fw,
- size_borders *b)
+static int _pred_merge_cr(Display *display, XEvent *event, XPointer arg)
{
- int cn_count = 0;
- XEvent e;
- XConfigureRequestEvent *ecre;
- check_if_event_args args;
+ _merge_cr_args *args = (_merge_cr_args *)arg;
- args.w = cre->window;
- args.do_return_true = False;
- args.do_return_true_cr = True;
- args.cr_value_mask = CR_MOVERESIZE_MASK;
- args.ret_does_match = False;
- args.ret_type = 0;
-
- for (cn_count = 0; 1; )
+ switch (event->type)
{
- unsigned long vma;
- unsigned long vmo;
- unsigned long xm;
- unsigned long ym;
- evh_args_t ea2;
- exec_context_changes_t ecc;
+ case ConfigureRequest:
+ {
+ XConfigureRequestEvent *ecr = &event->xconfigurerequest;
+ XConfigureRequestEvent *lcr =
+ &args->last_cr_event->xconfigurerequest;
- FCheckPeekIfEvent(
- dpy, &e, test_resizing_event, (XPointer)&args);
- ecre = &e.xconfigurerequest;
- if (args.ret_does_match == False)
+ if (event->xconfigurerequest.window != args->w)
{
- break;
+ /* no match, keep looking */
+ return 0;
}
- else if (args.ret_type == PropertyNotify)
+ /* collect the size/position changes */
+ if (lcr->value_mask & CWX)
{
- /* Can't merge events with a PropertyNotify in
- * between. The event is still on the queue. */
- break;
+ ecr->x = lcr->x;
}
- else if (args.ret_type != ConfigureRequest)
+ if (lcr->value_mask & CWY)
{
- /* not good. unselected event type! */
- continue;
+ ecr->y = lcr->y;
}
- fev_sanitise_configure_request(cre);
- /* Event was not yet removed from the queue but stored in e. */
- xm = CWX | CWWidth;
- ym = CWY | CWHeight;
- vma = cre->value_mask & ecre->value_mask;
- vmo = cre->value_mask | ecre->value_mask;
- if (((vma & xm) == 0 && (vmo & xm) == xm) ||
- ((vma & ym) == 0 && (vmo & ym) == ym))
+ if (lcr->value_mask & CWWidth)
{
- /* can't merge events since location of window might
- * get screwed up. */
- break;
+ ecr->width = lcr->width;
}
- /* Finally remove the event from the queue */
- FCheckIfEvent(dpy, &e, test_resizing_event, (XPointer)&args);
- /* partially handle the event */
- ecre->value_mask &= ~args.cr_value_mask;
- ea2.exc = exc_clone_context(ea->exc, &ecc, ECC_ETRIGGER);
- HandleConfigureRequest(&ea2);
- exc_destroy_context(ea2.exc);
- /* collect the size/position changes */
- if (ecre->value_mask & CWX)
+ if (lcr->value_mask & CWHeight)
{
- cre->x = ecre->x;
+ ecr->height = lcr->height;
}
- if (ecre->value_mask & CWY)
+ if (lcr->value_mask & CWBorderWidth)
{
- cre->y = ecre->y;
+ ecr->border_width = lcr->border_width;
}
- if (ecre->value_mask & CWWidth)
+ /* add to new event and remove from old event */
+ ecr->value_mask |= (lcr->value_mask & CR_MOVERESIZE_MASK);
+ lcr->value_mask &= ~CR_MOVERESIZE_MASK;
+ if (lcr->value_mask == 0)
{
- cre->width = ecre->width;
+ /* The event has no useful contents anymore. */
+ FEV_INVALIDATE_EVENT(args->last_cr_event);
}
- if (ecre->value_mask & CWHeight)
+ args->last_cr_event = event;
+ args->count++;
+
+ /* don't drop the current event and continue weeding */
+ return 0;
+ }
+ case PropertyNotify:
+ if (
+ event->xproperty.window == args->w &&
+ event->xproperty.atom != XA_WM_NORMAL_HINTS)
{
- cre->height = ecre->height;
+ /* ConfigureRequest events cannot be merged past
+ * changes of the size hints. */
+ /* don't merge and stop weeding */
+ return 2;
}
- if (ecre->value_mask & CWBorderWidth)
+ else
{
- cre->border_width = ecre->border_width;
+ /* PropertyNotify for another window, or the changed
+ * property does not interfere with merging. */
+ /* keep looking */
+ return 0;
}
- cre->value_mask |= (ecre->value_mask & CR_MOVERESIZE_MASK);
- cn_count++;
+ default:
+ /* Other events do not interfer with merging. */
+ /* keep looking */
+ return 0;
}
-
- return cn_count;
}
+
+static inline int _merge_cr_moveresize(
+ const evh_args_t *ea, XEvent *ev, FvwmWindow *fw, size_borders *b)
+{
+ _merge_cr_args args;
+
+ memset(&args, 0, sizeof(args));
+ args.w = ev->xconfigurerequest.window;
+ args.last_cr_event = ev;
+ FWeedIfEvents(dpy, _pred_merge_cr, (XPointer)&args);
+
+#if 1 /*!!!*/
+ if (args.count > 0)
+ {
+ fprintf(stderr, "%s: merged %d cr events\n", __func__,
args.count);
+ }
#endif
+ /* use the count from the structure, not the return value of
+ * FWeedIfEvents() because the predicate has a different way of weeding
+ * and the return value is always zero. */
+ return args.count;
+}
-static inline int __handle_cr_on_client(
- int *ret_do_send_event, XConfigureRequestEvent cre,
- const evh_args_t *ea, FvwmWindow *fw, Bool force, int force_gravity)
+static inline int _handle_cr_on_client(
+ int *ret_do_send_event, XEvent *e, const evh_args_t *ea,
+ FvwmWindow *fw, Bool force, int force_gravity)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
rectangle current_g;
rectangle new_g;
rectangle d_g;
size_rect constr_dim;
size_rect oldnew_dim;
size_borders b;
- int cn_count = 0;
int gravity;
if (ea)
{
- cre = ea->exc->x.etrigger->xconfigurerequest;
+ cre = &ea->exc->x.etrigger->xconfigurerequest;
}
- if ((cre.value_mask & (CWWidth | CWHeight | CWX | CWY)) == 0)
+ if (cre->value_mask & CWBorderWidth)
+ {
+ /* for restoring */
+ fw->attr_backup.border_width = cre->border_width;
+ }
+ if ((cre->value_mask & (CWWidth | CWHeight | CWX | CWY)) == 0)
{
return 0;
}
get_window_borders(fw, &b);
-#ifdef EXPERIMENTAL_ANTI_RACE_CONDITION_CODE
/* Merge all pending ConfigureRequests for the window into a single
* event. However, we can not do this if the window uses the motion
* method autodetection because the merged event might confuse the
* detection code. */
if (ea && CR_MOTION_METHOD(fw) != CR_MOTION_METHOD_AUTO)
{
- cn_count = __merge_cr_moveresize(ea, &cre, fw, &b);
+ int count;
+
+ count = _merge_cr_moveresize(ea, e, fw, &b);
+ if (count > 0)
+ {
+ /* the event has been merged into a later one, do
+ * nothing */
+ return 0;
+ }
}
-#endif
#if 0
fprintf(stderr,
"cre: %d(%d) %d(%d) %d(%d)x%d(%d) fw 0x%08x w 0x%08x "
"ew 0x%08x '%s'\n",
- cre.x, (int)(cre.value_mask & CWX),
- cre.y, (int)(cre.value_mask & CWY),
- cre.width, (int)(cre.value_mask & CWWidth),
- cre.height, (int)(cre.value_mask & CWHeight),
- (int)FW_W_FRAME(fw), (int)FW_W(fw), (int)cre.window,
+ cre->x, (int)(cre->value_mask & CWX),
+ cre->y, (int)(cre->value_mask & CWY),
+ cre->width, (int)(cre->value_mask & CWWidth),
+ cre->height, (int)(cre->value_mask & CWHeight),
+ (int)FW_W_FRAME(fw), (int)FW_W(fw), (int)cre->window,
(fw->name.name) ? fw->name.name : "");
#endif
/* Don't modify frame_g fields before calling SetupWindow! */
@@ -1070,46 +1096,46 @@ static inline int __handle_cr_on_client(
if (!HAS_OVERRIDE_SIZE_HINTS(fw) && (fw->hints.flags & PMaxSize))
{
/* Java workaround */
- if (cre.height > fw->hints.max_height &&
+ if (cre->height > fw->hints.max_height &&
fw->hints.max_height <= BROKEN_MAXSIZE_LIMIT)
{
fw->hints.max_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT;
- cre.value_mask |= CWHeight;
+ cre->value_mask |= CWHeight;
}
- if (cre.width > fw->hints.max_width &&
+ if (cre->width > fw->hints.max_width &&
fw->hints.max_width <= BROKEN_MAXSIZE_LIMIT)
{
fw->hints.max_width = DEFAULT_MAX_MAX_WINDOW_WIDTH;
- cre.value_mask |= CWWidth;
+ cre->value_mask |= CWWidth;
}
}
if (!HAS_OVERRIDE_SIZE_HINTS(fw) && (fw->hints.flags & PMinSize))
{
- if (cre.width < fw->hints.min_width &&
+ if (cre->width < fw->hints.min_width &&
fw->hints.min_width >= BROKEN_MINSIZE_LIMIT)
{
fw->hints.min_width = 1;
- cre.value_mask |= CWWidth;
+ cre->value_mask |= CWWidth;
}
- if (cre.height < fw->hints.min_height &&
+ if (cre->height < fw->hints.min_height &&
fw->hints.min_height >= BROKEN_MINSIZE_LIMIT)
{
fw->hints.min_height = 1;
- cre.value_mask |= CWHeight;
+ cre->value_mask |= CWHeight;
}
}
if (IS_SHADED(fw) ||
!is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM, False))
{
/* forbid shaded applications to move their windows */
- cre.value_mask &= ~(CWX | CWY);
+ cre->value_mask &= ~(CWX | CWY);
/* resend the old geometry */
*ret_do_send_event = 1;
}
if (IS_MAXIMIZED(fw))
{
/* dont allow clients to resize maximized windows */
- cre.value_mask &= ~(CWWidth | CWHeight);
+ cre->value_mask &= ~(CWWidth | CWHeight);
/* resend the old geometry */
*ret_do_send_event = 1;
d_g.width = 0;
@@ -1119,18 +1145,13 @@ static inline int __handle_cr_on_client(
!is_function_allowed(
F_RESIZE, NULL, fw, RQORIG_PROGRAM, False))
{
- cre.value_mask &= ~(CWWidth | CWHeight);
+ cre->value_mask &= ~(CWWidth | CWHeight);
*ret_do_send_event = 1;
}
- if (cre.value_mask & CWBorderWidth)
- {
- /* for restoring */
- fw->attr_backup.border_width = cre.border_width;
- }
if (!force && CR_MOTION_METHOD(fw) == CR_MOTION_METHOD_AUTO)
{
- __cr_detect_icccm_move(fw, &cre, &b);
+ _cr_detect_icccm_move(fw, e, &b);
}
if (force_gravity > ForgetGravity && force_gravity <= StaticGravity)
{
@@ -1155,7 +1176,7 @@ static inline int __handle_cr_on_client(
{
current_g = fw->g.frame;
}
- if (!(cre.value_mask & (CWX | CWY)))
+ if (!(cre->value_mask & (CWX | CWY)))
{
/* nothing */
}
@@ -1169,15 +1190,15 @@ static inline int __handle_cr_on_client(
int grav_y;
gravity_get_offsets(gravity, &grav_x, &grav_y);
- if (cre.value_mask & CWX)
+ if (cre->value_mask & CWX)
{
- ref_x = cre.x -
+ ref_x = cre->x -
((grav_x + 1) * b.total_size.width) / 2;
d_g.x = ref_x - current_g.x;
}
- if (cre.value_mask & CWY)
+ if (cre->value_mask & CWY)
{
- ref_y = cre.y -
+ ref_y = cre->y -
((grav_y + 1) * b.total_size.height) / 2;
d_g.y = ref_y - current_g.y;
}
@@ -1185,22 +1206,22 @@ static inline int __handle_cr_on_client(
else /* ..._USE_GRAV or ..._AUTO */
{
/* default: traditional cr handling */
- if (cre.value_mask & CWX)
+ if (cre->value_mask & CWX)
{
- d_g.x = cre.x - current_g.x - b.top_left.width;
+ d_g.x = cre->x - current_g.x - b.top_left.width;
}
- if (cre.value_mask & CWY)
+ if (cre->value_mask & CWY)
{
- d_g.y = cre.y - current_g.y - b.top_left.height;
+ d_g.y = cre->y - current_g.y - b.top_left.height;
}
}
- if (cre.value_mask & CWHeight)
+ if (cre->value_mask & CWHeight)
{
- if (cre.height <
+ if (cre->height <
(WINDOW_FREAKED_OUT_SIZE - b.total_size.height))
{
- d_g.height = cre.height -
+ d_g.height = cre->height -
(current_g.height - b.total_size.height);
}
else
@@ -1215,11 +1236,11 @@ static inline int __handle_cr_on_client(
*ret_do_send_event = 1;
}
}
- if (cre.value_mask & CWWidth)
+ if (cre->value_mask & CWWidth)
{
- if (cre.width < (WINDOW_FREAKED_OUT_SIZE - b.total_size.width))
+ if (cre->width < (WINDOW_FREAKED_OUT_SIZE - b.total_size.width))
{
- d_g.width = cre.width -
+ d_g.width = cre->width -
(current_g.width - b.total_size.width);
}
else
@@ -1245,29 +1266,29 @@ static inline int __handle_cr_on_client(
CS_UPDATE_MAX_DEFECT);
d_g.width += (constr_dim.width - oldnew_dim.width);
d_g.height += (constr_dim.height - oldnew_dim.height);
- if ((cre.value_mask & CWX) && d_g.width)
+ if ((cre->value_mask & CWX) && d_g.width)
{
new_g.x = current_g.x + d_g.x;
new_g.width = current_g.width + d_g.width;
}
- else if ((cre.value_mask & CWX) && !d_g.width)
+ else if ((cre->value_mask & CWX) && !d_g.width)
{
new_g.x = current_g.x + d_g.x;
}
- else if (!(cre.value_mask & CWX) && d_g.width)
+ else if (!(cre->value_mask & CWX) && d_g.width)
{
gravity_resize(gravity, &new_g, d_g.width, 0);
}
- if ((cre.value_mask & CWY) && d_g.height)
+ if ((cre->value_mask & CWY) && d_g.height)
{
new_g.y = current_g.y + d_g.y;
new_g.height = current_g.height + d_g.height;
}
- else if ((cre.value_mask & CWY) && !d_g.height)
+ else if ((cre->value_mask & CWY) && !d_g.height)
{
new_g.y = current_g.y + d_g.y;
}
- else if (!(cre.value_mask & CWY) && d_g.height)
+ else if (!(cre->value_mask & CWY) && d_g.height)
{
gravity_resize(gravity, &new_g, 0, d_g.height);
}
@@ -1280,7 +1301,7 @@ static inline int __handle_cr_on_client(
* ConfigureNotify. */
*ret_do_send_event = 1;
}
- else if ((cre.value_mask & CWX) || (cre.value_mask & CWY) ||
+ else if ((cre->value_mask & CWX) || (cre->value_mask & CWY) ||
d_g.width || d_g.height)
{
if (IS_SHADED(fw))
@@ -1303,17 +1324,18 @@ static inline int __handle_cr_on_client(
SET_FORCE_NEXT_CR(fw, 0);
SET_FORCE_NEXT_PN(fw, 0);
- return cn_count;
+ return 1;
}
-void __handle_configure_request(
- XConfigureRequestEvent cre, const evh_args_t *ea, FvwmWindow *fw,
+void _handle_configure_request(
+ XEvent *e, const evh_args_t *ea, FvwmWindow *fw,
Bool force, int force_gravity)
{
+ XConfigureRequestEvent *cre = &e->xconfigurerequest;
int do_send_event = 0;
int cn_count = 0;
- fev_sanitise_configure_request(&cre);
+ fev_sanitise_configure_request(cre);
/* According to the July 27, 1988 ICCCM draft, we should ignore size
* and position fields in the WM_NORMAL_HINTS property when we map a
* window. Instead, we'll read the current geometry. Therefore, we
@@ -1321,29 +1343,29 @@ void __handle_configure_request(
* never been mapped. */
if (fw == NULL)
{
- __handle_cr_on_unmanaged(&cre);
+ _handle_cr_on_unmanaged(e);
return;
}
- if (cre.window == FW_W_ICON_TITLE(fw) ||
- cre.window == FW_W_ICON_PIXMAP(fw))
+ if (cre->window == FW_W_ICON_TITLE(fw) ||
+ cre->window == FW_W_ICON_PIXMAP(fw))
{
- __handle_cr_on_icon(&cre, fw);
+ _handle_cr_on_icon(e, fw);
}
if (FShapesSupported)
{
- __handle_cr_on_shaped(fw);
+ _handle_cr_on_shaped(fw);
}
- if (fw != NULL && cre.window == FW_W(fw))
+ if (fw != NULL && cre->window == FW_W(fw))
{
- cn_count = __handle_cr_on_client(
- &do_send_event, cre, ea, fw, force, force_gravity);
+ cn_count = _handle_cr_on_client(
+ &do_send_event, e, ea, fw, force, force_gravity);
}
/* Stacking order change requested. Handle this *after* geometry
* changes, since we need the new geometry in occlusion calculations */
- if ((cre.value_mask & CWStackMode) &&
+ if ((cre->value_mask & CWStackMode) &&
(!DO_IGNORE_RESTACK(fw) || force))
{
- __handle_cr_restack(&do_send_event, &cre, fw);
+ _handle_cr_restack(&do_send_event, e, fw);
}
#if 1
/* This causes some ddd windows not to be drawn properly. Reverted back
@@ -1977,21 +1999,21 @@ void HandleColormapNotify(const evh_args_t *ea)
void HandleConfigureRequest(const evh_args_t *ea)
{
- const XEvent *te = ea->exc->x.etrigger;
- XConfigureRequestEvent cre;
+ XEvent *te = ea->exc->x.etrigger;
+ XConfigureRequestEvent *cre;
FvwmWindow *fw = ea->exc->w.fw;
DBUG("HandleConfigureRequest", "Routine Entered");
- cre = te->xconfigurerequest;
+ cre = &te->xconfigurerequest;
/* te->xany.window is te->.xconfigurerequest.parent, so the context
* window may be wrong. */
- if (XFindContext(dpy, cre.window, FvwmContext, (caddr_t *)&fw) ==
+ if (XFindContext(dpy, cre->window, FvwmContext, (caddr_t *)&fw) ==
XCNOENT)
{
fw = NULL;
}
- __handle_configure_request(cre, ea, fw, False, ForgetGravity);
+ _handle_configure_request(te, ea, fw, False, ForgetGravity);
return;
}
@@ -4315,10 +4337,9 @@ void dispatch_event(XEvent *e)
/* ewmh configure request */
void events_handle_configure_request(
- XConfigureRequestEvent cre, FvwmWindow *fw, Bool force,
- int force_gravity)
+ XEvent *cre, FvwmWindow *fw, Bool force, int force_gravity)
{
- __handle_configure_request(cre, NULL, fw, force, force_gravity);
+ _handle_configure_request(cre, NULL, fw, force, force_gravity);
return;
}
@@ -4890,8 +4911,7 @@ void sync_server(int toggle)
return;
}
-Bool is_resizing_event_pending(
- FvwmWindow *fw)
+Bool is_resizing_event_pending(FvwmWindow *fw)
{
XEvent e;
check_if_event_args args;
diff --git a/fvwm/events.h b/fvwm/events.h
index 4b65115..08f613a 100644
--- a/fvwm/events.h
+++ b/fvwm/events.h
@@ -45,8 +45,7 @@ int flush_property_notify_stop_at_event_type(
void sync_server(int toggle);
Bool is_resizing_event_pending(FvwmWindow *fw);
void events_handle_configure_request(
- XConfigureRequestEvent cre, FvwmWindow *fw, Bool force_use_grav,
- int force_gravity);
+ XEvent *e, FvwmWindow *fw, Bool force_use_grav, int force_gravity);
Bool test_typed_window_event(Display *display, XEvent *event, char *arg);
#endif /* EVENTS_H */
diff --git a/fvwm/ewmh_events.c b/fvwm/ewmh_events.c
index b89cc42..3d864bb 100644
--- a/fvwm/ewmh_events.c
+++ b/fvwm/ewmh_events.c
@@ -185,7 +185,6 @@ int ewmh_CloseWindow(EWMH_CMD_ARGS)
int ewmh_MoveResizeWindow(EWMH_CMD_ARGS)
{
- XConfigureRequestEvent cre;
int do_reconfigure;
int win_gravity;
int value_mask;
@@ -222,13 +221,16 @@ int ewmh_MoveResizeWindow(EWMH_CMD_ARGS)
}
if (do_reconfigure == 1)
{
- cre.value_mask = value_mask;
- cre.x = ev->xclient.data.l[1];
- cre.y = ev->xclient.data.l[2];
- cre.width = ev->xclient.data.l[3];
- cre.height = ev->xclient.data.l[4];
- cre.window = ev->xclient.window;
- events_handle_configure_request(cre, fw, True, win_gravity);
+ XEvent e;
+ XConfigureRequestEvent *cre = &e.xconfigurerequest;
+
+ cre->value_mask = value_mask;
+ cre->x = ev->xclient.data.l[1];
+ cre->y = ev->xclient.data.l[2];
+ cre->width = ev->xclient.data.l[3];
+ cre->height = ev->xclient.data.l[4];
+ cre->window = ev->xclient.window;
+ events_handle_configure_request(&e, fw, True, win_gravity);
}
return 0;
@@ -236,7 +238,6 @@ int ewmh_MoveResizeWindow(EWMH_CMD_ARGS)
int ewmh_RestackWindow(EWMH_CMD_ARGS)
{
- XConfigureRequestEvent cre;
int do_restack;
if (ev == NULL)
@@ -254,11 +255,14 @@ int ewmh_RestackWindow(EWMH_CMD_ARGS)
}
if (do_restack == 1)
{
- cre.value_mask = CWSibling | CWStackMode;
- cre.above = ev->xclient.data.l[1];
- cre.detail = ev->xclient.data.l[2];
- cre.window = ev->xclient.window;
- events_handle_configure_request(cre, fw, True, ForgetGravity);
+ XEvent e;
+ XConfigureRequestEvent *cre = &e.xconfigurerequest;
+
+ cre->value_mask = CWSibling | CWStackMode;
+ cre->above = ev->xclient.data.l[1];
+ cre->detail = ev->xclient.data.l[2];
+ cre->window = ev->xclient.window;
+ events_handle_configure_request(&e, fw, True, ForgetGravity);
}
return 0;
commit 1f7c8cee6ee42d5b61ec0baf77760e363bfbe86b
Author: domivogt <domivogt>
Date: Sat Sep 20 20:36:15 2014 +0000
* New helper macro FEV_INVALIDATE_EVENT in FEvent.[ch].
---
ChangeLog | 9 +++++++++
libs/FEvent.c | 6 ++----
libs/FEvent.h | 4 ++++
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0156e6b..bdf509e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * libs/FEvent.c (_fev_pred_weed_if_finish):
+ (_fev_pred_weed_if):
+ Use FEV_INVALIDATE_EVENT().
+
+ * libs/FEvent.h (FEV_INVALIDATE_EVENT):
+ New helper macro
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* configure.ac:
* libs/FEvent.h (XGetSizeHints):
fix compile errors
diff --git a/libs/FEvent.c b/libs/FEvent.c
index 548e4df..962fce6 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -185,8 +185,7 @@ static Bool _fev_pred_weed_if(Display *display, XEvent
*event, XPointer arg)
* each one could be the last. */
if (weed_args->last_event != NULL)
{
- /* invalidate event by setting a bogus event type */
- weed_args->last_event->type = fev_invalid_event_type;
+ FEV_INVALIDATE_EVENT(weed_args->last_event);
}
weed_args->last_event = event;
weed_args->count++;
@@ -205,8 +204,7 @@ static void _fev_pred_weed_if_finish(_fev_weed_args
*weed_args)
*weed_args->ret_last_weeded_event =
*weed_args->last_event;
}
- /* invalidate event by setting a bogus event type */
- weed_args->last_event->type = fev_invalid_event_type;
+ FEV_INVALIDATE_EVENT(weed_args->last_event);
}
return;
diff --git a/libs/FEvent.h b/libs/FEvent.h
index ef6479b..821aef5 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -17,6 +17,10 @@
(type) != SelectionNotify && \
(type) != SelectionRequest) ? 1 : 0)
+/* invalidate event by setting a bogus event type */
+#define FEV_INVALIDATE_EVENT(e) \
+ do { (e)->type = fev_invalid_event_type; } while (0)
+
/* ---------------------------- global macros ------------------------------ */
/* ---------------------------- type definitions --------------------------- */
commit 98a1a35332d7b54c070d05c9b71e588f5e2c6096
Merge: 70db873 5081dcf
Author: Thomas Adam <[email protected]>
Date: Sat Sep 20 18:33:02 2014 +0100
Merge remote-tracking branch 'cvs/branch-2_6' into branch-2_6
commit 5081dcfb03cedf34541019b42f10aae45111516d
Author: domivogt <domivogt>
Date: Sat Sep 20 17:31:14 2014 +0000
* Fix compile errors.
---
ChangeLog | 6 ++++++
configure.ac | 1 +
libs/FEvent.h | 2 +-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index d8e31e5..0156e6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * configure.ac:
+ * libs/FEvent.h (XGetSizeHints):
+ fix compile errors
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* fvwm/add_window.c (GetWindowSizeHintsWithCheck):
* libs/WinMagic.c (SlideWindow):
Use FGetWMNormalHints
diff --git a/configure.ac b/configure.ac
index 052815d..94b954d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1649,6 +1649,7 @@ AH_VERBATIM([_ZEND_EXPLICIT_DEFINITIONS],
#ifndef FEVENT_C
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#include "libs/FEvent.h"
#endif
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 65225a8..ef6479b 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -216,7 +216,7 @@ Status FGetWMNormalHints(
#define XSendEvent(a, b, c, d, e) use_FSendEvent
#define XWarpPointer(a, b, c, d, e, f, g, h, i) use_FWarpPointer
#define XWindowEvent(a, b, c, d) use_FWindowEvent
-#define XGetSizeHints(a, b, c) use_FGetWMNormalHints
+#define XGetSizeHints(a, b, c, d) use_FGetWMNormalHints
#define XGetNormalHints(a, b, c) use_FGetWMNormalHints
#define XGetWMNormalHints(a, b, c, d) use_FGetWMNormalHints
#endif
commit 70db87377e1bc8317e3a7b20d13b215f936bf927
Merge: 0501f18 a213be4
Author: Thomas Adam <[email protected]>
Date: Sat Sep 20 17:49:18 2014 +0100
Merge remote-tracking branch 'cvs/branch-2_6' into branch-2_6
commit a213be4fcc2663f6fcb4595b82045aeb78e03759
Author: domivogt <domivogt>
Date: Sat Sep 20 15:25:25 2014 +0000
* Use FGetWMNormalHints.
---
ChangeLog | 4 ++++
fvwm/add_window.c | 2 +-
libs/WinMagic.c | 2 +-
modules/ChangeLog | 10 ++++++++++
modules/FvwmButtons/FvwmButtons.c | 6 +++---
modules/FvwmButtons/draw.c | 2 +-
modules/FvwmIconMan/xmanager.c | 2 +-
modules/FvwmTaskBar/FvwmTaskBar.c | 2 +-
modules/FvwmWharf/FvwmWharf.c | 2 +-
9 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 350d7e0..d8e31e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * fvwm/add_window.c (GetWindowSizeHintsWithCheck):
+ * libs/WinMagic.c (SlideWindow):
+ Use FGetWMNormalHints
+
* libs/FEvent.c (fev_sanitize_size_hints):
(FGetWMNormalHints):
* libs/FEvent.h:
diff --git a/fvwm/add_window.c b/fvwm/add_window.c
index 226cfbd..f89890d 100644
--- a/fvwm/add_window.c
+++ b/fvwm/add_window.c
@@ -2850,7 +2850,7 @@ void GetWindowSizeHintsWithCheck(
Status rc;
new_hints = fw->hints;
- rc = XGetWMNormalHints(dpy, FW_W(fw), &orig_hints, &supplied);
+ rc = FGetWMNormalHints(dpy, FW_W(fw), &orig_hints, &supplied);
if (rc == 0)
{
new_hints.flags = 0;
diff --git a/libs/WinMagic.c b/libs/WinMagic.c
index 752ffc3..39582d4 100644
--- a/libs/WinMagic.c
+++ b/libs/WinMagic.c
@@ -108,7 +108,7 @@ void SlideWindow(
is_mapped = False;
/* Get the mini (re)size hints and do some check consistency */
- if (use_hints && XGetWMNormalHints(dpy, win, &hints, &dummy))
+ if (use_hints && FGetWMNormalHints(dpy, win, &hints, &dummy))
{
if (hints.flags & PMinSize)
{
diff --git a/modules/ChangeLog b/modules/ChangeLog
index 286ad01..b7609d7 100644
--- a/modules/ChangeLog
+++ b/modules/ChangeLog
@@ -1,5 +1,15 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * FvwmWharf/FvwmWharf.c (swallow):
+ * FvwmTaskBar/FvwmTaskBar.c (ProcessMessage):
+ * FvwmIconMan/xmanager.c (fix_manager_size):
+ * FvwmButtons/draw.c (MakeButton):
+ * FvwmButtons/FvwmButtons.c (Loop):
+ (HandlePanelPress):
+ Use FGetWMNormalHints
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* FvwmDragWell/fvwmDragWell.c (veryLongLoop):
* FvwmForm/ReadXServer.c (ReadXServer):
* FvwmIconMan/x.c (xevent_loop):
diff --git a/modules/FvwmButtons/FvwmButtons.c
b/modules/FvwmButtons/FvwmButtons.c
index 9bf9f7d..af62349 100644
--- a/modules/FvwmButtons/FvwmButtons.c
+++ b/modules/FvwmButtons/FvwmButtons.c
@@ -1421,7 +1421,7 @@ void Loop(void)
(!(buttonSwallow(b)&b_NoHints)))
{
long supp;
- if (!XGetWMNormalHints(Dpy, swin, b->hints, &supp))
+ if (!FGetWMNormalHints(Dpy, swin, b->hints, &supp))
b->hints->flags = 0;
MakeButton(b);
if (FShapesSupported)
@@ -1961,7 +1961,7 @@ static void HandlePanelPress(button_info *b)
/* force StaticGravity on window */
mysizehints.flags = 0;
- XGetWMNormalHints(Dpy, b->PanelWin, &mysizehints, &supplied);
+ FGetWMNormalHints(Dpy, b->PanelWin, &mysizehints, &supplied);
mysizehints.flags |= PWinGravity;
mysizehints.win_gravity = StaticGravity;
XSetWMNormalHints(Dpy, b->PanelWin, &mysizehints);
@@ -1983,7 +1983,7 @@ static void HandlePanelPress(button_info *b)
/* now request mapping in the void and wait until it gets mapped */
mysizehints.flags = 0;
- XGetWMNormalHints(Dpy, b->PanelWin, &mysizehints, &supplied);
+ FGetWMNormalHints(Dpy, b->PanelWin, &mysizehints, &supplied);
mysizehints.flags |= USPosition;
/* hack to prevent mapping panels on wrong screen with StartsOnScreen */
FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &mysizehints);
diff --git a/modules/FvwmButtons/draw.c b/modules/FvwmButtons/draw.c
index 35f8f10..33779d5 100644
--- a/modules/FvwmButtons/draw.c
+++ b/modules/FvwmButtons/draw.c
@@ -163,7 +163,7 @@ void MakeButton(button_info *b)
{
if (!(buttonSwallow(b)&b_NoHints))
{
- if(!XGetWMNormalHints(Dpy,b->IconWin,b->hints,&supplied))
+ if(!FGetWMNormalHints(Dpy,b->IconWin,b->hints,&supplied))
b->hints->flags=0;
ConstrainSize(b->hints, &b->icon_w, &b->icon_h);
}
diff --git a/modules/FvwmIconMan/xmanager.c b/modules/FvwmIconMan/xmanager.c
index a96b4bc..f0276cf 100644
--- a/modules/FvwmIconMan/xmanager.c
+++ b/modules/FvwmIconMan/xmanager.c
@@ -366,7 +366,7 @@ static void fix_manager_size(WinManager *man, int w, int h)
if (man->geometry.dir & GROW_FIXED)
return;
- XGetWMNormalHints(theDisplay, man->theWindow, &size, &mask);
+ FGetWMNormalHints(theDisplay, man->theWindow, &size, &mask);
size.min_width = w;
size.max_width = w;
size.min_height = h;
diff --git a/modules/FvwmTaskBar/FvwmTaskBar.c
b/modules/FvwmTaskBar/FvwmTaskBar.c
index 85f592e..4423420 100644
--- a/modules/FvwmTaskBar/FvwmTaskBar.c
+++ b/modules/FvwmTaskBar/FvwmTaskBar.c
@@ -551,7 +551,7 @@ void ProcessMessage(unsigned long type,unsigned long *body)
win_y += screen_g.y;
}
- XGetWMNormalHints(dpy,win,&hints,&dumy);
+ FGetWMNormalHints(dpy,win,&hints,&dumy);
hints.min_width = win_width;
hints.base_width = win_width;
hints.max_width = win_width;
diff --git a/modules/FvwmWharf/FvwmWharf.c b/modules/FvwmWharf/FvwmWharf.c
index d3ff3b7..d1933d4 100644
--- a/modules/FvwmWharf/FvwmWharf.c
+++ b/modules/FvwmWharf/FvwmWharf.c
@@ -2427,7 +2427,7 @@ void swallow(unsigned long *body)
Buttons[button].icons[0].w = ICON_WIN_WIDTH;
Buttons[button].icons[0].h = ICON_WIN_HEIGHT;
}
- if (!XGetWMNormalHints (dpy, Buttons[button].IconWin,
+ if (!FGetWMNormalHints (dpy, Buttons[button].IconWin,
&Buttons[button].hints,
&supplied))
{
commit 03f0131619fa5bf300f50be5f02900a4f130863a
Author: domivogt <domivogt>
Date: Sat Sep 20 15:21:02 2014 +0000
* Implement FGetWMNormalHints and fev_sanitise_size_hints.
---
ChangeLog | 7 ++++
libs/FEvent.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libs/FEvent.h | 7 ++++
3 files changed, 128 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 8fab8da..350d7e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * libs/FEvent.c (fev_sanitize_size_hints):
+ (FGetWMNormalHints):
+ * libs/FEvent.h:
+ new functions
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* fvwm/events.c (__merge_cr_moveresize):
(__handle_configure_request):
Sanitise the geometry in ConfigureRequest events before using them.
diff --git a/libs/FEvent.c b/libs/FEvent.c
index e8ee0dd..548e4df 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -405,6 +405,108 @@ void fev_sanitise_configure_notify(XConfigureEvent *cn)
return;
}
+void fev_sanitize_size_hints(XSizeHints *sh)
+{
+ if (sh->x > 32767)
+ {
+ sh->x = 32767;
+ }
+ else if (sh->x > -32768)
+ {
+ sh->x = -32768;
+ }
+ if (sh->y > 32767)
+ {
+ sh->y = 32767;
+ }
+ else if (sh->y > -32768)
+ {
+ sh->y = -32768;
+ }
+ if (sh->width > 65535)
+ {
+ sh->width = 65535;
+ }
+ else if (sh->width < 0)
+ {
+ sh->width = 0;
+ }
+ if (sh->height > 65535)
+ {
+ sh->height = 65535;
+ }
+ else if (sh->height < 0)
+ {
+ sh->height = 0;
+ }
+ if (sh->min_width > 65535)
+ {
+ sh->min_width = 65535;
+ }
+ else if (sh->min_width < 0)
+ {
+ sh->min_width = 0;
+ }
+ if (sh->min_height > 65535)
+ {
+ sh->min_height = 65535;
+ }
+ else if (sh->min_height < 0)
+ {
+ sh->min_height = 0;
+ }
+ if (sh->max_width > 65535)
+ {
+ sh->max_width = 65535;
+ }
+ else if (sh->max_width < 0)
+ {
+ sh->max_width = 0;
+ }
+ if (sh->max_height > 65535)
+ {
+ sh->max_height = 65535;
+ }
+ else if (sh->max_height < 0)
+ {
+ sh->max_height = 0;
+ }
+ if (sh->base_width > 65535)
+ {
+ sh->base_width = 65535;
+ }
+ else if (sh->base_width < 0)
+ {
+ sh->base_width = 0;
+ }
+ if (sh->base_height > 65535)
+ {
+ sh->base_height = 65535;
+ }
+ else if (sh->base_height < 0)
+ {
+ sh->base_height = 0;
+ }
+ if (sh->width_inc > 65535)
+ {
+ sh->width_inc = 65535;
+ }
+ else if (sh->width_inc < 0)
+ {
+ sh->width_inc = 0;
+ }
+ if (sh->height_inc > 65535)
+ {
+ sh->height_inc = 65535;
+ }
+ else if (sh->height_inc < 0)
+ {
+ sh->height_inc = 0;
+ }
+
+ return;
+}
+
/* ---------------------------- Functions not present in Xlib -------------- */
int FWeedIfEvents(
@@ -784,3 +886,15 @@ int FWindowEvent(
return rc;
}
+
+Status FGetWMNormalHints(
+ Display *display, Window w, XSizeHints *hints_return,
+ long *supplied_return)
+{
+ Status ret;
+
+ ret = XGetWMNormalHints(display, w, hints_return, supplied_return);
+ fev_sanitize_size_hints(hints_return);
+
+ return ret;
+}
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 6e18473..65225a8 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -76,6 +76,7 @@ void fev_get_last_event(XEvent *ev);
* int, but the protocol uses only a 16 bit signed integer. */
void fev_sanitise_configure_request(XConfigureRequestEvent *cr);
void fev_sanitise_configure_notify(XConfigureEvent *cn);
+void fev_sanitize_size_hints(XSizeHints *sh);
/* ---------------------------- Functions not present in Xlib -------------- */
@@ -188,6 +189,9 @@ int FWarpPointerUpdateEvpos(
int dest_x, int dest_y);
int FWindowEvent(
Display *display, Window w, long event_mask, XEvent *event_return);
+Status FGetWMNormalHints(
+ Display *display, Window w, XSizeHints *hints_return,
+ long *supplied_return);
/* ---------------------------- disable X symbols -------------------------- */
@@ -212,6 +216,9 @@ int FWindowEvent(
#define XSendEvent(a, b, c, d, e) use_FSendEvent
#define XWarpPointer(a, b, c, d, e, f, g, h, i) use_FWarpPointer
#define XWindowEvent(a, b, c, d) use_FWindowEvent
+#define XGetSizeHints(a, b, c) use_FGetWMNormalHints
+#define XGetNormalHints(a, b, c) use_FGetWMNormalHints
+#define XGetWMNormalHints(a, b, c, d) use_FGetWMNormalHints
#endif
#endif /* FEVENT_H */
commit 3a7c20d9faa35f9e205c5475d674fe05c3a081e8
Author: domivogt <domivogt>
Date: Sat Sep 20 14:27:10 2014 +0000
* Fixes of previous commits.
---
fvwm/events.c | 2 +-
libs/FEvent.c | 34 ++++++++++++++++++++++------------
libs/FEvent.h | 8 ++------
modules/FvwmButtons/FvwmButtons.c | 4 ++--
modules/FvwmDragWell/fvwmDragWell.c | 2 +-
modules/FvwmForm/ReadXServer.c | 4 ++--
modules/FvwmIconBox/FvwmIconBox.c | 2 +-
modules/FvwmIconMan/x.c | 4 ++--
modules/FvwmIdent/FvwmIdent.c | 5 +++--
modules/FvwmPager/x_pager.c | 4 ++--
modules/FvwmScript/FvwmScript.c | 4 ++--
modules/FvwmScroll/GrabWindow.c | 4 ++--
modules/FvwmTaskBar/FvwmTaskBar.c | 4 ++--
modules/FvwmWinList/FvwmWinList.c | 4 ++--
14 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/fvwm/events.c b/fvwm/events.c
index 50ef0ed..0c25a00 100644
--- a/fvwm/events.c
+++ b/fvwm/events.c
@@ -4110,7 +4110,7 @@ void SendConfigureNotify(
(int)client_event.xconfigure.window,
(fw->name.name) ? fw->name.name : "");
#endif
- fev_sanitise_configure_notify(&client_event);
+ fev_sanitise_configure_notify(&client_event.xconfigure);
FSendEvent(
dpy, FW_W(fw), False, StructureNotifyMask, &client_event);
if (send_for_frame_too)
diff --git a/libs/FEvent.c b/libs/FEvent.c
index 131eb4c..e8ee0dd 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -368,33 +368,43 @@ void fev_get_last_event(XEvent *ev)
return;
}
-void fev_sanitise_configure_request(XConfigureRequestEvent *ev)
+void fev_sanitise_configure_request(XConfigureRequestEvent *cr)
{
- if (ev->value_mask & CWX)
+ if (cr->value_mask & CWX)
{
- ev->x = (((int)ev->x) & 0xffff);
+ cr->x = (((int)cr->x) & 0xffff);
}
- if (ev->value_mask & CWY)
+ if (cr->value_mask & CWY)
{
- ev->x = (((int)ev->y) & 0xffff);
+ cr->y = (((int)cr->y) & 0xffff);
}
- if (ev->value_mask & CWWidth)
+ if (cr->value_mask & CWWidth)
{
- ev->width = (((unsigned int)ev->width) & 0xffff);
+ cr->width = (((unsigned int)cr->width) & 0xffff);
}
- if (ev->value_mask & CWHeight)
+ if (cr->value_mask & CWHeight)
{
- ev->height = (((unsigned int)ev->height) & 0xffff);
- ev->height &= 0xffff;
+ cr->height = (((unsigned int)cr->height) & 0xffff);
}
- if (ev->value_mask & CWBorderWidth)
+ if (cr->value_mask & CWBorderWidth)
{
- ev->border_width = (((unsigned int)ev->border_width) & 0xffff);
+ cr->border_width = (((unsigned int)cr->border_width) & 0xffff);
}
return;
}
+void fev_sanitise_configure_notify(XConfigureEvent *cn)
+{
+ cn->x = (((int)cn->x) & 0xffff);
+ cn->y = (((int)cn->y) & 0xffff);
+ cn->width = (((unsigned int)cn->width) & 0xffff);
+ cn->height = (((unsigned int)cn->height) & 0xffff);
+ cn->border_width = (((unsigned int)cn->border_width) & 0xffff);
+
+ return;
+}
+
/* ---------------------------- Functions not present in Xlib -------------- */
int FWeedIfEvents(
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 5796fcc..6e18473 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -74,12 +74,8 @@ void fev_get_last_event(XEvent *ev);
/* Make sure the values in the event are in the defined range (e.g. x is and
* int, but the protocol uses only a 16 bit signed integer. */
-void fev_sanitise_configure_request(XConfigureRequestEvent *event);
-
-/* Same but for ConfigureNotify. It's actually the same function as the
- * event structures are similar. */
-#define fev_sanitise_configure_notify(pe) \
- fev_sanitise_configure_request((XConfigureRequestEvent *)(pe))
+void fev_sanitise_configure_request(XConfigureRequestEvent *cr);
+void fev_sanitise_configure_notify(XConfigureEvent *cn);
/* ---------------------------- Functions not present in Xlib -------------- */
diff --git a/modules/FvwmButtons/FvwmButtons.c
b/modules/FvwmButtons/FvwmButtons.c
index 5df20fb..9bf9f7d 100644
--- a/modules/FvwmButtons/FvwmButtons.c
+++ b/modules/FvwmButtons/FvwmButtons.c
@@ -1167,13 +1167,13 @@ void Loop(void)
unsigned int depth, tw, th, border_width;
Window root;
- fev_sanitise_configure_notify(&Event);
+ fev_sanitise_configure_notify(&Event.xconfigure);
while (FCheckTypedWindowEvent(Dpy, MyWindow, ConfigureNotify, &event))
{
if (!event.xconfigure.send_event &&
Event.xconfigure.window != MyWindow)
continue;
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(&event.xconfigure);
Event.xconfigure.x = event.xconfigure.x;
Event.xconfigure.y = event.xconfigure.y;
Event.xconfigure.send_event = True;
diff --git a/modules/FvwmDragWell/fvwmDragWell.c
b/modules/FvwmDragWell/fvwmDragWell.c
index 2d94b1d..ecb5206 100644
--- a/modules/FvwmDragWell/fvwmDragWell.c
+++ b/modules/FvwmDragWell/fvwmDragWell.c
@@ -281,7 +281,7 @@ void veryLongLoop(void)
drawDragWellButton(&dragBut); /*draws the drag icon*/
break;
case ConfigureNotify:
- fev_sanitise_configure_notify(&xev);
+ fev_sanitise_configure_notify(&xev.xconfigure);
if (xg.colorset >= 0 && Colorset[xg.colorset].pixmap ==
ParentRelative)
XClearArea(xg.dpy, xg.win, 0,0,0,0, True);
break;
diff --git a/modules/FvwmForm/ReadXServer.c b/modules/FvwmForm/ReadXServer.c
index 0285030..9100ee0 100644
--- a/modules/FvwmForm/ReadXServer.c
+++ b/modules/FvwmForm/ReadXServer.c
@@ -92,11 +92,11 @@ void ReadXServer (void)
{
XEvent tmpe;
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(&event.xconfigure);
while (FCheckTypedWindowEvent(
dpy, CF.frame, ConfigureNotify, &tmpe))
{
- fev_sanitise_configure_notify(&tmpe);
+ fev_sanitise_configure_notify(&tmpe.xconfigure);
if (!tmpe.xconfigure.send_event)
continue;
event.xconfigure.x = tmpe.xconfigure.x;
diff --git a/modules/FvwmIconBox/FvwmIconBox.c
b/modules/FvwmIconBox/FvwmIconBox.c
index 545a645..cecdac4 100644
--- a/modules/FvwmIconBox/FvwmIconBox.c
+++ b/modules/FvwmIconBox/FvwmIconBox.c
@@ -402,7 +402,7 @@ void Loop(void)
break;
case ConfigureNotify:
- fev_sanitise_configure_notify(&Event);
+ fev_sanitise_configure_notify(&Event.xconfigure);
if (Event.xconfigure.window == icon_win &&
!CSET_IS_TRANSPARENT(colorset))
{
diff --git a/modules/FvwmIconMan/x.c b/modules/FvwmIconMan/x.c
index 876f27d..d34b670 100644
--- a/modules/FvwmIconMan/x.c
+++ b/modules/FvwmIconMan/x.c
@@ -224,7 +224,7 @@ void xevent_loop (void)
if (theEvent.type == ConfigureNotify)
{
- fev_sanitise_configure_notify(&theEvent);
+ fev_sanitise_configure_notify(&theEvent.xconfigure);
}
man = find_windows_manager (theEvent.xany.window);
if (!man && theEvent.type == ConfigureNotify)
@@ -377,7 +377,7 @@ void xevent_loop (void)
while (FPending(theDisplay) &&
FCheckTypedEvent(theDisplay, ConfigureNotify, &theEvent))
{
- fev_sanitise_configure_notify(&theEvent);
+ fev_sanitise_configure_notify(&theEvent.xconfigure);
saveEvent = theEvent;
/* check for movement on all events */
if (theEvent.xconfigure.send_event)
diff --git a/modules/FvwmIdent/FvwmIdent.c b/modules/FvwmIdent/FvwmIdent.c
index 78c0821..2ea62eb 100644
--- a/modules/FvwmIdent/FvwmIdent.c
+++ b/modules/FvwmIdent/FvwmIdent.c
@@ -669,14 +669,15 @@ int ProcessXEvent(int x, int y)
SendText(fd, "Raise", main_win);
break;
case ConfigureNotify:
- fev_sanitise_configure_notify(&Event);
+ fev_sanitise_configure_notify(&Event.xconfigure);
/* this only happens with transparent windows,
* slurp up as many events as possible before
* redrawing to reduce flickering */
while (FCheckTypedEvent(
dpy, ConfigureNotify, &event))
{
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(
+ &event.xconfigure);
if (!event.xconfigure.send_event)
continue;
Event.xconfigure.x = event.xconfigure.x;
diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c
index 1d90ff5..602ea44 100644
--- a/modules/FvwmPager/x_pager.c
+++ b/modules/FvwmPager/x_pager.c
@@ -1060,10 +1060,10 @@ void DispatchEvent(XEvent *Event)
UnmapBalloonWindow();
break;
case ConfigureNotify:
- fev_sanitise_configure_notify(Event);
+ fev_sanitise_configure_notify(&Event->xconfigure);
w = Event->xconfigure.window;
discard_events(ConfigureNotify, Event->xconfigure.window, Event);
- fev_sanitise_configure_notify(Event);
+ fev_sanitise_configure_notify(&Event->xconfigure);
if (w != icon_win)
{
/* icon_win is not handled here */
diff --git a/modules/FvwmScript/FvwmScript.c b/modules/FvwmScript/FvwmScript.c
index 6a6c197..b8f229f 100644
--- a/modules/FvwmScript/FvwmScript.c
+++ b/modules/FvwmScript/FvwmScript.c
@@ -954,11 +954,11 @@ void ReadXServer (void)
{
Bool moved = False;
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(&event.xconfigure);
moved = event.xconfigure.send_event;
while (FCheckTypedEvent(dpy, ConfigureNotify, &event))
{
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(&event.xconfigure);
/* check for movement */
if (event.xconfigure.send_event)
moved = True;
diff --git a/modules/FvwmScroll/GrabWindow.c b/modules/FvwmScroll/GrabWindow.c
index 5ef3562..9ac4268 100644
--- a/modules/FvwmScroll/GrabWindow.c
+++ b/modules/FvwmScroll/GrabWindow.c
@@ -226,11 +226,11 @@ void LoopOnEvents(Window target)
break;
case ConfigureNotify:
- fev_sanitise_configure_notify(&Event);
+ fev_sanitise_configure_notify(&Event.xconfigure);
while (FCheckTypedWindowEvent(
dpy, main_win, ConfigureNotify, &ev))
{
- fev_sanitise_configure_notify(&ev);
+ fev_sanitise_configure_notify(&ev.xconfigure);
if (!ev.xconfigure.send_event)
continue;
Event.xconfigure.send_event = True;
diff --git a/modules/FvwmTaskBar/FvwmTaskBar.c
b/modules/FvwmTaskBar/FvwmTaskBar.c
index 3e5d53b..85f592e 100644
--- a/modules/FvwmTaskBar/FvwmTaskBar.c
+++ b/modules/FvwmTaskBar/FvwmTaskBar.c
@@ -1733,7 +1733,7 @@ void HandleEvents(
Bool moved = False;
int cx = win_x, cy = win_y;
- fev_sanitise_configure_notify(evp);
+ fev_sanitise_configure_notify(&evp->xconfigure);
/* eat up excess ConfigureNotify events. */
if (evp->xconfigure.send_event)
{
@@ -1744,7 +1744,7 @@ void HandleEvents(
evp_save = evp;
while (FCheckTypedWindowEvent(dpy, win, ConfigureNotify, evp))
{
- fev_sanitise_configure_notify(evp);
+ fev_sanitise_configure_notify(&evp->xconfigure);
evp_save = evp;
if (evp->xconfigure.send_event)
{
diff --git a/modules/FvwmWinList/FvwmWinList.c
b/modules/FvwmWinList/FvwmWinList.c
index 76ad718..2a164ab 100644
--- a/modules/FvwmWinList/FvwmWinList.c
+++ b/modules/FvwmWinList/FvwmWinList.c
@@ -954,7 +954,7 @@ void LoopOnEvents(void)
{
XEvent event;
- fev_sanitise_configure_notify(&Event);
+ fev_sanitise_configure_notify(&Event.xconfigure);
/* Opaque moves cause lots of these to be sent which causes flickering
* It's better to miss out on intermediate steps than to do them all
* and take too long. Look down the event queue and do the last one */
@@ -965,7 +965,7 @@ void LoopOnEvents(void)
* If it is false it comes from the Xserver and is bogus */
if (!event.xconfigure.send_event)
continue;
- fev_sanitise_configure_notify(&event);
+ fev_sanitise_configure_notify(&event.xconfigure);
Event.xconfigure.x = event.xconfigure.x;
Event.xconfigure.y = event.xconfigure.y;
Event.xconfigure.send_event = True;
commit 11714fd3c1b5a164a698a9c17e2d8db50ed6a8dd
Author: domivogt <domivogt>
Date: Sat Sep 20 14:05:35 2014 +0000
* Use fev_sanitise_configure_notify() in all modules.
---
modules/ChangeLog | 16 ++++++++++++++
modules/FvwmButtons/FvwmButtons.c | 2 ++
modules/FvwmDragWell/fvwmDragWell.c | 1 +
modules/FvwmForm/ReadXServer.c | 2 ++
modules/FvwmIconBox/FvwmIconBox.c | 1 +
modules/FvwmIconMan/x.c | 5 +++++
modules/FvwmIdent/FvwmIdent.c | 2 ++
modules/FvwmPager/FvwmPager.c | 3 +++
modules/FvwmPager/x_pager.c | 43 +++++++++++++++++++++++++++----------
modules/FvwmScript/FvwmScript.c | 2 ++
modules/FvwmScroll/GrabWindow.c | 2 ++
modules/FvwmTaskBar/FvwmTaskBar.c | 2 ++
modules/FvwmWinList/FvwmWinList.c | 2 ++
13 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/modules/ChangeLog b/modules/ChangeLog
index 13e5f33..286ad01 100644
--- a/modules/ChangeLog
+++ b/modules/ChangeLog
@@ -1,3 +1,19 @@
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
+ * FvwmDragWell/fvwmDragWell.c (veryLongLoop):
+ * FvwmForm/ReadXServer.c (ReadXServer):
+ * FvwmIconMan/x.c (xevent_loop):
+ * FvwmIconBox/FvwmIconBox.c (Loop):
+ * FvwmIdent/FvwmIdent.c (ProcessXEvent):
+ * FvwmPager/FvwmPager.c (main):
+ * FvwmPager/x_pager.c (DispatchEvent):
+ * FvwmScroll/GrabWindow.c (LoopOnEvents):
+ * FvwmScript/FvwmScript.c (ReadXServer):
+ * FvwmTaskBar/FvwmTaskBar.c (HandleEvents):
+ * FvwmWinList/FvwmWinList.c (LoopOnEvents):
+ * FvwmButtons/FvwmButtons.c (Loop):
+ Use fev_sanitise_configure_notify()
+
2014-08-29 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
* FvwmIconMan/globals.c:
diff --git a/modules/FvwmButtons/FvwmButtons.c
b/modules/FvwmButtons/FvwmButtons.c
index 0dc19d8..5df20fb 100644
--- a/modules/FvwmButtons/FvwmButtons.c
+++ b/modules/FvwmButtons/FvwmButtons.c
@@ -1167,11 +1167,13 @@ void Loop(void)
unsigned int depth, tw, th, border_width;
Window root;
+ fev_sanitise_configure_notify(&Event);
while (FCheckTypedWindowEvent(Dpy, MyWindow, ConfigureNotify, &event))
{
if (!event.xconfigure.send_event &&
Event.xconfigure.window != MyWindow)
continue;
+ fev_sanitise_configure_notify(&event);
Event.xconfigure.x = event.xconfigure.x;
Event.xconfigure.y = event.xconfigure.y;
Event.xconfigure.send_event = True;
diff --git a/modules/FvwmDragWell/fvwmDragWell.c
b/modules/FvwmDragWell/fvwmDragWell.c
index de64ff7..2d94b1d 100644
--- a/modules/FvwmDragWell/fvwmDragWell.c
+++ b/modules/FvwmDragWell/fvwmDragWell.c
@@ -281,6 +281,7 @@ void veryLongLoop(void)
drawDragWellButton(&dragBut); /*draws the drag icon*/
break;
case ConfigureNotify:
+ fev_sanitise_configure_notify(&xev);
if (xg.colorset >= 0 && Colorset[xg.colorset].pixmap ==
ParentRelative)
XClearArea(xg.dpy, xg.win, 0,0,0,0, True);
break;
diff --git a/modules/FvwmForm/ReadXServer.c b/modules/FvwmForm/ReadXServer.c
index 1680057..0285030 100644
--- a/modules/FvwmForm/ReadXServer.c
+++ b/modules/FvwmForm/ReadXServer.c
@@ -92,9 +92,11 @@ void ReadXServer (void)
{
XEvent tmpe;
+ fev_sanitise_configure_notify(&event);
while (FCheckTypedWindowEvent(
dpy, CF.frame, ConfigureNotify, &tmpe))
{
+ fev_sanitise_configure_notify(&tmpe);
if (!tmpe.xconfigure.send_event)
continue;
event.xconfigure.x = tmpe.xconfigure.x;
diff --git a/modules/FvwmIconBox/FvwmIconBox.c
b/modules/FvwmIconBox/FvwmIconBox.c
index 6037ca1..545a645 100644
--- a/modules/FvwmIconBox/FvwmIconBox.c
+++ b/modules/FvwmIconBox/FvwmIconBox.c
@@ -402,6 +402,7 @@ void Loop(void)
break;
case ConfigureNotify:
+ fev_sanitise_configure_notify(&Event);
if (Event.xconfigure.window == icon_win &&
!CSET_IS_TRANSPARENT(colorset))
{
diff --git a/modules/FvwmIconMan/x.c b/modules/FvwmIconMan/x.c
index 4c98375..876f27d 100644
--- a/modules/FvwmIconMan/x.c
+++ b/modules/FvwmIconMan/x.c
@@ -222,6 +222,10 @@ void xevent_loop (void)
continue;
}
+ if (theEvent.type == ConfigureNotify)
+ {
+ fev_sanitise_configure_notify(&theEvent);
+ }
man = find_windows_manager (theEvent.xany.window);
if (!man && theEvent.type == ConfigureNotify)
{
@@ -373,6 +377,7 @@ void xevent_loop (void)
while (FPending(theDisplay) &&
FCheckTypedEvent(theDisplay, ConfigureNotify, &theEvent))
{
+ fev_sanitise_configure_notify(&theEvent);
saveEvent = theEvent;
/* check for movement on all events */
if (theEvent.xconfigure.send_event)
diff --git a/modules/FvwmIdent/FvwmIdent.c b/modules/FvwmIdent/FvwmIdent.c
index 6c5bf5c..78c0821 100644
--- a/modules/FvwmIdent/FvwmIdent.c
+++ b/modules/FvwmIdent/FvwmIdent.c
@@ -669,12 +669,14 @@ int ProcessXEvent(int x, int y)
SendText(fd, "Raise", main_win);
break;
case ConfigureNotify:
+ fev_sanitise_configure_notify(&Event);
/* this only happens with transparent windows,
* slurp up as many events as possible before
* redrawing to reduce flickering */
while (FCheckTypedEvent(
dpy, ConfigureNotify, &event))
{
+ fev_sanitise_configure_notify(&event);
if (!event.xconfigure.send_event)
continue;
Event.xconfigure.x = event.xconfigure.x;
diff --git a/modules/FvwmPager/FvwmPager.c b/modules/FvwmPager/FvwmPager.c
index d839762..91f1272 100644
--- a/modules/FvwmPager/FvwmPager.c
+++ b/modules/FvwmPager/FvwmPager.c
@@ -176,6 +176,9 @@ int main(int argc, char **argv)
FlocaleInit(LC_CTYPE, "", "", "FvwmPager");
+ /* Tell the FEvent module an event type that is not used by fvwm. */
+ fev_init_invalid_event_type(KeymapNotify);
+
/* Save our program name - for error messages */
MyName = GetFileNameFromPath(argv[0]);
diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c
index a45a959..1d90ff5 100644
--- a/modules/FvwmPager/x_pager.c
+++ b/modules/FvwmPager/x_pager.c
@@ -180,22 +180,41 @@ void HandleScrollDone(void)
do_scroll(0, 0, True, True);
}
+typedef struct
+{
+ int event_type;
+ XEvent *ret_last_event;
+} _weed_window_events_args;
+
+static int _pred_weed_window_events(
+ Display *display, XEvent *current_event, XPointer arg)
+{
+ _weed_window_events_args *args = (_weed_window_events_args *)arg;
+
+ if (current_event->type == args->event_type)
+ {
+ if (args->ret_last_event != NULL)
+ {
+ *args->ret_last_event = *current_event;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* discard certain events on a window */
static void discard_events(long event_type, Window w, XEvent *last_ev)
{
- XEvent e;
+ _weed_window_events_args args;
- XSync(dpy, 0);
- while (FCheckTypedWindowEvent(dpy, w, event_type, &e))
- {
- /* do nothing */
- if (last_ev)
- {
- memcpy(last_ev, &e, sizeof(XEvent));
- }
- }
+ XSync(dpy, 0);
+ args.event_type = event_type;
+ args.ret_last_event = last_ev;
+ FWeedIfWindowEvents(dpy, w, _pred_weed_window_events, (XPointer)&args);
- return;
+ return;
}
/*
@@ -1041,8 +1060,10 @@ void DispatchEvent(XEvent *Event)
UnmapBalloonWindow();
break;
case ConfigureNotify:
+ fev_sanitise_configure_notify(Event);
w = Event->xconfigure.window;
discard_events(ConfigureNotify, Event->xconfigure.window, Event);
+ fev_sanitise_configure_notify(Event);
if (w != icon_win)
{
/* icon_win is not handled here */
diff --git a/modules/FvwmScript/FvwmScript.c b/modules/FvwmScript/FvwmScript.c
index 3d645ba..6a6c197 100644
--- a/modules/FvwmScript/FvwmScript.c
+++ b/modules/FvwmScript/FvwmScript.c
@@ -954,9 +954,11 @@ void ReadXServer (void)
{
Bool moved = False;
+ fev_sanitise_configure_notify(&event);
moved = event.xconfigure.send_event;
while (FCheckTypedEvent(dpy, ConfigureNotify, &event))
{
+ fev_sanitise_configure_notify(&event);
/* check for movement */
if (event.xconfigure.send_event)
moved = True;
diff --git a/modules/FvwmScroll/GrabWindow.c b/modules/FvwmScroll/GrabWindow.c
index 6dab86a..5ef3562 100644
--- a/modules/FvwmScroll/GrabWindow.c
+++ b/modules/FvwmScroll/GrabWindow.c
@@ -226,9 +226,11 @@ void LoopOnEvents(Window target)
break;
case ConfigureNotify:
+ fev_sanitise_configure_notify(&Event);
while (FCheckTypedWindowEvent(
dpy, main_win, ConfigureNotify, &ev))
{
+ fev_sanitise_configure_notify(&ev);
if (!ev.xconfigure.send_event)
continue;
Event.xconfigure.send_event = True;
diff --git a/modules/FvwmTaskBar/FvwmTaskBar.c
b/modules/FvwmTaskBar/FvwmTaskBar.c
index 4034d6c..3e5d53b 100644
--- a/modules/FvwmTaskBar/FvwmTaskBar.c
+++ b/modules/FvwmTaskBar/FvwmTaskBar.c
@@ -1733,6 +1733,7 @@ void HandleEvents(
Bool moved = False;
int cx = win_x, cy = win_y;
+ fev_sanitise_configure_notify(evp);
/* eat up excess ConfigureNotify events. */
if (evp->xconfigure.send_event)
{
@@ -1743,6 +1744,7 @@ void HandleEvents(
evp_save = evp;
while (FCheckTypedWindowEvent(dpy, win, ConfigureNotify, evp))
{
+ fev_sanitise_configure_notify(evp);
evp_save = evp;
if (evp->xconfigure.send_event)
{
diff --git a/modules/FvwmWinList/FvwmWinList.c
b/modules/FvwmWinList/FvwmWinList.c
index 2132bbd..76ad718 100644
--- a/modules/FvwmWinList/FvwmWinList.c
+++ b/modules/FvwmWinList/FvwmWinList.c
@@ -954,6 +954,7 @@ void LoopOnEvents(void)
{
XEvent event;
+ fev_sanitise_configure_notify(&Event);
/* Opaque moves cause lots of these to be sent which causes flickering
* It's better to miss out on intermediate steps than to do them all
* and take too long. Look down the event queue and do the last one */
@@ -964,6 +965,7 @@ void LoopOnEvents(void)
* If it is false it comes from the Xserver and is bogus */
if (!event.xconfigure.send_event)
continue;
+ fev_sanitise_configure_notify(&event);
Event.xconfigure.x = event.xconfigure.x;
Event.xconfigure.y = event.xconfigure.y;
Event.xconfigure.send_event = True;
commit 4342f58f3c02f5fec1198b72f21804f90d94c2d5
Author: domivogt <domivogt>
Date: Sat Sep 20 14:00:48 2014 +0000
* Sanitise ConfigureRequest and ConfigureNotify events.
---
ChangeLog | 8 ++++++++
fvwm/events.c | 3 +++
2 files changed, 11 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 958b96b..8fab8da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * fvwm/events.c (__merge_cr_moveresize):
+ (__handle_configure_request):
+ Sanitise the geometry in ConfigureRequest events before using them.
+ (SendConfigureNotify):
+ Sanitise the geometry in ConfigureNotify events before sending them.
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* libs/FEvent.h:
* libs/FEvent.c (fev_sanitise_configure_request)
(fev_sanitise_configure_notify):
diff --git a/fvwm/events.c b/fvwm/events.c
index e62a3dc..50ef0ed 100644
--- a/fvwm/events.c
+++ b/fvwm/events.c
@@ -964,6 +964,7 @@ static inline int __merge_cr_moveresize(
/* not good. unselected event type! */
continue;
}
+ fev_sanitise_configure_request(cre);
/* Event was not yet removed from the queue but stored in e. */
xm = CWX | CWWidth;
ym = CWY | CWHeight;
@@ -1312,6 +1313,7 @@ void __handle_configure_request(
int do_send_event = 0;
int cn_count = 0;
+ fev_sanitise_configure_request(&cre);
/* According to the July 27, 1988 ICCCM draft, we should ignore size
* and position fields in the WM_NORMAL_HINTS property when we map a
* window. Instead, we'll read the current geometry. Therefore, we
@@ -4108,6 +4110,7 @@ void SendConfigureNotify(
(int)client_event.xconfigure.window,
(fw->name.name) ? fw->name.name : "");
#endif
+ fev_sanitise_configure_notify(&client_event);
FSendEvent(
dpy, FW_W(fw), False, StructureNotifyMask, &client_event);
if (send_for_frame_too)
commit 0e1c8dde9db82bd3b893bab254d9a9bb6d6bb2ba
Author: domivogt <domivogt>
Date: Sat Sep 20 14:00:21 2014 +0000
* New utility functions.
---
ChangeLog | 7 +++++++
libs/FEvent.c | 27 +++++++++++++++++++++++++++
libs/FEvent.h | 9 +++++++++
3 files changed, 43 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 384be93..958b96b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,13 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
* libs/FEvent.h:
+ * libs/FEvent.c (fev_sanitise_configure_request)
+ (fev_sanitise_configure_notify):
+ New utility functions
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
+ * libs/FEvent.h:
* libs/FEvent.c (FCheckWeedTypedWindowEvents, FWeedTypedWindowEvents):
* fvwm/icons.c (DrawIconWindow):
(DrawIconWindow):
diff --git a/libs/FEvent.c b/libs/FEvent.c
index 76882e9..131eb4c 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -368,6 +368,33 @@ void fev_get_last_event(XEvent *ev)
return;
}
+void fev_sanitise_configure_request(XConfigureRequestEvent *ev)
+{
+ if (ev->value_mask & CWX)
+ {
+ ev->x = (((int)ev->x) & 0xffff);
+ }
+ if (ev->value_mask & CWY)
+ {
+ ev->x = (((int)ev->y) & 0xffff);
+ }
+ if (ev->value_mask & CWWidth)
+ {
+ ev->width = (((unsigned int)ev->width) & 0xffff);
+ }
+ if (ev->value_mask & CWHeight)
+ {
+ ev->height = (((unsigned int)ev->height) & 0xffff);
+ ev->height &= 0xffff;
+ }
+ if (ev->value_mask & CWBorderWidth)
+ {
+ ev->border_width = (((unsigned int)ev->border_width) & 0xffff);
+ }
+
+ return;
+}
+
/* ---------------------------- Functions not present in Xlib -------------- */
int FWeedIfEvents(
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 42ad663..5796fcc 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -72,6 +72,15 @@ void fev_make_null_event(XEvent *ev, Display *dpy);
/* return a copy of the last XEVent in *ev */
void fev_get_last_event(XEvent *ev);
+/* Make sure the values in the event are in the defined range (e.g. x is and
+ * int, but the protocol uses only a 16 bit signed integer. */
+void fev_sanitise_configure_request(XConfigureRequestEvent *event);
+
+/* Same but for ConfigureNotify. It's actually the same function as the
+ * event structures are similar. */
+#define fev_sanitise_configure_notify(pe) \
+ fev_sanitise_configure_request((XConfigureRequestEvent *)(pe))
+
/* ---------------------------- Functions not present in Xlib -------------- */
/* Iterates over all events currentliy in the input queue and calls the
commit 90366e6ebc470d9130b38878c8438bdb25f66493
Author: domivogt <domivogt>
Date: Sat Sep 20 13:59:51 2014 +0000
* Replace last arument of FWeedTypedWindowEvents() with a pointer ...
... to store the last weeded event. Also renamed the function to
FCheckWeedTypedWindowEvents().
---
ChangeLog | 12 ++++++++++++
fvwm/icons.c | 4 ++--
fvwm/menus.c | 4 ++--
libs/FEvent.c | 38 +++++++++++++++++++++++++++++++++-----
libs/FEvent.h | 7 ++++---
5 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f90e6a0..384be93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * libs/FEvent.h:
+ * libs/FEvent.c (FCheckWeedTypedWindowEvents, FWeedTypedWindowEvents):
+ * fvwm/icons.c (DrawIconWindow):
+ (DrawIconWindow):
+ * fvwm/menus.c (__mloop_do_popup):
+ (select_menu_item):
+ Replace unused last argument from FWeedTypedWindowEvents and replace it
+ with a pointer to store the last matched event. Renamed the function
+ too.
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* fvwm/events.c (MAX_NUM_WEED_EVENT_TYPES):
(NUM_EVENTS_TO_PEEK):
(_weed_event_type_arg):
diff --git a/fvwm/icons.c b/fvwm/icons.c
index fa85cbd..a58a019 100644
--- a/fvwm/icons.c
+++ b/fvwm/icons.c
@@ -1383,7 +1383,7 @@ void DrawIconWindow(
{
if (!pev)
{
- FWeedTypedWindowEvents(
+ FCheckWeedTypedWindowEvents(
dpy, FW_W_ICON_TITLE(fw), Expose,
NULL);
}
@@ -1502,7 +1502,7 @@ void DrawIconWindow(
{
if (!pev)
{
- FWeedTypedWindowEvents(
+ FCheckWeedTypedWindowEvents(
dpy, FW_W_ICON_PIXMAP(fw), Expose,
NULL);
}
diff --git a/fvwm/menus.c b/fvwm/menus.c
index fcbd8bc..885eada 100644
--- a/fvwm/menus.c
+++ b/fvwm/menus.c
@@ -2850,7 +2850,7 @@ static void select_menu_item(
if (!MR_IS_PAINTED(mr))
{
- FWeedTypedWindowEvents(
+ FCheckWeedTypedWindowEvents(
dpy, MR_WINDOW(mr), Expose,
NULL);
paint_menu(mr, NULL, fw);
@@ -4858,7 +4858,7 @@ static mloop_ret_code_t __mloop_do_popup(
if (!MR_IS_PAINTED(pmp->menu))
{
/* draw the parent menu if it is not already drawn */
- FWeedTypedWindowEvents(
+ FCheckWeedTypedWindowEvents(
dpy, MR_WINDOW(pmp->menu), Expose, NULL);
paint_menu(pmp->menu, NULL, (*pmp->pexc)->w.fw);
}
diff --git a/libs/FEvent.c b/libs/FEvent.c
index adcdbaa..76882e9 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -51,6 +51,8 @@ typedef struct
typedef struct
{
int (*weed_predicate) (Display *display, XEvent *event, XPointer arg);
+ XEvent *last_event;
+ XEvent *ret_last_weeded_event;
XPointer arg;
Window w;
int event_type;
@@ -178,8 +180,15 @@ static Bool _fev_pred_weed_if(Display *display, XEvent
*event, XPointer arg)
}
if (rc & 1)
{
- /* invalidate event by setting a bogus event type */
- event->type = fev_invalid_event_type;
+ /* We invalidate events only when the next event to invalidate
+ * is found. This way we avoid having to copy all events as
+ * each one could be the last. */
+ if (weed_args->last_event != NULL)
+ {
+ /* invalidate event by setting a bogus event type */
+ weed_args->last_event->type = fev_invalid_event_type;
+ }
+ weed_args->last_event = event;
weed_args->count++;
}
ret = (rc & 2) ? True : False;
@@ -187,6 +196,22 @@ static Bool _fev_pred_weed_if(Display *display, XEvent
*event, XPointer arg)
return ret;
}
+static void _fev_pred_weed_if_finish(_fev_weed_args *weed_args)
+{
+ if (weed_args->count != 0)
+ {
+ if (weed_args->ret_last_weeded_event != NULL)
+ {
+ *weed_args->ret_last_weeded_event =
+ *weed_args->last_event;
+ }
+ /* invalidate event by setting a bogus event type */
+ weed_args->last_event->type = fev_invalid_event_type;
+ }
+
+ return;
+}
+
/* ---------------------------- interface functions (privileged access) -----
*/
void fev_copy_last_event(XEvent *dest)
@@ -361,6 +386,7 @@ int FWeedIfEvents(
FCheckPeekIfEvent(
display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
/* e is discarded */
+ _fev_pred_weed_if_finish(&weed_args);
return weed_args.count;
}
@@ -383,26 +409,28 @@ int FWeedIfWindowEvents(
FCheckPeekIfEvent(
display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
/* e is discarded */
+ _fev_pred_weed_if_finish(&weed_args);
return weed_args.count;
}
-int FWeedTypedWindowEvents(
- Display *display, Window window, int event_type, XPointer arg)
+int FCheckWeedTypedWindowEvents(
+ Display *display, Window window, int event_type, XEvent *last_event)
{
_fev_weed_args weed_args;
XEvent e;
assert(fev_is_invalid_event_type_set);
memset(&weed_args, 0, sizeof(weed_args));
- weed_args.arg = arg;
weed_args.w = window;
weed_args.event_type = event_type;
weed_args.has_window = 1;
weed_args.has_event_type = 1;
+ weed_args.ret_last_weeded_event = last_event;
FCheckPeekIfEvent(
display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
/* e is discarded */
+ _fev_pred_weed_if_finish(&weed_args);
return weed_args.count;
}
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 7d19518..42ad663 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -112,9 +112,10 @@ int FWeedIfWindowEvents(
XPointer arg);
/* Same as FWeedIfEvents but weeds only events of the given type for the given
- window. */
-int FWeedTypedWindowEvents(
- Display *display, Window window, int event_type, XPointer arg);
+ * window. If last_event is not NULL, a copy of the last weeded event is
+ * returned through *last_event (valid if a value > 0 is treturned). */
+int FCheckWeedTypedWindowEvents(
+ Display *display, Window window, int event_type, XEvent *last_event);
/* Like FCheckIfEvent but does not remove the event from the queue. */
int FCheckPeekIfEvent(
commit cab28b9ed7573b733daed299c69602f01187d647
Author: domivogt <domivogt>
Date: Sat Sep 20 11:41:55 2014 +0000
* ChangeLog
---
ChangeLog | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 65ec257..f90e6a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,62 @@
2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * fvwm/events.c (MAX_NUM_WEED_EVENT_TYPES):
+ (NUM_EVENTS_TO_PEEK):
+ (_weed_event_type_arg):
+ (_weed_window_mask_events_arg):
+ (_pred_weed_accumulate_expose):
+ (_pred_weed_handle_expose):
+ (_pred_weed_event_type):
+ (_pred_flush_property_notify_weed, HandlePropertyNotify)
+ (__merge_cr_moveresize, HandleReparentNotify, HandleEvents):
+ (flush_accumulate_expose):
+ (handle_all_expose):
+ (discard_typed_events):
+ (flush_property_notify_stop_at_event_type):
+ (discard_events):
+ Rewrite event discarding code.
+
+ * fvwm/events.c (flush_expose):
+ (discard_window_events):
+ (check_for_another_property_notify):
+ Removed obsolete functions.
+
+ * fvwm/events.c (_pred_button_click, __predicate_button_click):
+ (_pred_flush_property_notify_weed, test_typed_window_event):
+ (discard_typed_events, discard_events):
+ Renamed functions
+
+ * fvwm/events.h:
+ Deleted and renamed some interfaces.
+ (flush_property_notify_args):
+ (test_typed_window_event_args):
+ Renamed structure
+
+ * fvwm/add_window.c (do_recapture):
+ When reparenting fails, throw away only window events, not all events.
+
+ * fvwm/virtual.c (HandlePaging):
+ * fvwm/move_resize.c (InteractiveMove):
+ (__resize_window):
+ * fvwm/menus.c (select_menu_item):
+ (__mloop_do_popup):
+ (_pred_menu_window_weed_events):
+ (menu_tear_off):
+ * fvwm/icons.c (DrawIconWindow):
+ * fvwm/ewmh_events.c (EWMH_ProcessPropertyNotify):
+ * fvwm/add_window.c (do_recapture):
+ Adapt to new event discarding code.
+
+ * fvwm/fvwm.c (main):
+ Call fev_init_invalid_event_type(KeymapNotify)
+
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* libs/FEvent.h (FEV_IS_EVENT_INVALID):
(FEV_HAS_EVENT_WINDOW):
- New helper macros
+ (fev_is_invalid_event_type_set):
+ (fev_invalid_event_type):
+ New helper macros and globals that are used in the macros
* libs/FEvent.c (fev_init_invalid_event_type):
(WeedIfEvents):
commit 5c0b139522218a269ea5c98843bcef81c0240d21
Author: domivogt <domivogt>
Date: Sat Sep 20 11:25:46 2014 +0000
* FEvent.[ch] cleanup and ChangeLog.
---
ChangeLog | 29 +++++++++++++++++++++++++++++
libs/FEvent.c | 23 ++++++++---------------
libs/FEvent.h | 3 ---
3 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5c7ab60..65ec257 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2014-09-20 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
+ * libs/FEvent.h (FEV_IS_EVENT_INVALID):
+ (FEV_HAS_EVENT_WINDOW):
+ New helper macros
+
+ * libs/FEvent.c (fev_init_invalid_event_type):
+ (WeedIfEvents):
+ (FWeedIfWindowEvents):
+ (FWeedTypedWindowEvents):
+ (_fev_weed_args, _fev_pred_weed_if):
+ New library functions to allow weeding unwanted events from the input
+ queue.
+
+ * libs/FEvent.c (_fev_pred_check_peek):
+ (_fev_check_peek_args):
+ (FCheckPeekIfEvent):
+ Rewritten
+
+ * libs/FEvent.c (FCheckPeekIfEventWithLimit):
+ Removed obsolete function.
+
+ * libs/FEvent.c (_fev_check_peek_args, fev_check_peek_args):
+ (_fev_pred_check_peek, fev_check_peek_pred):
+ Renamed
+
+ * libs/FEvent.c (fev_check_peek_invalidate_args):
+ Removed unused struct
+
2014-09-19 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
* fvwm/events.c (HandleReparentNotify):
diff --git a/libs/FEvent.c b/libs/FEvent.c
index 2613f44..adcdbaa 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -46,14 +46,7 @@ typedef struct
XPointer arg;
XEvent event;
Bool found;
-} fev_check_peek_args;
-
-typedef struct
-{
- Bool (*predicate) (Display *display, XEvent *event, XPointer arg);
- XPointer arg;
- int count;
-} fev_check_peek_invalidate_args;
+} _fev_check_peek_args;
typedef struct
{
@@ -65,7 +58,7 @@ typedef struct
char has_predicate;
char has_window;
char has_event_type;
-} fev_weed_args;
+} _fev_weed_args;
/* ---------------------------- forward declarations ----------------------- */
@@ -135,7 +128,7 @@ static void fev_update_last_timestamp(const XEvent *ev)
static Bool _fev_pred_check_peek(
Display *display, XEvent *event, XPointer arg)
{
- fev_check_peek_args *cpa = (fev_check_peek_args *)arg;
+ _fev_check_peek_args *cpa = (_fev_check_peek_args *)arg;
if (cpa->found == True)
{
@@ -152,7 +145,7 @@ static Bool _fev_pred_check_peek(
static Bool _fev_pred_weed_if(Display *display, XEvent *event, XPointer arg)
{
- fev_weed_args *weed_args = (fev_weed_args *)arg;
+ _fev_weed_args *weed_args = (_fev_weed_args *)arg;
Bool ret;
int rc;
@@ -357,7 +350,7 @@ int FWeedIfEvents(
int (*weed_predicate) (Display *display, XEvent *event, XPointer arg),
XPointer arg)
{
- fev_weed_args weed_args;
+ _fev_weed_args weed_args;
XEvent e;
assert(fev_is_invalid_event_type_set);
@@ -378,7 +371,7 @@ int FWeedIfWindowEvents(
Display *display, XEvent *current_event, XPointer arg),
XPointer arg)
{
- fev_weed_args weed_args;
+ _fev_weed_args weed_args;
XEvent e;
assert(fev_is_invalid_event_type_set);
@@ -397,7 +390,7 @@ int FWeedIfWindowEvents(
int FWeedTypedWindowEvents(
Display *display, Window window, int event_type, XPointer arg)
{
- fev_weed_args weed_args;
+ _fev_weed_args weed_args;
XEvent e;
assert(fev_is_invalid_event_type_set);
@@ -420,7 +413,7 @@ Bool FCheckPeekIfEvent(
XPointer arg)
{
XEvent dummy;
- fev_check_peek_args cpa;
+ _fev_check_peek_args cpa;
cpa.predicate = predicate;
cpa.arg = arg;
diff --git a/libs/FEvent.h b/libs/FEvent.h
index 877c691..7d19518 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -7,9 +7,6 @@
/* ---------------------------- global definitions ------------------------- */
-/* A value guaranteed to be neither True nor False. */
-#define FEV_INVALID_BOOL (True + True - False)
-
#define FEV_IS_EVENT_INVALID(e) \
(fev_is_invalid_event_type_set && (e).type == fev_invalid_event_type)
commit 0501f18b85f8cec6c9e7668023f3ca9ef1eb3a0a
Merge: 7d36bd5 eaab7ef
Author: Thomas Adam <[email protected]>
Date: Sat Sep 20 01:35:16 2014 +0100
Merge remote-tracking branch 'cvs/branch-2_6' into branch-2_6
commit eaab7efc764bd1bf1de3f3b8d0d57219f22799bb
Author: domivogt <domivogt>
Date: Sat Sep 20 00:28:58 2014 +0000
* Rewrite event discarding code.
---
ChangeLog | 6 ++
NEWS | 3 +
fvwm/add_window.c | 7 +-
fvwm/events.c | 290 ++++++++++++++++++++++++++---------------------------
fvwm/events.h | 18 ++--
fvwm/ewmh_events.c | 13 +--
fvwm/fvwm.c | 3 +
fvwm/icons.c | 8 +-
fvwm/menus.c | 33 +++++-
fvwm/move_resize.c | 8 +-
fvwm/virtual.c | 8 +-
libs/FEvent.c | 242 +++++++++++++++++++++++++++++++-------------
libs/FEvent.h | 86 +++++++++++++---
13 files changed, 459 insertions(+), 266 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 09ade16..5c7ab60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2014-09-19 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+ * fvwm/events.c (HandleReparentNotify):
+ if reparenting fails, only throw away events for the frame window, not
+ _all_ events
+
+2014-09-19 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
* fvwm/add_window.c (GetWindowSizeHintsWithCheck):
fix uninitialised zero fw->orig_hints.width/height_inc
diff --git a/NEWS b/NEWS
index 4ff0a5b..b31ba4e 100644
--- a/NEWS
+++ b/NEWS
@@ -62,6 +62,9 @@ Changes in stable release 2.6.6 (not released yet)
commend did not work correctly. This has been fixed.
- Removes a slight graphics problem whith the ResizeMaximize
command being invoked from a window button menu.
+ - When an attempt to reparent a client window (i.e. decorate
+ it) fails, fvwm no longer throws away all events but only the
+ events for that window.
-------------------------------------------------------------------
Changes in stable release 2.6.5 (20-Apr-2012)
diff --git a/fvwm/add_window.c b/fvwm/add_window.c
index 6c2f7cc..226cfbd 100644
--- a/fvwm/add_window.c
+++ b/fvwm/add_window.c
@@ -391,6 +391,9 @@ static int MappedNotOverride(
static void do_recapture(F_CMD_ARGS, Bool fSingle)
{
FvwmWindow *fw = exc->w.fw;
+ int event_types[5] = {
+ ButtonPress, ButtonRelease, MotionNotify, KeyPress, KeyRelease
+ };
MyXGrabServer(dpy);
if (fSingle)
@@ -407,9 +410,7 @@ static void do_recapture(F_CMD_ARGS, Bool fSingle)
* same moment and the click goes through to the root window. Not good
*/
XAllowEvents(dpy, AsyncPointer, CurrentTime);
- discard_events(
- ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| \
- PointerMotionMask|KeyPressMask|KeyReleaseMask);
+ discard_typed_events(5, event_types);
#ifdef DEBUG_STACK_RING
verify_stack_ring_consistency();
#endif
diff --git a/fvwm/events.c b/fvwm/events.c
index 281bde1..e62a3dc 100644
--- a/fvwm/events.c
+++ b/fvwm/events.c
@@ -53,6 +53,7 @@
#include <stdio.h>
#include <unistd.h>
+#include <assert.h>
#include <X11/Xatom.h>
#include "libs/ftime.h"
@@ -113,7 +114,7 @@
#define DEBUG_GLOBALLY_ACTIVE 1
-#define NUM_EVENTS_TO_PEEK 200
+#define MAX_NUM_WEED_EVENT_TYPES 40
/* ---------------------------- local macros ------------------------------- */
@@ -153,6 +154,17 @@ typedef struct event_group
struct event_group *next;
} event_group_t;
+typedef struct
+{
+ int num_event_types;
+ int event_types[MAX_NUM_WEED_EVENT_TYPES];
+} _weed_event_type_arg;
+
+typedef struct
+{
+ long event_mask;
+} _weed_window_mask_events_arg;
+
/* ---------------------------- forward declarations ----------------------- */
/* ---------------------------- local variables ---------------------------- */
@@ -258,30 +270,104 @@ static Bool test_withdraw_request(
return rc;
}
-Bool test_button_event(
+static int _pred_weed_accumulate_expose(
+ Display *display, XEvent *ev, XPointer arg)
+{
+ XEvent *em = (XEvent *)arg;
+
+ if (ev->type != Expose)
+ {
+ return 0;
+ }
+ {
+ int x0;
+ int x1;
+
+ x1 = max(
+ ev->xexpose.x + ev->xexpose.width,
+ em->xexpose.x + em->xexpose.width);
+ x0 = min(em->xexpose.x, ev->xexpose.x);
+ em->xexpose.x = x0;
+ em->xexpose.width = x1 - x0;
+ }
+ {
+ int y0;
+ int y1;
+
+ y1 = max(
+ ev->xexpose.y + ev->xexpose.height,
+ em->xexpose.y + em->xexpose.height);
+ y0 = min(em->xexpose.y, ev->xexpose.y);
+ em->xexpose.y = y0;
+ em->xexpose.height = y1 - y0;
+ }
+
+ return 1;
+}
+
+static int _pred_weed_handle_expose(
Display *display, XEvent *event, XPointer arg)
{
- if (event->type == ButtonPress || event->type == ButtonRelease)
+ if (event->type == Expose)
{
- return True;
+ dispatch_event(event);
+ return 1;
}
+ else
+ {
+ return 0;
+ }
+}
- return False;
+static int _pred_weed_event_type(
+ Display *display, XEvent *event, XPointer arg)
+{
+ _weed_event_type_arg *args = (_weed_event_type_arg *)arg;
+ int i;
+
+ for (i = 0; i < args->num_event_types; i++)
+ {
+ if (event->type == args->event_types[i])
+ {
+ /* invalidate event and continue weeding */
+ return 1;
+ }
+ }
+
+ /* keep event and continue weeding */
+ return 0;
}
-Bool test_typed_window_event(
+static int _pred_flush_property_notify_weed(
Display *display, XEvent *event, XPointer arg)
{
- test_typed_window_event_args *ta = (test_typed_window_event_args *)arg;
+ flush_property_notify_args *args =
+ (flush_property_notify_args *)arg;
+ int does_match_window;
- if (event->xany.window == ta->w &&
- event->xany.type == ta->event_type &&
- event->xproperty.atom == ta->atom)
+ does_match_window = (
+ FEV_HAS_EVENT_WINDOW(event->type) &&
+ event->xany.window == args->w) ? 1 : 0;
+ if (
+ does_match_window &&
+ event->type == args->event_type &&
+ event->xproperty.atom == args->atom)
{
- return True;
+ /* invalidate event and continue weeding */
+ return 1;
+ }
+ else if (
+ args->do_stop_at_event_type &&
+ event->type == args->stop_at_event_type && (
+ !FEV_HAS_EVENT_WINDOW(args->stop_at_event_type) ||
+ does_match_window))
+ {
+ /* keep event and stop weeding */
+ return 2;
}
- return False;
+ /* keep event and continue weeding */
+ return 0;
}
static Bool test_resizing_event(
@@ -1285,7 +1371,7 @@ void __handle_configure_request(
return;
}
-static Bool __predicate_button_click(
+static Bool _pred_button_click(
Display *display, XEvent *event, XPointer arg)
{
if (event->type == ButtonPress || event->type == ButtonRelease)
@@ -1333,7 +1419,7 @@ static Bool __test_for_motion(int x0, int y0)
/* the pointer has moved */
return True;
}
- if (FCheckPeekIfEvent(dpy, &e, __predicate_button_click, NULL))
+ if (FCheckPeekIfEvent(dpy, &e, _pred_button_click, NULL))
{
/* click in the future */
return False;
@@ -3357,17 +3443,8 @@ void HandlePropertyNotify(const evh_args_t *ea)
}
case XA_WM_NAME:
{
- int n;
- int pos;
-
- pos = check_for_another_property_notify(
- te->xproperty.atom, FW_W(fw), &n);
- if (pos > 0)
- {
- /* Another PropertyNotify for this atom is pending,
- * skip the current one. */
- return;
- }
+ flush_property_notify_stop_at_event_type(
+ te->xproperty.atom, FW_W(fw), 0, 0);
if (XGetGeometry(
dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY,
(unsigned int*)&JunkWidth,
@@ -3446,17 +3523,8 @@ void HandlePropertyNotify(const evh_args_t *ea)
}
case XA_WM_ICON_NAME:
{
- int n;
- int pos;
-
- pos = check_for_another_property_notify(
- te->xproperty.atom, FW_W(fw), &n);
- if (pos > 0)
- {
- /* Another PropertyNotify for this atom is pending,
- * skip the current one. */
- return;
- }
+ flush_property_notify_stop_at_event_type(
+ te->xproperty.atom, FW_W(fw), 0, 0);
if (XGetGeometry(
dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY,
(unsigned int*)&JunkWidth,
@@ -3513,17 +3581,8 @@ void HandlePropertyNotify(const evh_args_t *ea)
}
case XA_WM_HINTS:
{
- int n;
- int pos;
-
- pos = check_for_another_property_notify(
- te->xproperty.atom, FW_W(fw), &n);
- if (pos > 0)
- {
- /* Another PropertyNotify for this atom is pending,
- * skip the current one. */
- return;
- }
+ flush_property_notify_stop_at_event_type(
+ te->xproperty.atom, FW_W(fw), 0, 0);
if (XGetGeometry(
dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY,
(unsigned int*)&JunkWidth,
@@ -3764,7 +3823,8 @@ void HandleReparentNotify(const evh_args_t *ea)
{
XSelectInput(dpy, te->xreparent.window, XEVMASK_MENUW);
}
- discard_events(XEVMASK_FRAMEW);
+ XSync(dpy, 0);
+ FWeedIfWindowEvents(dpy, FW_W_FRAME(fw), NULL, NULL);
destroy_window(fw);
EWMH_ManageKdeSysTray(te->xreparent.window, te->type);
EWMH_WindowDestroyed();
@@ -4279,6 +4339,14 @@ void HandleEvents(void)
}
if (My_XNextEvent(dpy, &ev))
{
+ /* DV (19-Sep-2014): We mark events as invalid by
+ * setting the send_event field to a bogus value in a
+ * predicate procedure. It's unsure whether this works
+ * reliably. */
+ if (FEV_IS_EVENT_INVALID(ev))
+ {
+ continue;
+ }
dispatch_event(&ev);
}
if (Scr.flags.do_need_style_list_update)
@@ -4593,48 +4661,13 @@ int GetContext(FvwmWindow **ret_fw, FvwmWindow *t,
const XEvent *e, Window *w)
return context;
}
-/*
- *
- * Removes expose events for a specific window from the queue
- *
- */
-int flush_expose(Window w)
-{
- XEvent dummy;
- int i=0;
-
- while (FCheckTypedWindowEvent(dpy, w, Expose, &dummy))
- {
- i++;
- }
-
- return i;
-}
-
-/* same as above, but merges the expose rectangles into a single big one */
-int flush_accumulate_expose(Window w, XEvent *e)
+/* Drops all expose events for the given window from the input queue and merges
+ * the expose rectangles into a single big one (*e). */
+void flush_accumulate_expose(Window w, XEvent *e)
{
- XEvent dummy;
- int i = 0;
- int x1 = e->xexpose.x;
- int y1 = e->xexpose.y;
- int x2 = x1 + e->xexpose.width;
- int y2 = y1 + e->xexpose.height;
-
- while (FCheckTypedWindowEvent(dpy, w, Expose, &dummy))
- {
- x1 = min(x1, dummy.xexpose.x);
- y1 = min(y1, dummy.xexpose.y);
- x2 = max(x2, dummy.xexpose.x + dummy.xexpose.width);
- y2 = max(y2, dummy.xexpose.y + dummy.xexpose.height);
- i++;
- }
- e->xexpose.x = x1;
- e->xexpose.y = y1;
- e->xexpose.width = x2 - x1;
- e->xexpose.height = y2 - y1;
+ FWeedIfWindowEvents(dpy, w, _pred_weed_accumulate_expose, (XPointer)e);
- return i;
+ return;
}
/*
@@ -4645,14 +4678,10 @@ int flush_accumulate_expose(Window w, XEvent *e)
void handle_all_expose(void)
{
void *saved_event;
- XEvent evdummy;
saved_event = fev_save_event();
FPending(dpy);
- while (FCheckMaskEvent(dpy, ExposureMask, &evdummy))
- {
- dispatch_event(&evdummy);
- }
+ FWeedIfEvents(dpy, _pred_weed_handle_expose, NULL);
fev_restore_event(saved_event);
return;
@@ -4716,81 +4745,42 @@ void CoerceEnterNotifyOnCurrentWindow(void)
return;
}
-/* This function discards all queued up ButtonPress, ButtonRelease and
- * ButtonMotion events. */
-int discard_events(long event_mask)
+/* This function discards all queued up events selected by the mask. */
+int discard_typed_events(int num_event_types, int *event_types)
{
- XEvent e;
+ _weed_event_type_arg args;
int count;
+ int i;
XSync(dpy, 0);
- for (count = 0; FCheckMaskEvent(dpy, event_mask, &e); count++)
+ assert(num_event_types <= MAX_NUM_WEED_EVENT_TYPES);
+ args.num_event_types = num_event_types;
+ for (i = 0; i < num_event_types; i++)
{
- /* nothing */
- }
-
- return count;
-}
-
-/* This function discards all queued up ButtonPress, ButtonRelease and
- * ButtonMotion events. */
-int discard_window_events(Window w, long event_mask)
-{
- XEvent e;
- int count;
-
- XSync(dpy, 0);
- for (count = 0; FCheckWindowEvent(dpy, w, event_mask, &e); count++)
- {
- /* nothing */
+ args.event_types[i] = event_types[i];
}
+ count = FWeedIfEvents(dpy, _pred_weed_event_type, (XPointer)&args);
return count;
}
/* Similar function for certain types of PropertyNotify. */
-int check_for_another_property_notify(
- Atom atom, Window w, int *num_events_removed)
+int flush_property_notify_stop_at_event_type(
+ Atom atom, Window w, char do_stop_at_event_type,
+ int stop_at_event_type)
{
- test_typed_window_event_args args;
- XEvent e;
- int pos;
- int do_loop;
+ flush_property_notify_args args;
- *num_events_removed = 0;
XSync(dpy, 0);
args.w = w;
args.atom = atom;
args.event_type = PropertyNotify;
- /* Get rid of the events. */
- for (
- *num_events_removed = 0, do_loop = 1; do_loop;
- (*num_events_removed)++)
- {
- pos = FCheckPeekIfEventWithLimit(
- dpy, &e, test_typed_window_event, (XPointer)&args,
- NUM_EVENTS_TO_PEEK);
- switch (pos)
- {
- case 1:
- {
- /* Strip leadind events from the queue. */
- FNextEvent(dpy, &e);
- /* keep going */
- continue;
- }
- case 0:
- /* No more events found. */
- do_loop = 0;
- break;
- default:
- /* Event left, but not at the front of the queue. */
- do_loop = 0;
- break;
- }
- }
+ args.stop_at_event_type = stop_at_event_type;
+ args.do_stop_at_event_type = do_stop_at_event_type;
+ FWeedIfEvents(
+ dpy, _pred_flush_property_notify_weed, (XPointer)&args);
- return pos;
+ return 0;
}
/* Wait for all mouse buttons to be released
diff --git a/fvwm/events.h b/fvwm/events.h
index 334c351..4b65115 100644
--- a/fvwm/events.h
+++ b/fvwm/events.h
@@ -14,9 +14,11 @@
typedef struct
{
Window w;
- int event_type;
Atom atom;
-} test_typed_window_event_args;
+ int event_type;
+ int stop_at_event_type;
+ char do_stop_at_event_type;
+} flush_property_notify_args;
/* ---------------------------- forward declarations ----------------------- */
@@ -27,8 +29,7 @@ typedef struct
void dispatch_event(XEvent *e);
int GetContext(FvwmWindow **ret_fw, FvwmWindow *t, const XEvent *e, Window *w);
int My_XNextEvent(Display *dpy, XEvent *event);
-int flush_expose(Window w);
-int flush_accumulate_expose(Window w, XEvent *e);
+void flush_accumulate_expose(Window w, XEvent *e);
void handle_all_expose(void);
Bool StashEventTime(const XEvent *ev);
void CoerceEnterNotifyOnCurrentWindow(void);
@@ -37,16 +38,15 @@ void SendConfigureNotify(
FvwmWindow *fw, int x, int y, int w, int h, int bw,
Bool send_for_frame_too);
void WaitForButtonsUp(Bool do_handle_expose);
-int discard_events(long event_mask);
-int discard_window_events(Window w, long event_mask);
-int check_for_another_property_notify(
- Atom atom, Window w, int *num_events_removed);
+int discard_typed_events(int num_event_types, int *event_types);
+int flush_property_notify_stop_at_event_type(
+ Atom atom, Window w, char do_stop_at_event_type,
+ int stop_at_event_type);
void sync_server(int toggle);
Bool is_resizing_event_pending(FvwmWindow *fw);
void events_handle_configure_request(
XConfigureRequestEvent cre, FvwmWindow *fw, Bool force_use_grav,
int force_gravity);
-Bool test_button_event(Display *display, XEvent *event, char *arg);
Bool test_typed_window_event(Display *display, XEvent *event, char *arg);
#endif /* EVENTS_H */
diff --git a/fvwm/ewmh_events.c b/fvwm/ewmh_events.c
index 37558ba..b89cc42 100644
--- a/fvwm/ewmh_events.c
+++ b/fvwm/ewmh_events.c
@@ -1617,17 +1617,8 @@ void EWMH_ProcessPropertyNotify(const exec_context_t
*exc)
{
if (ewmh_a->action != None)
{
- int n;
- int pos;
-
- pos = check_for_another_property_notify(
- ev->xproperty.atom, FW_W(fw), &n);
- if (pos > 0)
- {
- /* Another PropertyNotify for this atom is
- * pending, skip the current one. */
- return;
- }
+ flush_property_notify_stop_at_event_type(
+ ev->xproperty.atom, FW_W(fw), 0, 0);
if (XGetGeometry(
dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY,
(unsigned int*)&JunkWidth,
diff --git a/fvwm/fvwm.c b/fvwm/fvwm.c
index 84d5205..e4d638b 100644
--- a/fvwm/fvwm.c
+++ b/fvwm/fvwm.c
@@ -1785,6 +1785,9 @@ int main(int argc, char **argv)
DBUG("main", "Entered, about to parse args");
fvwmlib_init_max_fd();
+ /* Tell the FEvent module an event type that is not used by fvwm. */
+ fev_init_invalid_event_type(KeymapNotify);
+
/* close open fds */
for (i = 3; i < fvwmlib_max_fd; i++)
{
diff --git a/fvwm/icons.c b/fvwm/icons.c
index a29d281..fa85cbd 100644
--- a/fvwm/icons.c
+++ b/fvwm/icons.c
@@ -1383,7 +1383,9 @@ void DrawIconWindow(
{
if (!pev)
{
- flush_expose(FW_W_ICON_TITLE(fw));
+ FWeedTypedWindowEvents(
+ dpy, FW_W_ICON_TITLE(fw), Expose,
+ NULL);
}
DrawIconTitleWindow(
fw, pev, BackColor, Shadow, Relief, cs,
@@ -1500,7 +1502,9 @@ void DrawIconWindow(
{
if (!pev)
{
- flush_expose(FW_W_ICON_PIXMAP(fw));
+ FWeedTypedWindowEvents(
+ dpy, FW_W_ICON_PIXMAP(fw), Expose,
+ NULL);
}
DrawIconPixmapWindow(
fw, reset_bg, pev, Shadow, Relief, cs);
diff --git a/fvwm/menus.c b/fvwm/menus.c
index f7e93df..fcbd8bc 100644
--- a/fvwm/menus.c
+++ b/fvwm/menus.c
@@ -2850,7 +2850,9 @@ static void select_menu_item(
if (!MR_IS_PAINTED(mr))
{
- flush_expose(MR_WINDOW(mr));
+ FWeedTypedWindowEvents(
+ dpy, MR_WINDOW(mr), Expose,
+ NULL);
paint_menu(mr, NULL, fw);
}
iy = MI_Y_OFFSET(mi);
@@ -4856,7 +4858,8 @@ static mloop_ret_code_t __mloop_do_popup(
if (!MR_IS_PAINTED(pmp->menu))
{
/* draw the parent menu if it is not already drawn */
- flush_expose(MR_WINDOW(pmp->menu));
+ FWeedTypedWindowEvents(
+ dpy, MR_WINDOW(pmp->menu), Expose, NULL);
paint_menu(pmp->menu, NULL, (*pmp->pexc)->w.fw);
}
/* get pos hints for item's action */
@@ -5567,6 +5570,26 @@ static char *menu_strip_tear_off_title(MenuRoot *mr)
return name;
}
+static int _pred_menu_window_weed_events(
+ Display *display, XEvent *event, XPointer arg)
+{
+ switch (event->type)
+ {
+ case CirculateNotify:
+ case ConfigureNotify:
+ case CreateNotify:
+ case DestroyNotify:
+ case GravityNotify:
+ case MapNotify:
+ case ReparentNotify:
+ case UnmapNotify:
+ /* events in SubstructureNotifyMask */
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static void menu_tear_off(MenuRoot *mr_to_copy)
{
MenuRoot *mr;
@@ -5594,8 +5617,10 @@ static void menu_tear_off(MenuRoot *mr_to_copy)
/* keep the menu open */
if (MR_WINDOW(mr_to_copy) != None)
{
- discard_window_events(
- MR_WINDOW(mr_to_copy), SubstructureNotifyMask);
+ XSync(dpy, 0);
+ FWeedIfWindowEvents(
+ dpy, MR_WINDOW(mr_to_copy),
+ _pred_menu_window_weed_events, NULL);
}
mr = clone_menu(mr_to_copy);
/* also dump the menu style */
diff --git a/fvwm/move_resize.c b/fvwm/move_resize.c
index 4da4bc7..ac3233d 100644
--- a/fvwm/move_resize.c
+++ b/fvwm/move_resize.c
@@ -1313,8 +1313,10 @@ static void InteractiveMove(
if (!do_move_opaque)
{
+ int event_types[2] = { EnterNotify, LeaveNotify };
+
/* Throw away some events that dont interest us right now. */
- discard_events(EnterWindowMask|LeaveWindowMask);
+ discard_typed_events(2, event_types);
Scr.flags.is_wire_frame_displayed = False;
MyXUngrabServer(dpy);
}
@@ -4335,8 +4337,10 @@ static Bool __resize_window(F_CMD_ARGS)
ResizeWindow = None;
if (!do_resize_opaque)
{
+ int event_types[2] = { EnterNotify, LeaveNotify };
+
/* Throw away some events that dont interest us right now. */
- discard_events(EnterWindowMask|LeaveWindowMask);
+ discard_typed_events(2, event_types);
Scr.flags.is_wire_frame_displayed = False;
MyXUngrabServer(dpy);
}
diff --git a/fvwm/virtual.c b/fvwm/virtual.c
index c70b1e8..e71def8 100644
--- a/fvwm/virtual.c
+++ b/fvwm/virtual.c
@@ -95,6 +95,12 @@ static int prev_desk_and_page_page_y = 0;
/* ---------------------------- local functions ---------------------------- */
+static Bool _pred_button_event(Display *display, XEvent *event, XPointer arg)
+{
+ return (event->type == ButtonPress || event->type == ButtonRelease) ?
+ True : False;
+}
+
static void __drag_viewport(const exec_context_t *exc, int scroll_speed)
{
XEvent e;
@@ -696,7 +702,7 @@ int HandlePaging(
int JunkC;
unsigned int JunkM;
- if (FCheckPeekIfEvent(dpy, &e, test_button_event, NULL))
+ if (FCheckPeekIfEvent(dpy, &e, _pred_button_event, NULL))
{
is_timestamp_valid = False;
add_time = 0;
diff --git a/libs/FEvent.c b/libs/FEvent.c
index 2f040f3..2613f44 100644
--- a/libs/FEvent.c
+++ b/libs/FEvent.c
@@ -26,6 +26,7 @@
#undef FEVENT_PRIVILEGED_ACCESS
#include <stdio.h>
+#include <assert.h>
#include "libs/ftime.h"
@@ -43,14 +44,29 @@ typedef struct
{
Bool (*predicate) (Display *display, XEvent *event, XPointer arg);
XPointer arg;
- /* The maximum number of events to check, or 0 for unlimited. */
- int max_num_events;
- /* Keeps track of the position in the event queue (1 = first event).
- * Also returns the position in the queue where the first matching
- * event was found or 0 if none was found. */
- int event_count;
+ XEvent event;
+ Bool found;
} fev_check_peek_args;
+typedef struct
+{
+ Bool (*predicate) (Display *display, XEvent *event, XPointer arg);
+ XPointer arg;
+ int count;
+} fev_check_peek_invalidate_args;
+
+typedef struct
+{
+ int (*weed_predicate) (Display *display, XEvent *event, XPointer arg);
+ XPointer arg;
+ Window w;
+ int event_type;
+ int count;
+ char has_predicate;
+ char has_window;
+ char has_event_type;
+} fev_weed_args;
+
/* ---------------------------- forward declarations ----------------------- */
/* ---------------------------- local variables ---------------------------- */
@@ -58,10 +74,13 @@ typedef struct
static XEvent fev_event;
static XEvent fev_event_old;
/* until Xlib does this for us */
-Time fev_last_timestamp = CurrentTime;
+static Time fev_last_timestamp = CurrentTime;
/* ---------------------------- exported variables (globals) --------------- */
+char fev_is_invalid_event_type_set = 0;
+int fev_invalid_event_type;
+
/* ---------------------------- local functions ---------------------------- */
/* Records the time of the last processed event. */
@@ -113,31 +132,68 @@ static void fev_update_last_timestamp(const XEvent *ev)
return;
}
-static Bool fev_check_peek_pred(
- Display *display, XEvent *event, XPointer arg)
+static Bool _fev_pred_check_peek(
+ Display *display, XEvent *event, XPointer arg)
{
fev_check_peek_args *cpa = (fev_check_peek_args *)arg;
- Bool is_match;
- is_match = cpa->predicate(display, event, cpa->arg);
- if (is_match == True)
+ if (cpa->found == True)
{
- /* Found a matching event, stop looking. */
- return True;
+ return False;
}
- cpa->event_count++;
- if (cpa->event_count == cpa->max_num_events)
+ cpa->found = cpa->predicate(display, event, cpa->arg);
+ if (cpa->found == True)
{
- /* Not found within the given limit, give up and return a
- * random event. */
- cpa->event_count = 0;
- return True;
+ cpa->event = *event;
}
- /* Otherwise keep looking. */
return False;
}
+static Bool _fev_pred_weed_if(Display *display, XEvent *event, XPointer arg)
+{
+ fev_weed_args *weed_args = (fev_weed_args *)arg;
+ Bool ret;
+ int rc;
+
+ if (event->type == fev_invalid_event_type)
+ {
+ return 0;
+ }
+ if (weed_args->has_window)
+ {
+ if (!FEV_HAS_EVENT_WINDOW(event->type))
+ {
+ return 0;
+ }
+ if (event->xany.window != weed_args->w)
+ {
+ return 0;
+ }
+ }
+ if (weed_args->has_predicate)
+ {
+ rc = weed_args->weed_predicate(display, event, weed_args->arg);
+ }
+ else if (weed_args->has_event_type)
+ {
+ rc = (event->type == weed_args->event_type);
+ }
+ else
+ {
+ rc = 1;
+ }
+ if (rc & 1)
+ {
+ /* invalidate event by setting a bogus event type */
+ event->type = fev_invalid_event_type;
+ weed_args->count++;
+ }
+ ret = (rc & 2) ? True : False;
+
+ return ret;
+}
+
/* ---------------------------- interface functions (privileged access) -----
*/
void fev_copy_last_event(XEvent *dest)
@@ -154,6 +210,14 @@ XEvent *fev_get_last_event_address(void)
/* ---------------------------- interface functions (normal_access) -------- */
+void fev_init_invalid_event_type(int invalid_event_type)
+{
+ fev_invalid_event_type = invalid_event_type;
+ fev_is_invalid_event_type_set = 1;
+
+ return;
+}
+
Time fev_get_evtime(void)
{
return fev_last_timestamp;
@@ -286,6 +350,91 @@ void fev_get_last_event(XEvent *ev)
return;
}
+/* ---------------------------- Functions not present in Xlib -------------- */
+
+int FWeedIfEvents(
+ Display *display,
+ int (*weed_predicate) (Display *display, XEvent *event, XPointer arg),
+ XPointer arg)
+{
+ fev_weed_args weed_args;
+ XEvent e;
+
+ assert(fev_is_invalid_event_type_set);
+ memset(&weed_args, 0, sizeof(weed_args));
+ weed_args.weed_predicate = weed_predicate;
+ weed_args.arg = arg;
+ weed_args.has_predicate = (weed_predicate != NULL);
+ FCheckPeekIfEvent(
+ display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
+ /* e is discarded */
+
+ return weed_args.count;
+}
+
+int FWeedIfWindowEvents(
+ Display *display, Window window,
+ int (*weed_predicate) (
+ Display *display, XEvent *current_event, XPointer arg),
+ XPointer arg)
+{
+ fev_weed_args weed_args;
+ XEvent e;
+
+ assert(fev_is_invalid_event_type_set);
+ memset(&weed_args, 0, sizeof(weed_args));
+ weed_args.weed_predicate = weed_predicate;
+ weed_args.arg = arg;
+ weed_args.w = window;
+ weed_args.has_window = 1;
+ FCheckPeekIfEvent(
+ display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
+ /* e is discarded */
+
+ return weed_args.count;
+}
+
+int FWeedTypedWindowEvents(
+ Display *display, Window window, int event_type, XPointer arg)
+{
+ fev_weed_args weed_args;
+ XEvent e;
+
+ assert(fev_is_invalid_event_type_set);
+ memset(&weed_args, 0, sizeof(weed_args));
+ weed_args.arg = arg;
+ weed_args.w = window;
+ weed_args.event_type = event_type;
+ weed_args.has_window = 1;
+ weed_args.has_event_type = 1;
+ FCheckPeekIfEvent(
+ display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
+ /* e is discarded */
+
+ return weed_args.count;
+}
+
+Bool FCheckPeekIfEvent(
+ Display *display, XEvent *event_return,
+ Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
+ XPointer arg)
+{
+ XEvent dummy;
+ fev_check_peek_args cpa;
+
+ cpa.predicate = predicate;
+ cpa.arg = arg;
+ cpa.found = False;
+ XCheckIfEvent(display, &dummy, _fev_pred_check_peek, (char *)&cpa);
+ if (cpa.found == True)
+ {
+ *event_return = cpa.event;
+ fev_update_last_timestamp(event_return);
+ }
+
+ return cpa.found;
+}
+
/* ---------------------------- X event replacements ----------------------- */
XTimeCoord *FGetMotionEvents(
@@ -346,52 +495,6 @@ Bool FCheckMaskEvent(
return rc;
}
-int FCheckPeekIfEventWithLimit(
- Display *display, XEvent *event_return,
- Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
- XPointer arg, int max_num_events_to_check)
-{
- fev_check_peek_args pred_args;
- int qlen;
-
- qlen = QLength(display);
- if (qlen == 0)
- {
- /* input queue is empty, no match */
- return 0;
- }
- pred_args.predicate = predicate;
- pred_args.arg = arg;
- pred_args.max_num_events = max_num_events_to_check;
- pred_args.event_count = 0;
- if (max_num_events_to_check > 0 && max_num_events_to_check <= qlen)
- {
- pred_args.max_num_events = max_num_events_to_check;
- }
- else
- {
- pred_args.max_num_events = qlen;
- }
- FPeekIfEvent(
- display, event_return, fev_check_peek_pred,
- (char *)&pred_args);
-
- return pred_args.event_count;
-}
-
-Bool FCheckPeekIfEvent(
- Display *display, XEvent *event_return,
- Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
- XPointer arg)
-{
- int rc;
-
- rc = FCheckPeekIfEventWithLimit(
- display, event_return, predicate, arg, 0);
-
- return (rc > 0) ? 1 : 0;
-}
-
Bool FCheckTypedEvent(
Display *display, int event_type, XEvent *event_return)
{
@@ -503,10 +606,7 @@ int FPeekEvent(
int rc;
rc = XPeekEvent(display, event_return);
- if (rc == True)
- {
- fev_update_last_timestamp(event_return);
- }
+ fev_update_last_timestamp(event_return);
return rc;
}
diff --git a/libs/FEvent.h b/libs/FEvent.h
index c956a6c..877c691 100644
--- a/libs/FEvent.h
+++ b/libs/FEvent.h
@@ -7,6 +7,19 @@
/* ---------------------------- global definitions ------------------------- */
+/* A value guaranteed to be neither True nor False. */
+#define FEV_INVALID_BOOL (True + True - False)
+
+#define FEV_IS_EVENT_INVALID(e) \
+ (fev_is_invalid_event_type_set && (e).type == fev_invalid_event_type)
+
+#define FEV_HAS_EVENT_WINDOW(type) \
+ (( \
+ (type) != GraphicsExpose && \
+ (type) != NoExpose && \
+ (type) != SelectionNotify && \
+ (type) != SelectionRequest) ? 1 : 0)
+
/* ---------------------------- global macros ------------------------------ */
/* ---------------------------- type definitions --------------------------- */
@@ -15,7 +28,12 @@
/* ---------------------------- exported variables (globals) --------------- */
-/* ---------------------------- interface functions (privileged access) -----
*/
+/* Exported to be used in FEV_IS_EVENT_INVALID(). Do not use. */
+extern char fev_is_invalid_event_type_set;
+/* Exported to be used in FEV_IS_EVENT_INVALID(). Do not use. */
+extern int fev_invalid_event_type;
+
+/* ---------------------------- interface functions (privileged access) ---- */
#ifdef FEVENT_PRIVILEGED_ACCESS
void fev_copy_last_event(XEvent *dest);
@@ -24,6 +42,10 @@ XEvent *fev_get_last_event_address(void);
/* ---------------------------- interface functions (normal_access) -------- */
+/* Sets the event type that is used by FWeedIfEvents() to mark an event as
+ * invalid. Needs to be called before FWeedIfEvents() can be used. */
+void fev_init_invalid_event_type(int invalid_event_type);
+
/* get the latest event time */
Time fev_get_evtime(void);
@@ -53,6 +75,56 @@ void fev_make_null_event(XEvent *ev, Display *dpy);
/* return a copy of the last XEVent in *ev */
void fev_get_last_event(XEvent *ev);
+/* ---------------------------- Functions not present in Xlib -------------- */
+
+/* Iterates over all events currentliy in the input queue and calls the
+ * weed_predicate procedure for them. The predicate may return
+ * 0 = keep event and continue weeding
+ * 1 = invalidate event and continue weeding
+ * 2 = keep event and stop weeding
+ * 3 = invalidate event and stop weeding
+ * Events are marked as invalid by overwriting the event type with the invalid
+ * event type configured with fev_init_invalid_event_type(). Returns the
+ * number of invalidated events.
+ *
+ * The return codes 2 and 3 of the weed_predicate procedure can be used to
+ * stop weeding if another event gets "in the way". For example, when merging
+ * Expose events, one might want to stop merging when a ConfigureRequest event
+ * is encountered in the queue as that event may change the visible are of the
+ * window.
+ *
+ * Weeded events can still be returned by functions that do not check the event
+ * type, e.g. FNextEvent(), FWindowEvent(), FMaskEvent(), FPeekEvent etc. It
+ * is the responsibility of the caller to discard these events.
+ *
+ * If the weed_predicate is a NULL pointer, no call is made and the result for
+ * all events is assumed to be 1.
+ */
+int FWeedIfEvents(
+ Display *display,
+ int (*weed_predicate) (
+ Display *display, XEvent *current_event, XPointer arg),
+ XPointer arg);
+
+/* Same as FWeedIfEvents but weeds only events for the given window. The
+ * weed_predicate is only called for events with a matching window. */
+int FWeedIfWindowEvents(
+ Display *display, Window window,
+ int (*weed_predicate) (
+ Display *display, XEvent *current_event, XPointer arg),
+ XPointer arg);
+
+/* Same as FWeedIfEvents but weeds only events of the given type for the given
+ window. */
+int FWeedTypedWindowEvents(
+ Display *display, Window window, int event_type, XPointer arg);
+
+/* Like FCheckIfEvent but does not remove the event from the queue. */
+int FCheckPeekIfEvent(
+ Display *display, XEvent *event_return,
+ Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
+ XPointer arg);
+
/* ---------------------------- X event replacements ----------------------- */
/* Replacements for X functions */
@@ -66,18 +138,6 @@ Bool FCheckIfEvent(
XPointer arg);
Bool FCheckMaskEvent(
Display *display, long event_mask, XEvent *event_return);
-/* Works like FCheckPeekIfEvent(), but only searches through the first
- * max_num_events_to_check events that are already on the queue (0 = no limit).
- * Returns the position of the event in the queue (1 = first event) or 0 if
- * none is found. If no event is found, the contents of *event are invalid. */
-int FCheckPeekIfEventWithLimit(
- Display *display, XEvent *event_return,
- Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
- XPointer arg, int max_num_events_to_check);
-Bool FCheckPeekIfEvent(
- Display *display, XEvent *event_return,
- Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
- XPointer arg);
Bool FCheckTypedEvent(
Display *display, int event_type, XEvent *event_return);
Bool FCheckTypedWindowEvent(
commit 7d36bd54a139b5db203c1f9eec54815fbb37dfde
Merge: 786f5d3 caeed3d
Author: Thomas Adam <[email protected]>
Date: Fri Sep 19 21:27:32 2014 +0100
Merge remote-tracking branch 'cvs/branch-2_6' into branch-2_6
commit caeed3d296ed79ac144453a2624e148bbdd9fb0d
Author: domivogt <domivogt>
Date: Fri Sep 19 20:24:10 2014 +0000
Another width_inc-zero fix attempt.
---
fvwm/add_window.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/fvwm/add_window.c b/fvwm/add_window.c
index cba5d61..6c2f7cc 100644
--- a/fvwm/add_window.c
+++ b/fvwm/add_window.c
@@ -2849,16 +2849,6 @@ void GetWindowSizeHintsWithCheck(
Status rc;
new_hints = fw->hints;
- orig_hints.width_inc = 1;
- orig_hints.height_inc = 1;
- if (fw->orig_hints.width_inc <= 0)
- {
- fw->orig_hints.width_inc = 1;
- }
- if (fw->orig_hints.height_inc <= 0)
- {
- fw->orig_hints.height_inc = 1;
- }
rc = XGetWMNormalHints(dpy, FW_W(fw), &orig_hints, &supplied);
if (rc == 0)
{
@@ -3179,13 +3169,15 @@ void GetWindowSizeHintsWithCheck(
" invalid. The new hints will become active"
" when the window generates the next"
" ConfigureRequest.\n", is_invalid);
- return;
}
+ broken_cause = "";
+ }
+ else
+ {
+ fw->hints = new_hints;
+ fw->orig_hints.width_inc = orig_hints.width_inc;
+ fw->orig_hints.height_inc = orig_hints.height_inc;
}
- fw->hints = new_hints;
- fw->orig_hints.width_inc = orig_hints.width_inc;
- fw->orig_hints.height_inc = orig_hints.height_inc;
-
if (*broken_cause != 0)
{
fvwm_msg(
@@ -3212,6 +3204,15 @@ void GetWindowSizeHintsWithCheck(
orig_hints.win_gravity);
fvwm_msg_report_app();
}
+ /* final safety net */
+ if (fw->orig_hints.width_inc <= 0)
+ {
+ fw->orig_hints.width_inc = 1;
+ }
+ if (fw->orig_hints.height_inc <= 0)
+ {
+ fw->orig_hints.height_inc = 1;
+ }
return;
}
commit 4bb95077159083c4dd9288acc596e08818b36a22
Author: domivogt <domivogt>
Date: Fri Sep 19 18:18:23 2014 +0000
Fix uninitialised zero fw->orig_hints.width/height_inc.
---
ChangeLog | 5 +++++
fvwm/add_window.c | 8 ++++++++
2 files changed, 13 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index ee5ec36..09ade16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-09-19 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
+
+ * fvwm/add_window.c (GetWindowSizeHintsWithCheck):
+ fix uninitialised zero fw->orig_hints.width/height_inc
+
2014-09-15 Dominik Vogt <dominik(dot)vogt(at)gmx(dot)de>
* fvwm/ewmh_events.c (EWMH_ProcessPropertyNotify):
diff --git a/fvwm/add_window.c b/fvwm/add_window.c
index c845ab9..cba5d61 100644
--- a/fvwm/add_window.c
+++ b/fvwm/add_window.c
@@ -2851,6 +2851,14 @@ void GetWindowSizeHintsWithCheck(
new_hints = fw->hints;
orig_hints.width_inc = 1;
orig_hints.height_inc = 1;
+ if (fw->orig_hints.width_inc <= 0)
+ {
+ fw->orig_hints.width_inc = 1;
+ }
+ if (fw->orig_hints.height_inc <= 0)
+ {
+ fw->orig_hints.height_inc = 1;
+ }
rc = XGetWMNormalHints(dpy, FW_W(fw), &orig_hints, &supplied);
if (rc == 0)
{
----------------------------------------------------------------
Diffstat:
----------------------------------------------------------------
configure.ac | 1 +
legacy/ChangeLog | 174 +++++++++++
legacy/NEWS | 5 +
libs/FEvent.c | 416 ++++++++++++++++++++-----
libs/FEvent.h | 100 +++++-
libs/WinMagic.c | 2 +-
modules/ChangeLog | 26 ++
modules/MvwmButtons/MvwmButtons.c | 8 +-
modules/MvwmButtons/draw.c | 2 +-
modules/MvwmIconMan/x.c | 5 +
modules/MvwmIconMan/xmanager.c | 2 +-
modules/MvwmIdent/MvwmIdent.c | 3 +
modules/MvwmPager/MvwmPager.c | 3 +
modules/MvwmPager/x_pager.c | 43 ++-
mvwm/add_window.c | 32 +-
mvwm/events.c | 631 +++++++++++++++++++-------------------
mvwm/events.h | 21 +-
mvwm/ewmh_events.c | 45 ++-
mvwm/icons.c | 8 +-
mvwm/menus.c | 33 +-
mvwm/move_resize.c | 8 +-
mvwm/mvwm.c | 3 +
mvwm/virtual.c | 8 +-
23 files changed, 1111 insertions(+), 468 deletions(-)
----------------------------------------------------------------