diff --git a/configure.ac b/configure.ac index 63a83aa49..9596ad38e 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,7 @@ if test ! x"$with_golang" = xno; then sed -e 's/ .*$//') AC_MSG_CHECKING([whether go version is >= 1.14.x ($go_version)]) case "$go_version" in - 1.14*|1.15*|1.16*|1.17*|1.18*|1.19*|1.20*|1.21*) + 1.14*|1.15*|1.16*|1.17*|1.18*|1.19*|1.20*|1.21*|1.22*|1.23*) AC_MSG_RESULT([yes - version is: $go_version]) with_golang="yes" GO= diff --git a/fvwm/builtins.c b/fvwm/builtins.c index 5a588cb42..833f4f8c5 100644 --- a/fvwm/builtins.c +++ b/fvwm/builtins.c @@ -165,6 +165,9 @@ status_send(void) if ((desk_doc[d_count] = cJSON_CreateObject()) == NULL) goto out; + if (m->Desktops == NULL) + goto out; + this_desktop = cJSON_AddObjectToObject(desk_doc[d_count], "desktops"); diff --git a/fvwm/events.c b/fvwm/events.c index 3623d30d1..1e498a7d8 100644 --- a/fvwm/events.c +++ b/fvwm/events.c @@ -1774,7 +1774,7 @@ static void _refocus_stolen_focus_win(const evh_args_t *ea) void monitor_update_ewmh(void) { FvwmWindow *t; - struct monitor *m, *mref; + struct monitor *m, *mref, *mo, *mo1; fvwm_debug(__func__, "monitor debug...\n"); if (Scr.bo.do_debug_randr) @@ -1785,6 +1785,23 @@ void monitor_update_ewmh(void) mref = RB_MIN(monitors, &monitor_q); RB_FOREACH(m, monitors, &monitor_q) { + if (m->flags & MONITOR_CHANGED) { + if (changed_monitor_count() == 1) + goto out; + TAILQ_FOREACH(mo, &monitorsold_q, oentry) { + if (strcmp(m->si->name, mo->si->name) != 0) + continue; + if (mo->Desktops == NULL) + continue; + for (t = Scr.FvwmRoot.next; t; t = t->next) { + if (t->m == mo) { + t->m = m; + update_fvwm_monitor(t); + } + } + } + continue; + } if (m->flags & MONITOR_NEW) { if (m->Desktops == NULL) { int ewbs[4] = {0, 0, 0, 0}; @@ -1795,6 +1812,9 @@ void monitor_update_ewmh(void) m->Desktops->desk = 0; apply_desktops_monitor(m); + if (m->Desktops->next == mref->Desktops->next) + continue; + calculate_page_sizes(m, mref->dx, mref->dy); fvwm_debug(__func__, @@ -1813,6 +1833,14 @@ void monitor_update_ewmh(void) EWMH_Init(m); } +out: + TAILQ_FOREACH_SAFE(mo, &monitorsold_q, oentry, mo1) { + TAILQ_REMOVE(&monitorsold_q, mo, oentry); + fvwm_debug(__func__, "Removed mo '%s' from processing", + mo->si->name); + } + + BroadcastMonitorList(NULL); for (t = Scr.FvwmRoot.next; t; t = t->next) { @@ -1861,6 +1889,7 @@ monitor_emit_broadcast(void) break; if (pm != mnew) { + fvwm_debug(__func__, "MONITOR PRIMARY"); execute_function_override_window( NULL, NULL, randrfunc, NULL, 0, NULL); } @@ -2266,6 +2295,12 @@ void HandleEnterNotify(const evh_args_t *ea) pfm = monitor_resolve_name(prev_focused_monitor); this_m = monitor_get_current(); + /* Don't toggle the previous monitor if there isn't one, or + * the two monitors are the same. + */ + if ((pfm == NULL) || (pfm == this_m)) + return; + /* Send MX_MONITOR_FOCUS event. */ toggle_prev_monitor_state(this_m, pfm, NULL); diff --git a/libs/FScreen.c b/libs/FScreen.c index 041c6fd74..1d5a78703 100644 --- a/libs/FScreen.c +++ b/libs/FScreen.c @@ -56,6 +56,7 @@ enum monitor_tracking monitor_mode; bool is_tracking_shared; struct screen_infos screen_info_q, screen_info_q_temp; struct monitors monitor_q; +struct monitorsold monitorsold_q; int randr_event; const char *prev_focused_monitor; static struct monitor *monitor_global = NULL; @@ -338,6 +339,17 @@ monitor_by_last_primary(void) return (m); } +int changed_monitor_count(void) +{ + struct monitor *m; + int c = 0; + + TAILQ_FOREACH(m, &monitorsold_q, oentry) + c++; + + return (c); +} + static void monitor_check_primary(void) { @@ -431,8 +443,10 @@ monitor_output_change(Display *dpy, XRRScreenChangeNotifyEvent *e) if (oinfo->connection == RR_Connected && m->flags & MONITOR_ENABLED) { - if (m->flags & MONITOR_CHANGED) + if (m->flags & MONITOR_CHANGED) { m->emit |= MONITOR_CHANGED; + TAILQ_INSERT_TAIL(&monitorsold_q, m, oentry); + } continue; } @@ -600,6 +614,9 @@ void FScreenInit(Display *dpy) if (TAILQ_EMPTY(&screen_info_q)) TAILQ_INIT(&screen_info_q); + if (TAILQ_EMPTY(&monitorsold_q)) + TAILQ_INIT(&monitorsold_q); + if (!XRRQueryExtension(dpy, &randr_event, &err_base) || !XRRQueryVersion (dpy, &major, &minor)) { fvwm_debug(__func__, "RandR not present"); diff --git a/libs/FScreen.h b/libs/FScreen.h index 6a6084098..59a98a861 100644 --- a/libs/FScreen.h +++ b/libs/FScreen.h @@ -145,14 +145,18 @@ struct monitor { bool pan_frames_mapped; RB_ENTRY(monitor) entry; + TAILQ_ENTRY(monitor) oentry; }; RB_HEAD(monitors, monitor); +TAILQ_HEAD(monitorsold, monitor); extern struct monitors monitors; extern struct monitors monitor_q; +extern struct monitorsold monitorsold_q; int monitor_compare(struct monitor *, struct monitor *); RB_PROTOTYPE(monitors, monitor, entry, monitor_compare); +int changed_monitor_count(void); struct monitor *monitor_resolve_name(const char *); struct monitor *monitor_by_xy(int, int); struct monitor *monitor_by_output(int);