diff --git a/ChangeLog b/ChangeLog
index 957e0090a4610ee06cfc9d2fe0fd1dab37c8c384..80ef0f9410d73048b8b2369954a232d4dcca1d49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
 What's new in version 0.9.1
 
 * Switch from PLPA, which is now deprecated, to HWLOC.
+* Support for UTF-8 tree drawing
+  (thanks to Bin Guo)
 * Option for counting CPUs from zero
   (thanks to Sean Noonan)
 * Meters update in every screen (no longer halting while on Setup, etc.)
diff --git a/Process.c b/Process.c
index 0632278a27c8f8981f40a2bd9fca9faac8b22048..31c874066b40262c4fcd5d1d99d81610c509f840 100644
--- a/Process.c
+++ b/Process.c
@@ -387,21 +387,26 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
       } else {
          char* buf = buffer;
          int maxIndent = 0;
+         const char **treeStr = this->pl->treeStr;
+         bool lastItem = (this->indent < 0);
+         int indent = (this->indent < 0 ? -this->indent : this->indent);
+         if (treeStr == NULL)
+             treeStr = ProcessList_treeStrAscii;
+
          for (int i = 0; i < 32; i++)
-            if (this->indent & (1 << i))
+            if (indent & (1 << i))
                maxIndent = i+1;
           for (int i = 0; i < maxIndent - 1; i++) {
-            if (this->indent & (1 << i))
-               snprintf(buf, n, " |  ");
+            int written;
+            if (indent & (1 << i))
+               written = snprintf(buf, n, "%s  ", treeStr[TREE_STR_VERT]);
             else
-               snprintf(buf, n, "    ");
-            buf += 4;
-            n -= 4;
+               written = snprintf(buf, n, "   ");
+            buf += written;
+            n -= written;
          }
-         if (this->pl->direction == 1)
-            snprintf(buf, n, " `%s ", this->showChildren ? "-" : "+" );
-         else
-            snprintf(buf, n, " ,%s ", this->showChildren ? "-" : "+" );
+         const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
+         snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
          RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
          Process_writeCommand(this, attr, baseattr, str);
          return;
diff --git a/ProcessList.c b/ProcessList.c
index c986cecd00dd8ba61dfb986e047b9a566311ae29..b681fededf3c1186a67322acee5ca218ad350669 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -57,9 +57,23 @@ in the source distribution for its full text.
 #ifndef ProcessList_cpuId
 #define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
 #endif
-}*/
 
-/*{
+typedef enum TreeStr_ {
+   TREE_STR_HORZ,
+   TREE_STR_VERT,
+   TREE_STR_RTEE,
+   TREE_STR_BEND,
+   TREE_STR_TEND,
+   TREE_STR_OPEN,
+   TREE_STR_SHUT,
+   TREE_STR_COUNT
+} TreeStr;
+
+typedef enum TreeType_ {
+   TREE_TYPE_AUTO,
+   TREE_TYPE_ASCII,
+   TREE_TYPE_UTF8,
+} TreeType;
 
 typedef struct CPUData_ {
    unsigned long long int totalTime;
@@ -132,12 +146,34 @@ typedef struct ProcessList_ {
    bool highlightThreads;
    bool detailedCPUTime;
    bool countCPUsFromZero;
+   const char **treeStr;
 
 } ProcessList;
+
 }*/
 
 static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
 
+const char *ProcessList_treeStrAscii[TREE_STR_COUNT] = {
+   "-", // TREE_STR_HORZ
+   "|", // TREE_STR_VERT
+   "`", // TREE_STR_RTEE
+   "`", // TREE_STR_BEND
+   ",", // TREE_STR_TEND
+   "+", // TREE_STR_OPEN
+   "-", // TREE_STR_SHUT
+};
+
+const char *ProcessList_treeStrUtf8[TREE_STR_COUNT] = {
+   "\xe2\x94\x80", // TREE_STR_HORZ ─
+   "\xe2\x94\x82", // TREE_STR_VERT │
+   "\xe2\x94\x9c", // TREE_STR_RTEE ├
+   "\xe2\x94\x94", // TREE_STR_BEND â””
+   "\xe2\x94\x8c", // TREE_STR_TEND ┌
+   "+",            // TREE_STR_OPEN +
+   "\xe2\x94\x80", // TREE_STR_SHUT ─
+};
+
 ProcessList* ProcessList_new(UsersTable* usersTable) {
    ProcessList* this;
    this = calloc(sizeof(ProcessList), 1);
@@ -194,6 +230,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
    this->highlightMegabytes = false;
    this->detailedCPUTime = false;
    this->countCPUsFromZero = false;
+   this->treeStr = NULL;
 
    return this;
 }
@@ -282,7 +319,10 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
       assert(this->processes2->items == s+1); (void)s;
       int nextIndent = indent | (1 << level);
       ProcessList_buildTree(this, process->pid, level+1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
-      process->indent = nextIndent;
+      if (i == size - 1)
+         process->indent = -nextIndent;
+      else
+         process->indent = nextIndent;
    }
    Vector_delete(children);
 }
diff --git a/ProcessList.h b/ProcessList.h
index e68ca49eea3ee43de4bfc57dc4fad307cf9fb715..5432c187a88a9340725c425e13b0d17b864de475 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -60,6 +60,22 @@ in the source distribution for its full text.
 #define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
 #endif
 
+typedef enum TreeStr_ {
+   TREE_STR_HORZ,
+   TREE_STR_VERT,
+   TREE_STR_RTEE,
+   TREE_STR_BEND,
+   TREE_STR_TEND,
+   TREE_STR_OPEN,
+   TREE_STR_SHUT,
+   TREE_STR_COUNT
+} TreeStr;
+
+typedef enum TreeType_ {
+   TREE_TYPE_AUTO,
+   TREE_TYPE_ASCII,
+   TREE_TYPE_UTF8,
+} TreeType;
 
 typedef struct CPUData_ {
    unsigned long long int totalTime;
@@ -132,9 +148,15 @@ typedef struct ProcessList_ {
    bool highlightThreads;
    bool detailedCPUTime;
    bool countCPUsFromZero;
+   const char **treeStr;
 
 } ProcessList;
 
+
+extern const char *ProcessList_treeStrAscii[TREE_STR_COUNT];
+
+extern const char *ProcessList_treeStrUtf8[TREE_STR_COUNT];
+
 ProcessList* ProcessList_new(UsersTable* usersTable);
 
 void ProcessList_delete(ProcessList* this);
diff --git a/htop.c b/htop.c
index 10924a1d914ee1035895ba3cafed81dfbeaad72a..b71198a6de029a93667d3f613c8eaf4c0933ba38 100644
--- a/htop.c
+++ b/htop.c
@@ -263,6 +263,7 @@ int main(int argc, char** argv) {
    bool userOnly = false;
    uid_t userId = 0;
    int usecolors = 1;
+   TreeType treeType = TREE_TYPE_AUTO;
 
    int opt, opti=0;
    static struct option long_opts[] =
@@ -281,8 +282,10 @@ int main(int argc, char** argv) {
    char *lc_ctype = getenv("LC_CTYPE");
    if(lc_ctype != NULL)
       setlocale(LC_CTYPE, lc_ctype);
+   else if ((lc_ctype = getenv("LC_ALL")))
+      setlocale(LC_CTYPE, lc_ctype);
    else
-      setlocale(LC_CTYPE, getenv("LC_ALL"));
+      setlocale(LC_CTYPE, "");
 
    /* Parse arguments */
    while ((opt = getopt_long(argc, argv, "hvCs:d:u:", long_opts, &opti))) {
@@ -361,6 +364,34 @@ int main(int argc, char** argv) {
       settings->delay = delay;
    if (!usecolors) 
       settings->colorScheme = COLORSCHEME_MONOCHROME;
+
+   if (treeType == TREE_TYPE_AUTO) {
+#ifdef HAVE_LIBNCURSESW
+      char *locale = setlocale(LC_ALL, NULL);
+      if (locale == NULL || locale[0] == '\0')
+         locale = setlocale(LC_CTYPE, NULL);
+      if (locale != NULL &&
+          (strstr(locale, "UTF-8") ||
+           strstr(locale, "utf-8") ||
+           strstr(locale, "UTF8")  ||
+           strstr(locale, "utf8")))
+         treeType = TREE_TYPE_UTF8;
+      else
+         treeType = TREE_TYPE_ASCII;
+#else
+      treeType = TREE_TYPE_ASCII;
+#endif
+   }
+   switch (treeType) {
+   default:
+   case TREE_TYPE_ASCII:
+      pl->treeStr = ProcessList_treeStrAscii;
+      break;
+   case TREE_TYPE_UTF8:
+      pl->treeStr = ProcessList_treeStrUtf8;
+      break;
+   }
+
    
    CRT_init(settings->delay, settings->colorScheme);