From 2721f23b14c33b05184bede0f0a7827c7bad9929 Mon Sep 17 00:00:00 2001 From: Thomas Adam Date: Sat, 20 Dec 2025 14:50:37 +0000 Subject: [PATCH 1/2] Send_WindowList: allow for optional monitor When modules send a request for all windows, this can be computationally expensive as this was sent for all monitors. It was expected that modules would filter these packets out. However, this operation is expensive the more monitors which are attached with windows. Allow for modules to opt-in to immediately filtering out a specific monitor at source, by appending the name of a monitor to the end of the "Send_WindowList" command. --- fvwm/module_interface.c | 171 +++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/fvwm/module_interface.c b/fvwm/module_interface.c index 436ad3961..8dc4c2ae1 100644 --- a/fvwm/module_interface.c +++ b/fvwm/module_interface.c @@ -54,6 +54,7 @@ static fqueue cqueue = FQUEUE_INIT; static const unsigned long dummy = 0; static void send_monitor_info(fmodule *); +static void send_one_windowlist_batch(fmodule *, struct monitor *, int); static unsigned long * make_vpacket(unsigned long *body, unsigned long event_type, @@ -910,27 +911,15 @@ void CMD_Send_Reply(F_CMD_ARGS) return; } -void CMD_Send_WindowList(F_CMD_ARGS) +static void +send_one_windowlist_batch(fmodule *mod, struct monitor *m, int force) { FvwmWindow *t; - fmodule *mod = exc->m.module; - struct monitor *m; - if (mod == NULL) - { - return; - } - - /* TA: 2020-01-09: We send this for *ALL* configured monitors. - * - * Modules can filter out those monitor packets they're not interested - * in. - */ - RB_FOREACH(m, monitors, &monitor_q) { - SendPacket(mod, M_NEW_DESK, 2, (long)m->virtual_scr.CurrentDesk, + SendPacket(mod, M_NEW_DESK, 2, (long)m->virtual_scr.CurrentDesk, (long)m->si->rr_output); - SendPacket( - mod, M_NEW_PAGE, 8, (long)m->virtual_scr.Vx, (long)m->virtual_scr.Vy, + SendPacket(mod, M_NEW_PAGE, 8, (long)m->virtual_scr.Vx, + (long)m->virtual_scr.Vy, (long)m->virtual_scr.CurrentDesk, (long) monitor_get_all_widths(), (long) monitor_get_all_heights(), @@ -938,104 +927,124 @@ void CMD_Send_WindowList(F_CMD_ARGS) (long)((m->virtual_scr.VyMax / monitor_get_all_heights()) + 1), (long)m->si->rr_output); - if (Scr.Hilite != NULL) - { - SendPacket( - mod, M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), + if (Scr.Hilite != NULL) + { + SendPacket(mod, M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), (long)FW_W_FRAME(Scr.Hilite), (unsigned long)True, (long)Scr.Hilite->hicolors.fore, (long)Scr.Hilite->hicolors.back); - } - else - { - SendPacket( - mod, M_FOCUS_CHANGE, 5, 0, 0, (unsigned long)True, + } + else + { + SendPacket(mod, M_FOCUS_CHANGE, 5, 0, 0, (unsigned long)True, (long)Colorset[0].fg, (long)Colorset[0].bg); - } - if (Scr.DefaultIcon != NULL) - { - SendName(mod, M_DEFAULTICON, 0, 0, 0, Scr.DefaultIcon); - } + } + if (Scr.DefaultIcon != NULL) + { + SendName(mod, M_DEFAULTICON, 0, 0, 0, Scr.DefaultIcon); + } - for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) - { - if ((monitor_mode == MONITOR_TRACKING_M) && t->m != m) - continue; + for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) + { + if ((monitor_mode == MONITOR_TRACKING_M || force) && t->m != m) + continue; - SendConfig(mod,M_CONFIGURE_WINDOW,t); - SendName( + SendConfig(mod,M_CONFIGURE_WINDOW,t); + SendName( mod, M_WINDOW_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->name.name); - SendName( + SendName( mod, M_ICON_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->icon_name.name); - SendName( + SendName( mod, M_VISIBLE_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->visible_name); - SendName( + SendName( mod, MX_VISIBLE_ICON_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t,t->visible_icon_name); - if (t->icon_bitmap_file != NULL - && t->icon_bitmap_file != Scr.DefaultIcon) - { - SendName( + if (t->icon_bitmap_file != NULL + && t->icon_bitmap_file != Scr.DefaultIcon) + { + SendName( mod, M_ICON_FILE, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->icon_bitmap_file); - } + } - SendName( + SendName( mod, M_RES_CLASS, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->class.res_class); - SendName( + SendName( mod, M_RES_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->class.res_name); - if (IS_ICONIFIED(t) && !IS_ICON_UNMAPPED(t)) + if (IS_ICONIFIED(t) && !IS_ICON_UNMAPPED(t)) + { + rectangle r; + Bool rc; + + rc = get_visible_icon_geometry(t, &r); + if (rc == True) { - rectangle r; - Bool rc; - - rc = get_visible_icon_geometry(t, &r); - if (rc == True) - { - SendPacket( - mod, M_ICONIFY, 7, (long)FW_W(t), - (long)FW_W_FRAME(t), (unsigned long)t, - (long)r.x, (long)r.y, - (long)r.width, (long)r.height); - } + SendPacket(mod, M_ICONIFY, 7, (long)FW_W(t), + (long)FW_W_FRAME(t), (unsigned long)t, + (long)r.x, (long)r.y, + (long)r.width, (long)r.height); } - if ((IS_ICONIFIED(t))&&(IS_ICON_UNMAPPED(t))) - { - SendPacket( - mod, M_ICONIFY, 7, (long)FW_W(t), + } + if ((IS_ICONIFIED(t))&&(IS_ICON_UNMAPPED(t))) + { + SendPacket(mod, M_ICONIFY, 7, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)0, (long)0, (long)0, (long)0); - } - if (FMiniIconsSupported && t->mini_icon != NULL) - { - SendFvwmPicture( - mod, M_MINI_ICON, FW_W(t), FW_W_FRAME(t), + } + if (FMiniIconsSupported && t->mini_icon != NULL) + { + SendFvwmPicture(mod, M_MINI_ICON, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->mini_icon, t->mini_pixmap_file); - } } + } - if (Scr.Hilite == NULL) - { - BroadcastPacket( - M_FOCUS_CHANGE, 5, (long)0, (long)0, + if (Scr.Hilite == NULL) + { + BroadcastPacket(M_FOCUS_CHANGE, 5, (long)0, (long)0, (unsigned long)True, (long)Colorset[0].fg, (long)Colorset[0].bg); - } - else - { - BroadcastPacket( - M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), + } + else + { + BroadcastPacket(M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), (long)FW_W(Scr.Hilite), (unsigned long)True, (long)Scr.Hilite->hicolors.fore, (long)Scr.Hilite->hicolors.back); - } + } +} + +void CMD_Send_WindowList(F_CMD_ARGS) +{ + fmodule *mod = exc->m.module; + struct monitor *m; + char *option = NULL; + + if (mod == NULL) + { + return; + } + + action = GetNextFullOption(action, &option); + if (strlen(option) > 0) { + m = monitor_resolve_name(option); + send_one_windowlist_batch(mod, m, 1); + goto done; + } + + /* TA: 2020-01-09: We send this for *ALL* configured monitors. + * + * Modules can filter out those monitor packets they're not interested + * in. + */ + RB_FOREACH(m, monitors, &monitor_q) { + send_one_windowlist_batch(mod, m, 0); /* If we're tracking just the global monitor, then stop here * -- essentially, we only need to send this information once. @@ -1043,6 +1052,6 @@ void CMD_Send_WindowList(F_CMD_ARGS) if (monitor_mode == MONITOR_TRACKING_G) break; } - +done: SendPacket(mod, M_END_WINDOWLIST, 0); } From a370c8fe9646f424c5bd840fe0ae2faebdae43f2 Mon Sep 17 00:00:00 2001 From: Thomas Adam Date: Sat, 20 Dec 2025 14:55:16 +0000 Subject: [PATCH 2/2] FvwmRearrange: send monitor with Send_WindowList When requesting a list of windows to operate on, explicitly send the monitor name to use. This is only applicable if -screen is set or none is provided (defaulting to the current monitor). This is ignored in the case where the global screen has been requested. --- modules/FvwmRearrange/FvwmRearrange.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/FvwmRearrange/FvwmRearrange.c b/modules/FvwmRearrange/FvwmRearrange.c index 341ac3a56..b8c89d9fd 100644 --- a/modules/FvwmRearrange/FvwmRearrange.c +++ b/modules/FvwmRearrange/FvwmRearrange.c @@ -942,7 +942,13 @@ main(int argc, char *argv[]) | M_RES_NAME ); - SendText(fd, "Send_WindowList", 0); + char *scr_name = mon->si->name; + char msg[4096]; + + if (is_global) + scr_name = ""; + snprintf(msg, sizeof(msg), "Send_WindowList %s", scr_name); + SendText(fd, msg, 0); /* Tell fvwm we're running */ SendFinishedStartupNotification(fd);