!7 cmodule2 LinuxWindowList > DynObjectTable { switchable bool inZOrder = false; start { if (!isLinux()) ret with setModuleName("Sorry, wrong OS - LINUX Window List"); dontPersist(); set fieldsInOrder; defaultAction = voidfunc(wmctrl_Entry e) { wmctrl_activateWindow(e) }; doEvery(0.0, 10.0, r updateMe); dm_vmBus_answerToMessage currentWindowTitle(() -> currentWindowTitle()); } afterVisualize { popupMenuItem_top("Close window", r { wmctrl_closeWindow(selected()) }); popupMenuItem_top("Switch to window", defaultAction); popupMenuItem_top("Shoot window", rThread { showImage(shootSystemWindow(selected())) }); } void update { S output = backtick("wmctrl -lpG"); L l = linux_parse_wmctrl_lpG_output(output); if (inZOrder) { LS order = map last7chars(regexpExtractAll("0x[a-f0-9]+", backtick("xprop -root _NET_CLIENT_LIST_STACKING"))); final Map map = mapItemsToListIndex(order); l = sortedByCalculatedFieldDesc(l, func(wmctrl_Entry e) { map.get(last7chars(e.windowIdentity)) }); } setData(l); } // API // id = "0x..." S titleForWindowID(S windowIdentity) { while (l(windowIdentity) < 10) windowIdentity = spliceString(windowIdentity, 2, 2, "0"); //print("Searching window: " + windowIdentity); ret getString windowTitle(objectWhere(data(), +windowIdentity)); } // may be costly (one invocation of xprop) // information is accurate if window is older than 10 secs S currentWindowTitle() enter { ret titleForWindowID(linux_activeWindowID()); } }