diff --git a/doc/FvwmEvent.adoc b/doc/FvwmEvent.adoc index 53d48565e..8566a40dc 100644 --- a/doc/FvwmEvent.adoc +++ b/doc/FvwmEvent.adoc @@ -170,17 +170,7 @@ needed. The monitor_* events do not operate in a window context (as there isn't one), but react to when a monitor is plugged in (enabled), unplugged (disabled), focused (focus) or changed (resized/rotated, etc., which -will only be true if the monitor is already active). In all cases, the -monitor name is is passed through to the command, hence the following -example prints out the changed monitor's name, and width/height values: -+ -.... - DestroyFunc MonitorExample - AddToFunc MonitorExample - + I Echo "Monitor $0 changed ($[monitor.$0.width] x $[monitor.$0.height]) - - *FvwmEvent: monitor_changed MonitorExample -.... +will only be true if the monitor is already active). + The echo event is generated whenever Fvwm receives an Echo command. + diff --git a/fvwm/events.c b/fvwm/events.c index 5178be99a..e98a08a87 100644 --- a/fvwm/events.c +++ b/fvwm/events.c @@ -182,6 +182,8 @@ typedef struct } _merge_cr_args; /* ---------------------------- forward declarations ----------------------- */ +static void toggle_prev_monitor_state(struct monitor *, struct monitor *, + FvwmWindow *); /* ---------------------------- local variables ---------------------------- */ @@ -1981,6 +1983,35 @@ void HandleDestroyNotify(const evh_args_t *ea) return; } +static void +toggle_prev_monitor_state(struct monitor *this, struct monitor *prev, + FvwmWindow *fw) +{ + if (fw == NULL) { + /* Assume root window. */ + if (this != prev) { + BroadcastName(MX_MONITOR_FOCUS, -1, -1, -1, + this->si->name /* Name of the monitor. */ + ); + } + /* Toggle the state of the previous monitor. */ + prev->is_prev = false; + this->is_prev = true; + + return; + } + + if (fw->m != prev) { + BroadcastName(MX_MONITOR_FOCUS, -1, -1, -1, + this->si->name /* Name of the monitor. */ + ); + + /* Toggle the state of the previous monitor. */ + prev->is_prev = false; + this->is_prev = true; + } +} + #if DEBUG_ENTERNOTIFY static int ecount=0; #define ENTER_DBG(x) fprintf x; @@ -2223,6 +2254,14 @@ void HandleEnterNotify(const evh_args_t *ea) InstallWindowColormaps(NULL); } focus_grab_buttons(lf); + + struct monitor *pfm, *this_m; + pfm = monitor_resolve_name(prev_focused_monitor); + this_m = monitor_get_current(); + + /* Send MX_MONITOR_FOCUS event. */ + toggle_prev_monitor_state(this_m, pfm, NULL); + return; } else @@ -2312,9 +2351,20 @@ void HandleEnterNotify(const evh_args_t *ea) ewp->window == FW_W_ICON_TITLE(fw) || ewp->window == FW_W_ICON_PIXMAP(fw)) { - BroadcastPacket( - MX_ENTER_WINDOW, 3, (long)FW_W(fw), - (long)FW_W_FRAME(fw), (unsigned long)fw); + struct monitor *pfm; + pfm = monitor_resolve_name(prev_focused_monitor); + + BroadcastPacket(MX_ENTER_WINDOW, 3, (long)FW_W(fw), + (long)FW_W_FRAME(fw), (unsigned long)fw); + + if (fw != NULL) { + /* Send MX_MONITOR_FOCUS event. */ + toggle_prev_monitor_state(fw->m, pfm, fw); + + if (pfm->virtual_scr.CurrentDesk != + fw->m->virtual_scr.CurrentDesk) + EWMH_SetCurrentDesktop(fw->m); + } } sf = get_focus_window(); if (sf && fw != sf && FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(sf))) @@ -2577,20 +2627,6 @@ void HandleFocusIn(const evh_args_t *ea) (unsigned long)IsLastFocusSetByMouse(), (long)fc, (long)bc); EWMH_SetActiveWindow(focus_w); - - struct monitor *pfm; - pfm = monitor_resolve_name(prev_focused_monitor); - - if (fw != NULL && fw->m != pfm) { - pfm->is_prev = true; - fw->m->is_prev = false; - BroadcastName(MX_MONITOR_FOCUS, -1, -1, -1, - fw->m->si->name /* Name of the monitor. */ - ); - if (pfm->virtual_scr.CurrentDesk != - fw->m->virtual_scr.CurrentDesk) - EWMH_SetCurrentDesktop(fw->m); - } } last_focus_w = focus_w; last_focus_fw = focus_fw; diff --git a/libs/FScreen.c b/libs/FScreen.c index 2ac92f732..5076c0d8a 100644 --- a/libs/FScreen.c +++ b/libs/FScreen.c @@ -167,8 +167,11 @@ struct monitor * monitor_get_prev(void) { struct monitor *m, *mret = NULL; + struct monitor *this = monitor_get_current(); TAILQ_FOREACH(m, &monitor_q, entry) { + if (m == this) + continue; if (m->is_prev) { mret = m; break; @@ -537,6 +540,7 @@ void FScreenInit(Display *dpy) m->Desktops->next = NULL; m->Desktops->desk = 0; m->flags |= (MONITOR_NEW|MONITOR_ENABLED); + m->is_prev = false; monitor_scan_edges(m); } @@ -572,6 +576,7 @@ monitor_dump_state(struct monitor *m) "\tDisabled:\t%s\n" "\tIs Primary:\t%s\n" "\tIs Current:\t%s\n" + "\tIs Previous:\t%s\n" "\tOutput:\t%d\n" "\tCoords:\t{x: %d, y: %d, w: %d, h: %d}\n" "\tVirtScr: {\n" @@ -586,6 +591,7 @@ monitor_dump_state(struct monitor *m) (m2->flags & MONITOR_DISABLED) ? "true" : "false", (m2->flags & MONITOR_PRIMARY) ? "yes" : "no", (mcur && m2 == mcur) ? "yes" : "no", + m2->is_prev ? "yes" : "no", (int)m2->si->rr_output, m2->si->x, m2->si->y, m2->si->w, m2->si->h, m2->virtual_scr.VxMax, m2->virtual_scr.VyMax, diff --git a/modules/FvwmEvent/FvwmEvent.c b/modules/FvwmEvent/FvwmEvent.c index c4234b7d3..b250a5659 100644 --- a/modules/FvwmEvent/FvwmEvent.c +++ b/modules/FvwmEvent/FvwmEvent.c @@ -95,7 +95,6 @@ static Bool audio_compat = False; static char *audio_play_dir = NULL; #define ARG_NO_WINID 1024 /* just a large number */ -#define ARG_EXPECTS_CHAR 1025 #define EVENT_ENTRY(name,action_arg) { name, action_arg, {NULL} } static event_entry message_event_table[] = @@ -139,11 +138,11 @@ static event_entry extended_message_event_table[] = EVENT_ENTRY( "enter_window", 0 ), EVENT_ENTRY( "leave_window", 0 ), EVENT_ENTRY( "property_change", 0), - EVENT_ENTRY( "monitor_enabled", 0 | ARG_EXPECTS_CHAR), - EVENT_ENTRY( "monitor_disabled", 0 | ARG_EXPECTS_CHAR), - EVENT_ENTRY( "monitor_changed", 0 | ARG_EXPECTS_CHAR), - EVENT_ENTRY( "monitor_focus", 0 | ARG_EXPECTS_CHAR), - EVENT_ENTRY( "echo", 0 | ARG_EXPECTS_CHAR), + EVENT_ENTRY( "monitor_enabled", 0 | ARG_NO_WINID), + EVENT_ENTRY( "monitor_disabled", 0 | ARG_NO_WINID), + EVENT_ENTRY( "monitor_changed", 0 | ARG_NO_WINID), + EVENT_ENTRY( "monitor_focus", 0 | ARG_NO_WINID), + EVENT_ENTRY( "echo", 0), EVENT_ENTRY( "reply", 0), /* FvwmEvent will never receive MX_REPLY */ EVENT_ENTRY(NULL,0) }; @@ -469,11 +468,6 @@ void execute_event(event_entry *event_table, short event, unsigned long *body) action, body[action_arg]); } } - /* monitor_* events. */ - else if (action_arg != -1 && (action_arg & ARG_EXPECTS_CHAR)) { - sprintf(buf, "%s %s %s", cmd_line, action, - (char *)(&body[3])); - } else { sprintf(buf,"%s %s", cmd_line, action);