From 0458282fd8337ef8614766039619302513aa4717 Mon Sep 17 00:00:00 2001 From: diego roversi Date: Tue, 12 Sep 2023 11:24:29 +0200 Subject: [PATCH 1/8] Use capacity when battery doesn't have information about full charge. (#746) --- src/aapm.cc | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/aapm.cc b/src/aapm.cc index d69c420c..fbf5cad3 100644 --- a/src/aapm.cc +++ b/src/aapm.cc @@ -471,6 +471,7 @@ void YApm::SysStr(char *s, bool Tool) { long BATcapacity_full = -1; long BATcapacity_design = -1; long BATcapacity_remain = -1; + long BATcapacity = -1; long BATrate = -1; long BATtime_remain = -1; @@ -525,6 +526,20 @@ void YApm::SysStr(char *s, bool Tool) { } fclose(fd); } + // if there is no energy_full or charge_full use capacity + if (BATcapacity_remain == -1) { + fd = open3("/sys/class/power_supply/", BATname, "/capacity"); + if (fd != nullptr) { + if (fgets(buf, sizeof(buf), fd)) { + //in case it contains non-numeric value + if (sscanf(buf, "%ld", &BATcapacity) <= 0) { + BATcapacity = -1; + } + } + } + BATcapacity_full = 100; + BATcapacity_remain = BATcapacity; + } fd = open3("/sys/class/power_supply/", BATname, "/present"); if (fd != nullptr) { @@ -569,6 +584,21 @@ void YApm::SysStr(char *s, bool Tool) { } fclose(fd); } + // if there is no energy_full or charge_full use capacity + if (BATcapacity_full == -1) { + fd = open3("/sys/class/power_supply/", BATname, "/capacity"); + if (fd != nullptr) { + if (fgets(buf, sizeof(buf), fd)) { + //in case it contains non-numeric value + if (sscanf(buf, "%ld", &BATcapacity) <= 0) { + BATcapacity = -1; + } + } + } + BATcapacity_full = 100; + BATcapacity_remain = BATcapacity; + } + if (BATcapacity_remain > BATcapacity_full && BATcapacity_design > 0) BATcapacity_full = BATcapacity_design; acpiBatteries[i]->capacity_full = BATcapacity_full; @@ -790,7 +820,8 @@ YApm::YApm(YWindow *aParent, bool autodetect): while (dir.next()) { if (mode == SYSFS) { mstring str("/sys/class/power_supply/", dir.entry(), "/online"); - if (upath(str).isReadable()) { + mstring strb("/sys/class/power_supply/", dir.entry(), "/capacity"); + if (upath(str).isReadable() && ! upath(strb).isReadable()) { if (acpiACName == nullptr) acpiACName = newstr(dir.entry()); continue; From 130e835a90a0a44ee11c95749828fcab5621436b Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Tue, 12 Sep 2023 18:25:02 +0200 Subject: [PATCH 2/8] Simplify APM file handling with class SysFS for bbidulock/icewm#746. --- src/aapm.cc | 231 ++++++++++++++++++++++------------------------------ src/aapm.h | 11 +++ 2 files changed, 109 insertions(+), 133 deletions(-) diff --git a/src/aapm.cc b/src/aapm.cc index fbf5cad3..70c53488 100644 --- a/src/aapm.cc +++ b/src/aapm.cc @@ -52,6 +52,53 @@ extern YColorName taskBarBg; #define SYS_STR_SIZE 64 #define APM_LINE_LEN 80 +SysFS::SysFS(const char* topdir, const char* subdir) + : dirfd(-1) +{ + char buf[256]; + snprintf(buf, sizeof buf, "%s%s", topdir, subdir); + dirfd = open(buf, O_DIRECTORY | O_RDONLY); +} + +SysFS::~SysFS() { + if (0 <= dirfd) + close(dirfd); +} + +bool SysFS::readable(const char* name) { + return 0 <= dirfd && faccessat(dirfd, name, R_OK, 0) == 0; +} + +bool SysFS::read(const char* name, char* buf) { + bool got = false; + const size_t bufsize = 256; + if (0 <= dirfd) { + int fd = openat(dirfd, name, O_RDONLY); + if (0 <= fd) { + int n = ::read(fd, buf, bufsize - 1); + if (0 < n) { + buf[n] = '\0'; + got = true; + } + close(fd); + } + } + return got; +} + +bool SysFS::read(const char* name, long* num) { + bool got = false; + const size_t bufsize = 256; + char buf[bufsize]; + if (read(name, buf)) { + if (sscanf(buf, "%ld", num) <= 0) + *num = -1; + else + got = true; + } + return got; +} + void YApm::ApmStr(char *s, bool Tool) { char apmver[16]; char units[16]; @@ -181,9 +228,9 @@ bool YApm::ignore_directory_ac_entry(const char* name) { } void YApm::AcpiStr(char *s, bool Tool) { - char buf[255], bat_info[250]; + char buf[256], bat_info[250]; - *s='\0'; + *s = '\0'; //assign some default values, in case //the file in /proc/acpi will contain unexpected values @@ -433,28 +480,18 @@ void YApm::AcpiStr(char *s, bool Tool) { } void YApm::SysStr(char *s, bool Tool) { - char buf[255], bat_info[250]; + char buf[256], bat_info[250]; - *s='\0'; + *s = '\0'; - //assign some default values, in case - //the file in /sys/class/power_supply will contain unexpected values - int ACstatus = -1; + AC_Status ACstatus = AC_UNKNOWN; if (nonempty(acpiACName)) { - FILE* fd = open3("/sys/class/power_supply/", acpiACName, "/online"); - if (fd != nullptr) { - while (fgets(buf, sizeof(buf), fd)) { - if (*buf == '1') { - ACstatus = AC_ONLINE; - } - else if (*buf == '0') { - ACstatus = AC_OFFLINE; - } - else { - ACstatus = AC_UNKNOWN; - } - } - fclose(fd); + SysFS fs("/sys/class/power_supply/", acpiACName); + if (fs && fs.read("online", buf)) { + if (*buf == '1') + ACstatus = AC_ONLINE; + else if (*buf == '0') + ACstatus = AC_OFFLINE; } } @@ -464,8 +501,6 @@ void YApm::SysStr(char *s, bool Tool) { int n = 0; for (int i = 0; i < batteryNum; i++) { const char* BATname = acpiBatteries[i]->name; - //assign some default values, in case - //the files in /sys/class/power_supply will contain unexpected values BAT_Present BATpresent = BAT_ABSENT; BAT_Status BATstatus = BAT_UNKNOWN; long BATcapacity_full = -1; @@ -474,133 +509,63 @@ void YApm::SysStr(char *s, bool Tool) { long BATcapacity = -1; long BATrate = -1; long BATtime_remain = -1; + SysFS fs("/sys/class/power_supply/", BATname); - FILE* fd = open3("/sys/class/power_supply/", BATname, "/status"); - if (fd == nullptr) { - fd = open3("/sys/class/power_supply/", BATname, "/power_now"); - } - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - if (strncasecmp(buf, "charging", 8) == 0) { - BATstatus = BAT_CHARGING; - } - else if (strncasecmp(buf, "discharging", 11) == 0) { - BATstatus = BAT_DISCHARGING; - } - else if (strncasecmp(buf, "full", 4) == 0) { - BATstatus = BAT_FULL; - } - else { - BATstatus = BAT_UNKNOWN; - } + if (fs.read("status", buf) || fs.read("power_now", buf)) { + if (strncasecmp(buf, "charging", 8) == 0) { + BATstatus = BAT_CHARGING; + } + else if (strncasecmp(buf, "discharging", 11) == 0) { + BATstatus = BAT_DISCHARGING; + } + else if (strncasecmp(buf, "full", 4) == 0) { + BATstatus = BAT_FULL; + } + else { + BATstatus = BAT_UNKNOWN; } - fclose(fd); } // XXX: investigate, if current_now is missing, can we // stop polling it? For all or just for this battery? - fd = open3("/sys/class/power_supply/", BATname, "/current_now"); - if (fd == nullptr) { - fd = open3("/sys/class/power_supply/", BATname, "/power_now"); - } - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //In case it contains non-numeric value - if (sscanf(buf, "%ld", &BATrate) <= 0) { - BATrate = -1; - } - } - fclose(fd); - } + if (fs.read("current_now", &BATrate) == false) + fs.read("power_now", &BATrate); + + if (fs.read("energy_now", &BATcapacity_remain) == false) + fs.read("charge_now", &BATcapacity_remain); - fd = open3("/sys/class/power_supply/", BATname, "/energy_now"); - if (fd == nullptr) { - fd = open3("/sys/class/power_supply/", BATname, "/charge_now"); - } - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //In case it contains non-numeric value - if (sscanf(buf, "%ld", &BATcapacity_remain) <= 0) { - BATcapacity_remain = -1; - } - } - fclose(fd); - } // if there is no energy_full or charge_full use capacity if (BATcapacity_remain == -1) { - fd = open3("/sys/class/power_supply/", BATname, "/capacity"); - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //in case it contains non-numeric value - if (sscanf(buf, "%ld", &BATcapacity) <= 0) { - BATcapacity = -1; - } - } + if (fs.read("capacity", &BATcapacity)) { + BATcapacity_full = 100; + BATcapacity_remain = BATcapacity; } - BATcapacity_full = 100; - BATcapacity_remain = BATcapacity; } - fd = open3("/sys/class/power_supply/", BATname, "/present"); - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - if (*buf == '1') { - BATpresent = BAT_PRESENT; - } - else { - BATpresent = BAT_ABSENT; - } - } - fclose(fd); - } + if (fs.read("present", buf) && *buf == '1') + BATpresent = BAT_PRESENT; - if (BATpresent == BAT_PRESENT) { //battery is present now + if (BATpresent == BAT_PRESENT) { // battery is present now if (acpiBatteries[i]->present == BAT_ABSENT) { - //and previously was absent - //read full-capacity value - fd = open3("/sys/class/power_supply/", BATname, "/energy_full_design"); - if (fd == nullptr) { - fd = open3("/sys/class/power_supply/", BATname, "/charge_full_design"); - } - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //in case it contains non-numeric value - if (sscanf(buf, "%ld", &BATcapacity_design) <= 0) { - BATcapacity_design = -1; - } - } - fclose(fd); - } - fd = open3("/sys/class/power_supply/", BATname, "/energy_full"); - if (fd == nullptr) { - fd = open3("/sys/class/power_supply/", BATname, "/charge_full"); - } - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //in case it contains non-numeric value - if (sscanf(buf, "%ld", &BATcapacity_full) <= 0) { - BATcapacity_full = -1; - } - } - fclose(fd); - } + // and previously was absent + // read full-capacity value + if (fs.read("energy_full_design", &BATcapacity_design) == false) + fs.read("charge_full_design", &BATcapacity_design); + + if (fs.read("energy_full", &BATcapacity_full) == false) + fs.read("charge_full", &BATcapacity_full); + // if there is no energy_full or charge_full use capacity if (BATcapacity_full == -1) { - fd = open3("/sys/class/power_supply/", BATname, "/capacity"); - if (fd != nullptr) { - if (fgets(buf, sizeof(buf), fd)) { - //in case it contains non-numeric value - if (sscanf(buf, "%ld", &BATcapacity) <= 0) { - BATcapacity = -1; - } - } - } + fs.read("capacity", &BATcapacity); BATcapacity_full = 100; BATcapacity_remain = BATcapacity; } - if (BATcapacity_remain > BATcapacity_full && BATcapacity_design > 0) + if (BATcapacity_remain > BATcapacity_full && + BATcapacity_design > 0) BATcapacity_full = BATcapacity_design; + acpiBatteries[i]->capacity_full = BATcapacity_full; } else { @@ -610,7 +575,8 @@ void YApm::SysStr(char *s, bool Tool) { acpiBatteries[i]->present = BATpresent; // the code above caches BATcapacity_full when battery is installed; - // however, this value and _remain can increase slightly while the battery is charging, + // however, this value and _remain can increase slightly + // while the battery is charging, // so set a limit to not display resulting value over 100% to the user if (BATcapacity_remain > BATcapacity_full) BATcapacity_remain = BATcapacity_full; @@ -819,9 +785,8 @@ YApm::YApm(YWindow *aParent, bool autodetect): //scan for batteries while (dir.next()) { if (mode == SYSFS) { - mstring str("/sys/class/power_supply/", dir.entry(), "/online"); - mstring strb("/sys/class/power_supply/", dir.entry(), "/capacity"); - if (upath(str).isReadable() && ! upath(strb).isReadable()) { + SysFS fs("/sys/class/power_supply/", dir.entry()); + if (fs.readable("online") && ! fs.readable("capacity")) { if (acpiACName == nullptr) acpiACName = newstr(dir.entry()); continue; diff --git a/src/aapm.h b/src/aapm.h index 30bf96f3..16325734 100644 --- a/src/aapm.h +++ b/src/aapm.h @@ -26,6 +26,17 @@ struct Battery { present(false), capacity_full(-1) { } }; +class SysFS { +private: + int dirfd; +public: + SysFS(const char* topdir, const char* subdir); + ~SysFS(); + bool readable(const char* name); + operator bool() { return 0 <= dirfd; } + bool read(const char* name, char* buf); + bool read(const char* name, long* num); +}; class YApm: public IApplet, From 6f4a7b4762a9539aa18f00a3acf63c33b953a42d Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Mon, 18 Sep 2023 00:12:56 +0200 Subject: [PATCH 3/8] When cascading, include the border size for bbidulock/icewm#747. --- src/wmmgr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wmmgr.cc b/src/wmmgr.cc index 32ef92e8..df579752 100644 --- a/src/wmmgr.cc +++ b/src/wmmgr.cc @@ -1573,8 +1573,8 @@ void YWindowManager::getCascadePlace(YFrameWindow *frame, int &lastX, int &lastY y = lastY; y -= min(frame->borderYN(), int(topSideVerticalOffset)); - lastX += wsTitleBar; - lastY += wsTitleBar; + lastX += wsTitleBar + frame->borderXN(); + lastY += wsTitleBar + frame->borderYN(); if (int(y + h) >= My) { y = my; lastY = wsTitleBar; From 84d26eb3f35c977765c4b025f22cc3682115859f Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Mon, 18 Sep 2023 20:59:23 +0200 Subject: [PATCH 4/8] Add pref "TaskBarShowTransientWindows" to only show window titles on task buttons when it is true, which is the default, for issue 633. --- src/atasks.cc | 8 +++++--- src/default.h | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/atasks.cc b/src/atasks.cc index 280e001c..7d847690 100644 --- a/src/atasks.cc +++ b/src/atasks.cc @@ -600,7 +600,7 @@ void TaskButton::paint(Graphics& g, const YRect& r) { int textX = 0; int textY = 0; - mstring str(fActive ? fActive->getIconTitle() : null); + mstring str(fActive && taskBarShowWindowTitles ? fActive->getIconTitle() : null); if (str != null) { YFont font = getFont(); if (font != null) { @@ -666,7 +666,7 @@ int TaskButton::estimate() { p += YIcon::smallSize(); } - mstring str(fActive ? fActive->getIconTitle() : null); + mstring str(fActive && taskBarShowWindowTitles ? fActive->getIconTitle() : null); if (str != null) { YFont font = getFont(); if (font != null) { @@ -1140,7 +1140,9 @@ void TaskPane::relayoutNow(bool force) { for (TaskButton* task : fTasks) { if (task->getShown()) { - const int w1 = wid + (lc < rem); + const int w1 = taskBarShowWindowTitles + ? wid + (lc < rem) + : task->estimate(); if (task != dragging()) { YRect r(x, 0, unsigned(w1), height()); if (rightToLeft) { diff --git a/src/default.h b/src/default.h index 07f3f59b..ebd4d903 100644 --- a/src/default.h +++ b/src/default.h @@ -57,6 +57,7 @@ XIV(bool, trayShowAllWindows, true) XIV(bool, taskBarShowTransientWindows, true) XIV(bool, taskBarShowAllWindows, false) XIV(bool, taskBarShowWindowIcons, true) +XIV(bool, taskBarShowWindowTitles, true) XIV(bool, taskBarAutoHide, false) XIV(bool, taskBarFullscreenAutoShow, true) XIV(bool, taskBarDoubleHeight, false) @@ -332,7 +333,8 @@ cfoption icewm_preferences[] = { OBV("TrayShowAllWindows", &trayShowAllWindows, "Show windows from all workspaces on tray"), OBV("TaskBarShowTransientWindows", &taskBarShowTransientWindows, "Show transient (dialogs, ...) windows on task bar"), OBV("TaskBarShowAllWindows", &taskBarShowAllWindows, "Show windows from all workspaces on task bar"), - OBV("TaskBarShowWindowIcons", &taskBarShowWindowIcons, "Show icons of windows on the task bar"), + OBV("TaskBarShowWindowIcons", &taskBarShowWindowIcons, "Show icons of windows on task buttons of the task bar"), + OBV("TaskBarShowWindowTitles", &taskBarShowWindowTitles, "Show titles of windows on task buttons of the task bar"), OBV("TaskBarShowStartMenu", &taskBarShowStartMenu, "Show 'Start' menu on task bar"), OBV("TaskBarShowWindowListMenu", &taskBarShowWindowListMenu, "Show 'window list' menu on task bar"), OBV("TaskBarShowCPUStatus", &taskBarShowCPUStatus, "Show CPU status on task bar"), From 23f4fb3fa506039f436df14f30313878036cb926 Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Tue, 19 Sep 2023 18:10:13 +0200 Subject: [PATCH 5/8] Document new pref "TaskBarShowWindowTitles". --- man/icewm-preferences.pod | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/man/icewm-preferences.pod b/man/icewm-preferences.pod index fbbca36e..9b8f92ac 100644 --- a/man/icewm-preferences.pod +++ b/man/icewm-preferences.pod @@ -501,7 +501,11 @@ Show windows from all workspaces on task bar. =item B=1 -Show icons of windows on the task bar. +Show icons of windows on task buttons of the task bar. + +=item B=1 + +Show titles of windows on task buttons of the task bar. =item B=1 From 210fff6a39d24c34432f822a0c24629ef1964fba Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Thu, 21 Sep 2023 00:00:42 +0200 Subject: [PATCH 6/8] Add DoNotManage winoption for issues #653 and ice-wm/icewm#136. --- man/icewm-winoptions.pod | 1 + man/icewmhint.pod | 1 + src/wmframe.h | 1 + src/wmmgr.cc | 26 ++++++++++++++++++++++++-- src/wmmgr.h | 1 + src/wmoption.cc | 1 + 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/man/icewm-winoptions.pod b/man/icewm-winoptions.pod index 153d7b3a..5f65ddc5 100644 --- a/man/icewm-winoptions.pod +++ b/man/icewm-winoptions.pod @@ -191,6 +191,7 @@ the application: appTakesFocus: {1|0} let application take focus. doNotCover: {1|0} limits workspace if sticky. doNotFocus: {1|0} do not focus. + doNotManage: {1|0} do not manage. forcedClose: {1|0} no close confirmation dialog. fullKeys: {1|0} don't install icewm key bindings. ignoreNoFocusHint: {1|0} focus even when no-input is set. diff --git a/man/icewmhint.pod b/man/icewmhint.pod index 69f53196..6d72c363 100644 --- a/man/icewmhint.pod +++ b/man/icewmhint.pod @@ -198,6 +198,7 @@ advanced features are as follows: appTakesFocus let application take focus. doNotCover limits workspace if sticky. doNotFocus do not focus. + doNotManage do not manage. forcedClose no close dialog. fullKeys provided more keys. ignoreNoFocusHint focus even no-input. diff --git a/src/wmframe.h b/src/wmframe.h index f2eb0e87..33069dd4 100644 --- a/src/wmframe.h +++ b/src/wmframe.h @@ -265,6 +265,7 @@ class YFrameWindow: foNoIgnoreTaskBar = (1 << 20), foClose = (1 << 22), foIgnoreOverrideRedirect = (1 << 23), + foDoNotManage = (1 << 24), }; unsigned frameFunctions() const { return fFrameFunctions; } diff --git a/src/wmmgr.cc b/src/wmmgr.cc index df579752..62f01f2f 100644 --- a/src/wmmgr.cc +++ b/src/wmmgr.cc @@ -1736,6 +1736,27 @@ void YWindowManager::placeWindow(YFrameWindow *frame, frame->setNormalGeometryOuter(posX, posY, posWidth, posHeight); } +bool YWindowManager::isManageable(Window win, bool mapClient) { + bool manage = true; + if (WindowOptions::anyOption(YFrameWindow::foDoNotManage)) { + ClassHint hint; + if (hint.get(win) && + nonempty(hint.res_name) && hint.res_name[0] != '/') + { + WindowOption wo(hint.res_name); + if (hintOptions) + hintOptions->mergeWindowOption(wo, hint.res_name, false); + if (defOptions) + defOptions->mergeWindowOption(wo, hint.res_name, false); + if (wo.hasOption(YFrameWindow::foDoNotManage)) + manage = false; + if (manage == false && mapClient) + XMapWindow(xapp->display(), win); + } + } + return manage; +} + bool YWindowManager::ignoreOverride(Window win, const XWindowAttributes& attr, int* layer) { bool ignoring = false; @@ -1788,8 +1809,9 @@ YFrameClient* YWindowManager::allocateClient(Window win, bool mapClient) { XWindowAttributes attributes; int layer = WinLayerInvalid; if (XGetWindowAttributes(xapp->display(), win, &attributes) && - (attributes.override_redirect == false || - ignoreOverride(win, attributes, &layer)) && + (attributes.override_redirect + ? ignoreOverride(win, attributes, &layer) + : isManageable(win, mapClient)) && (mapClient || attributes.map_state > IsUnmapped)) { client = new YFrameClient(nullptr, nullptr, win, diff --git a/src/wmmgr.h b/src/wmmgr.h index 67d5b5dd..08ddd01f 100644 --- a/src/wmmgr.h +++ b/src/wmmgr.h @@ -329,6 +329,7 @@ class YWindowManager: }; bool ignoreOverride(Window win, const XWindowAttributes& attr, int* layer); + bool isManageable(Window win, bool mapClient); bool tabbingClient(YFrameClient* client); YFrameClient* allocateClient(Window win, bool mapClient); YFrameWindow* allocateFrame(YFrameClient* client); diff --git a/src/wmoption.cc b/src/wmoption.cc index 806b4013..f75a9d57 100644 --- a/src/wmoption.cc +++ b/src/wmoption.cc @@ -236,6 +236,7 @@ void WindowOptions::setWinOption(mstring n_class_instance, { "dTitleBar", YFrameWindow::fdTitleBar }, { "doNotCover", YFrameWindow::foDoNotCover }, { "doNotFocus", YFrameWindow::foDoNotFocus }, + { "doNotManage", YFrameWindow::foDoNotManage }, { "fClose", YFrameWindow::ffClose }, { "fHide", YFrameWindow::ffHide }, { "fMaximize", YFrameWindow::ffMaximize }, From 11868632e80ca5498af953e720447575a3547bbe Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Wed, 27 Sep 2023 23:44:19 +0200 Subject: [PATCH 7/8] Let icewmbg interpret command-line arguments relative to the current working directory for issue #497. Let icewmbg accept additional arguments as images or directories. Add -f,--fork option to icewmbg. Add --postpreferences option to icewmbg. --- man/icesh.pod | 1 + man/icewm-menu.pod | 8 +-- man/icewmbg.pod | 23 ++++++-- src/icewmbg.cc | 133 ++++++++++++++++++++++++++++++++++++--------- 4 files changed, 128 insertions(+), 37 deletions(-) diff --git a/man/icesh.pod b/man/icesh.pod index 04707c20..a9157c73 100644 --- a/man/icesh.pod +++ b/man/icesh.pod @@ -784,6 +784,7 @@ Let icewm refresh the desktop background. =item B Monitor the B property and report all changes. +Hit C to abort this and continue with the next command. =item B [I