📄 gntwm.c
字号:
populate_window_list(GntWM *wm){ GList *iter; GntTree *tree = GNT_TREE(wm->windows->tree); for (iter = wm->list; iter; iter = iter->next) { GntBox *box = GNT_BOX(iter->data); gnt_tree_add_row_last(tree, box, gnt_tree_create_row(tree, box->title), NULL); update_window_in_list(wm, GNT_WIDGET(box)); }}static gbooleanwindow_list_key_pressed(GntWidget *widget, const char *text, GntWM *wm){ if (text[1] == 0 && wm->ordered) { GntWidget *sel = gnt_tree_get_selection_data(GNT_TREE(widget)); switch (text[0]) { case '-': case ',': shift_window(wm, sel, -1); break; case '=': case '.': shift_window(wm, sel, 1); break; default: return FALSE; } gnt_tree_remove_all(GNT_TREE(widget)); populate_window_list(wm); gnt_tree_set_selected(GNT_TREE(widget), sel); return TRUE; } return FALSE;}static gbooleanwindow_list(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); GntWidget *tree, *win; if (wm->_list.window || wm->menu) return TRUE; if (!wm->ordered) return TRUE; setup__list(wm); wm->windows = &wm->_list; win = wm->windows->window; tree = wm->windows->tree; gnt_box_set_title(GNT_BOX(win), "Window List"); populate_window_list(wm); gnt_tree_set_selected(GNT_TREE(tree), wm->ordered->data); g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm); g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(window_list_key_pressed), wm); gnt_tree_set_col_width(GNT_TREE(tree), 0, getmaxx(stdscr) / 3); gnt_widget_set_size(tree, 0, getmaxy(stdscr) / 2); gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); gnt_widget_show(win); return TRUE;}static gbooleandump_screen(GntBindable *bindable, GList *null){ int x, y; chtype old = 0, now = 0; FILE *file = fopen("dump.html", "w"); struct { char ascii; char *unicode; } unis[] = { {'q', "─"}, {'t', "├"}, {'u', "┤"}, {'x', "│"}, {'-', "↑"}, {'.', "↓"}, {'l', "┌"}, {'k', "┐"}, {'m', "└"}, {'j', "┘"}, {'a', "▒"}, {'\0', NULL} }; fprintf(file, "<head>\n <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\n</head>\n<body>\n"); fprintf(file, "<pre>"); for (y = 0; y < getmaxy(stdscr); y++) { for (x = 0; x < getmaxx(stdscr); x++) { char ch[2] = {0, 0}, *print;#ifdef NO_WIDECHAR now = mvwinch(curscr, y, x); ch[0] = now & A_CHARTEXT; now ^= ch[0];#else cchar_t wch; char unicode[12]; mvwin_wch(curscr, y, x, &wch); now = wch.attr; ch[0] = (char)(wch.chars[0] & 0xff);#endif#define CHECK(attr, start, end) \ do \ { \ if (now & attr) \ { \ if (!(old & attr)) \ fprintf(file, "%s", start); \ } \ else if (old & attr) \ { \ fprintf(file, "%s", end); \ } \ } while (0) CHECK(A_BOLD, "<b>", "</b>"); CHECK(A_UNDERLINE, "<u>", "</u>"); CHECK(A_BLINK, "<blink>", "</blink>"); if ((now & A_COLOR) != (old & A_COLOR) || (now & A_REVERSE) != (old & A_REVERSE)) { int ret; short fgp, bgp, r, g, b; struct { int r, g, b; } fg, bg; ret = pair_content(PAIR_NUMBER(now & A_COLOR), &fgp, &bgp); if (fgp == -1) fgp = COLOR_BLACK; if (bgp == -1) bgp = COLOR_WHITE; if (now & A_REVERSE) { short tmp = fgp; fgp = bgp; bgp = tmp; } ret = color_content(fgp, &r, &g, &b); fg.r = r; fg.b = b; fg.g = g; ret = color_content(bgp, &r, &g, &b); bg.r = r; bg.b = b; bg.g = g;#define ADJUST(x) (x = x * 255 / 1000) ADJUST(fg.r); ADJUST(fg.g); ADJUST(fg.b); ADJUST(bg.r); ADJUST(bg.b); ADJUST(bg.g); if (x) fprintf(file, "</span>"); fprintf(file, "<span style=\"background:#%02x%02x%02x;color:#%02x%02x%02x\">", bg.r, bg.g, bg.b, fg.r, fg.g, fg.b); } print = ch;#ifndef NO_WIDECHAR if (wch.chars[0] > 255) { snprintf(unicode, sizeof(unicode), "&#x%x;", wch.chars[0]); print = unicode; }#endif if (now & A_ALTCHARSET) { int u; for (u = 0; unis[u].ascii; u++) { if (ch[0] == unis[u].ascii) { print = unis[u].unicode; break; } } if (!unis[u].ascii) print = " "; } if (ch[0] == '&') fprintf(file, "&"); else if (ch[0] == '<') fprintf(file, "<"); else if (ch[0] == '>') fprintf(file, ">"); else fprintf(file, "%s", print); old = now; } fprintf(file, "</span>\n"); old = 0; } fprintf(file, "</pre>\n</body>"); fclose(file); return TRUE;}static voidshift_window(GntWM *wm, GntWidget *widget, int dir){ GList *all = wm->list; GList *list = g_list_find(all, widget); int length, pos; if (!list) return; length = g_list_length(all); pos = g_list_position(all, list); pos += dir; if (dir > 0) pos++; if (pos < 0) pos = length; else if (pos > length) pos = 0; all = g_list_insert(all, widget, pos); all = g_list_delete_link(all, list); wm->list = all; draw_taskbar(wm, FALSE);}static gbooleanshift_left(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); if (wm->_list.window) return TRUE; shift_window(wm, wm->ordered->data, -1); return TRUE;}static gbooleanshift_right(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); if (wm->_list.window) return TRUE; shift_window(wm, wm->ordered->data, 1); return TRUE;}static voidaction_list_activate(GntTree *tree, GntWM *wm){ GntAction *action = gnt_tree_get_selection_data(tree); action->callback(); gnt_widget_destroy(wm->_list.window);}static intcompare_action(gconstpointer p1, gconstpointer p2){ const GntAction *a1 = p1; const GntAction *a2 = p2; return g_utf8_collate(a1->label, a2->label);}static gbooleanlist_actions(GntBindable *bindable, GList *null){ GntWidget *tree, *win; GList *iter; GntWM *wm = GNT_WM(bindable); if (wm->_list.window || wm->menu) return TRUE; if (wm->acts == NULL) return TRUE; setup__list(wm); wm->actions = &wm->_list; win = wm->actions->window; tree = wm->actions->tree; gnt_box_set_title(GNT_BOX(win), "Actions"); GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); /* XXX: Do we really want this? */ gnt_tree_set_compare_func(GNT_TREE(tree), compare_action); for (iter = wm->acts; iter; iter = iter->next) { GntAction *action = iter->data; gnt_tree_add_row_last(GNT_TREE(tree), action, gnt_tree_create_row(GNT_TREE(tree), action->label), NULL); } g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(action_list_activate), wm); gnt_widget_set_size(tree, 0, g_list_length(wm->acts)); gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - g_list_length(wm->acts)); gnt_widget_show(win); return TRUE;}#ifndef NO_WIDECHARstatic intwidestringwidth(wchar_t *wide){ int len, ret; char *string; len = wcstombs(NULL, wide, 0) + 1; string = g_new0(char, len); wcstombs(string, wide, len); ret = gnt_util_onscreen_width(string, NULL); g_free(string); return ret;}#endif/* Returns the onscreen width of the character at the position */static intreverse_char(WINDOW *d, int y, int x, gboolean set){#define DECIDE(ch) (set ? ((ch) | A_REVERSE) : ((ch) & ~A_REVERSE))#ifdef NO_WIDECHAR chtype ch; ch = mvwinch(d, y, x); mvwaddch(d, y, x, DECIDE(ch)); return 1;#else cchar_t ch; int wc = 1; if (mvwin_wch(d, y, x, &ch) == OK) { wc = widestringwidth(ch.chars); ch.attr = DECIDE(ch.attr); ch.attr &= WA_ATTRIBUTES; /* XXX: This is a workaround for a bug */ mvwadd_wch(d, y, x, &ch); } return wc;#endif}static voidwindow_reverse(GntWidget *win, gboolean set, GntWM *wm){ int i; int w, h; WINDOW *d; if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER)) return; d = win->window; gnt_widget_get_size(win, &w, &h); if (gnt_widget_has_shadow(win)) { --w; --h; } /* the top and bottom */ for (i = 0; i < w; i += reverse_char(d, 0, i, set)); for (i = 0; i < w; i += reverse_char(d, h-1, i, set)); /* the left and right */ for (i = 0; i < h; i += reverse_char(d, i, 0, set)); for (i = 0; i < h; i += reverse_char(d, i, w-1, set)); copy_win(win, g_hash_table_lookup(wm->nodes, win)); update_screen(wm);}static gbooleanstart_move(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); if (wm->_list.window || wm->menu) return TRUE; if (!wm->ordered) return TRUE; wm->mode = GNT_KP_MODE_MOVE; window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); return TRUE;}static gbooleanstart_resize(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); if (wm->_list.window || wm->menu) return TRUE; if (!wm->ordered) return TRUE; wm->mode = GNT_KP_MODE_RESIZE; window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); return TRUE;}static gbooleanwm_quit(GntBindable *bindable, GList *list){ GntWM *wm = GNT_WM(bindable); if (write_timeout) write_already(wm); g_main_loop_quit(wm->loop); return TRUE;}static gbooleanreturn_true(GntWM *wm, GntWidget *w, int *a, int *b){ return TRUE;}static gbooleanrefresh_screen(GntBindable *bindable, GList *null){ GntWM *wm = GNT_WM(bindable); endwin(); refresh(); curs_set(0); /* endwin resets the cursor to normal */ g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, NULL); update_screen(wm); draw_taskbar(wm, TRUE); return FALSE;}static gbooleantoggle_clipboard(GntBindable *bindable, GList *n){ static GntWidget *clip; gchar *text; int maxx, maxy; if (clip) { gnt_widget_destroy(clip); clip = NULL; return TRUE; } getmaxyx(stdscr, maxy, maxx); text = gnt_get_clipboard_string(); clip = gnt_hwindow_new(FALSE); GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_TRANSIENT); GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_NO_BORDER); gnt_box_set_pad(GNT_BOX(clip), 0); gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(" ")); gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(text)); gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(" ")); gnt_widget_set_position(clip, 0, 0); gnt_widget_draw(clip); g_free(text); return TRUE;}static voidgnt_wm_class_init(GntWMClass *klass){ int i; klass->new_window = gnt_wm_new_window_real; klass->decorate_window = NULL; klass->close_window = NULL; klass->window_resize_confirm = return_true; klass->window_resized = gnt_wm_win_resized; klass->window_move_confirm = return_true; klass->window_moved = gnt_wm_win_moved; klass->window_update = NULL; klass->key_pressed = NULL; klass->mouse_clicked = NULL; klass->give_focus = gnt_wm_give_focus; signals[SIG_NEW_WIN] = g_signal_new("new_win", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, new_window), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_DECORATE_WIN] = g_signal_new("decorate_win", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, decorate_window), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_CLOSE_WIN] = g_signal_new("close_win", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, close_window), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_CONFIRM_RESIZE] = g_signal_new("confirm_resize", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, window_resize_confirm), gnt_boolean_handled_accumulator, NULL, gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER, G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER); signals[SIG_CONFIRM_MOVE] = g_signal_new("confirm_move", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, window_move_confirm), gnt_boolean_handled_accumulator, NULL, gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER, G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER); signals[SIG_RESIZED] = g_signal_new("window_resized", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, window_resized), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_MOVED] = g_signal_new("window_moved", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, window_moved), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_UPDATE_WIN] = g_signal_new("window_update", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, window_update), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_GIVE_FOCUS] = g_signal_new("give_focus",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -