martanne / abduco

abduco provides session management i.e. it allows programs to be run independently from its controlling terminal. That is programs can be detached - run in the background - and then later reattached. Together with dvtm it provides a simpler and cleaner alternative to tmux or screen.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Attachment/Detachment is not working propertly

vbarbarosh opened this issue · comments

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.2 (jessie)
Release:    8.2
Codename:   jessie
$ wget https://github.com/martanne/abduco/archive/v0.4.tar.gz
$ tar xf v0.4.tar.gz
$ cd abduco-0.4
$ make
$ ./abduco -c hello htop

1

--- CTRL-\ ---

$ ./abduco
Active sessions (on host corei3)
$ ./abduco -a hello

2
3

Thanks for the detailed report!

abduco expects that the client application redraws its complete user interface after having received a SIGWINCH signal. This doesn't seem to be the case for htop though (maybe its developers want to chime in and correct me here @hishamhm). If you resize the terminal (either before or after re-attaching) it redraws correctly, right?

A short term "solution" is to run abduco -c hello dvtm htop that way dvtm will catch the SIGWINCH signal and redraw all its client windows even if the terminal size did not change.

@martanne Hi! I produce a full redraw in htop when I get a KEY_RESIZE from ncurses. Perhaps ncurses is not triggering a KEY_RESIZE event if it gets SIGWINCH and the size didn't really change.

That is what I suspected, but after skimming through the ncurses sources (they are a big mess by the way) it seems to emit it. I wrote the following test program to confirm it.

#include <curses.h>
#include <time.h>

int main(int argc, char *argv[]) {
        initscr();
        for (;;) {
                int key = getch();
                switch (key) {
                case ERR:
                        addstr("getch failed\n");
                        break;
                case KEY_RESIZE:
                {
                        char buf[1024];
                        time_t t = time(NULL);
                        struct tm *now = localtime(&t);
                        if (!now) {
                                addstr("localtime failed\n");
                                break;
                        }
                        strftime(buf, sizeof buf, "%c", now);
                        addstr(buf);
                        addstr(" RESIZE\n");
                        break;
                }
                case 'q':
                        endwin();
                        return 0;
                }
                refresh();
        }
}

I think the "problem" is that curses caches the screen content, when you then redraw the interface in response to a KEY_RESIZE it will only emit the changes made since the last redraw (it doesn't know that we are connecting from an empty terminal). Adding a clear() call before redrawing the user interface would likely fix it. Is there a central place to add such a call and confirm my suspicion?

Is there a central place to add such a call and confirm my suspicion?

In htop? In current git, I think you can do it in function ScreenManager_resize.

That is what I had expected, unfortunately ScreenManager_resize never gets called. What happens is the following ScreenManager_run

The patch below seems to fix the issue for me. I also added a clear call to ScreenManager_resize in case other panels do not handle KEY_RESIZE on their own.

From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= <mat@brain-dump.org>
Date: Thu, 7 Jan 2016 12:32:57 +0100
Subject: [PATCH] Redraw complete user interface upon terminal resize

---
 Action.c        | 10 +++++-----
 ScreenManager.c |  1 +
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/Action.c b/Action.c
index 5e0e109..e81fe97 100644
--- a/Action.c
+++ b/Action.c
@@ -183,11 +183,6 @@ static Htop_Reaction sortBy(State* st) {

 // ----------------------------------------

-static Htop_Reaction actionResize(State* st) {
-   Panel_resize(st->panel, COLS, LINES-(st->panel->y)-1);
-   return HTOP_REDRAW_BAR;
-}
-
 static Htop_Reaction actionSortByMemory(State* st) {
    return Action_setSortKey(st->settings, PERCENT_MEM);
 }
@@ -377,6 +372,11 @@ static Htop_Reaction actionRedraw() {
    return HTOP_REFRESH | HTOP_REDRAW_BAR;
 }

+static Htop_Reaction actionResize(State* st) {
+   Panel_resize(st->panel, COLS, LINES-(st->panel->y)-1);
+   return actionRedraw();
+}
+
 static struct { const char* key; const char* info; } helpLeft[] = {
    { .key = " Arrows: ", .info = "scroll process list" },
    { .key = " Digits: ", .info = "incremental PID search" },
diff --git a/ScreenManager.c b/ScreenManager.c
index df7431f..c328f07 100644
--- a/ScreenManager.c
+++ b/ScreenManager.c
@@ -99,6 +99,7 @@ Panel* ScreenManager_remove(ScreenManager* this, int idx) {
 }

 void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
+   clear();
    this->x1 = x1;
    this->y1 = y1;
    this->x2 = x2;
-- 
2.6.4