📄 gntwm.c
字号:
G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, give_focus), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[SIG_MOUSE_CLICK] = g_signal_new("mouse_clicked", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWMClass, mouse_clicked), gnt_boolean_handled_accumulator, NULL, gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER, G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-next", window_next, "\033" "n", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-prev", window_prev, "\033" "p", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-close", window_close, "\033" "c", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-list", window_list, "\033" "w", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "dump-screen", dump_screen, "\033" "d", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-left", shift_left, "\033" ",", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-right", shift_right, "\033" ".", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "action-list", list_actions, "\033" "a", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-move", start_move, "\033" "m", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-resize", start_resize, "\033" "r", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "wm-quit", wm_quit, "\033" "q", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "refresh-screen", refresh_screen, "\033" "l", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "switch-window-n", switch_window_n, NULL, NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-down", window_scroll_down, "\033" GNT_KEY_CTRL_J, NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-up", window_scroll_up, "\033" GNT_KEY_CTRL_K, NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-widget", help_for_widget, "\033" "/", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-clipboard", toggle_clipboard, "\033" "C", NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); /* Make sure Alt+x are detected properly. */ for (i = '0'; i <= '9'; i++) { char str[] = "\033X"; str[1] = i; gnt_keys_add_combination(str); } GNTDEBUG;}/****************************************************************************** * GntWM API *****************************************************************************/GTypegnt_wm_get_gtype(void){ static GType type = 0; if(type == 0) { static const GTypeInfo info = { sizeof(GntWMClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc)gnt_wm_class_init, NULL, NULL, /* class_data */ sizeof(GntWM), 0, /* n_preallocs */ gnt_wm_init, /* instance_init */ NULL /* value_table */ }; type = g_type_register_static(GNT_TYPE_BINDABLE, "GntWM", &info, 0); } return type;}static voidupdate_window_in_list(GntWM *wm, GntWidget *wid){ GntTextFormatFlags flag = 0; if (wm->windows == NULL) return; if (wid == wm->ordered->data) flag |= GNT_TEXT_FLAG_DIM; else if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT)) flag |= GNT_TEXT_FLAG_BOLD; gnt_tree_set_row_flags(GNT_TREE(wm->windows->tree), wid, flag);}static voidgnt_wm_new_window_real(GntWM *wm, GntWidget *widget){ GntNode *node; gboolean transient = FALSE; if (widget->window == NULL) return; node = g_new0(GntNode, 1); node->me = widget; node->scroll = 0; g_hash_table_replace(wm->nodes, widget, node); refresh_node(widget, node, NULL); transient = !!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT);#if 1 { int x, y, w, h, maxx, maxy; gboolean shadow = TRUE; if (!gnt_widget_has_shadow(widget)) shadow = FALSE; x = widget->priv.x; y = widget->priv.y; w = widget->priv.width; h = widget->priv.height; getmaxyx(stdscr, maxy, maxx); maxy -= 1; /* room for the taskbar */ maxy -= shadow; maxx -= shadow; x = MAX(0, x); y = MAX(0, y); if (x + w >= maxx) x = MAX(0, maxx - w); if (y + h >= maxy) y = MAX(0, maxy - h); w = MIN(w, maxx); h = MIN(h, maxy); node->window = newwin(h + shadow, w + shadow, y, x); copy_win(widget, node); }#endif node->panel = new_panel(node->window); set_panel_userptr(node->panel, node); if (!transient) { if (node->me != wm->_list.window) { GntWidget *w = NULL; if (wm->ordered) w = wm->ordered->data; wm->list = g_list_append(wm->list, widget); if (wm->event_stack) wm->ordered = g_list_prepend(wm->ordered, widget); else wm->ordered = g_list_append(wm->ordered, widget); gnt_widget_set_focus(widget, TRUE); if (w) gnt_widget_set_focus(w, FALSE); } if (wm->event_stack || node->me == wm->_list.window) { gnt_wm_raise_window(wm, node->me); } else { bottom_panel(node->panel); /* New windows should not grab focus */ gnt_widget_set_urgent(node->me); } }}void gnt_wm_new_window(GntWM *wm, GntWidget *widget){ while (widget->parent) widget = widget->parent; if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_INVISIBLE) || g_hash_table_lookup(wm->nodes, widget)) { update_screen(wm); return; } if (GNT_IS_BOX(widget)) { const char *title = GNT_BOX(widget)->title; GntPosition *p = NULL; if (title && (p = g_hash_table_lookup(wm->positions, title)) != NULL) { sanitize_position(widget, &p->x, &p->y); gnt_widget_set_position(widget, p->x, p->y); mvwin(widget->window, p->y, p->x); } } g_signal_emit(wm, signals[SIG_NEW_WIN], 0, widget); g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget); if (wm->windows && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && wm->_list.window != widget && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) { gnt_tree_add_row_last(GNT_TREE(wm->windows->tree), widget, gnt_tree_create_row(GNT_TREE(wm->windows->tree), GNT_BOX(widget)->title), NULL); update_window_in_list(wm, widget); } } update_screen(wm); draw_taskbar(wm, FALSE);}void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget){ g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget);}void gnt_wm_window_close(GntWM *wm, GntWidget *widget){ GntNode *node; int pos; if ((node = g_hash_table_lookup(wm->nodes, widget)) == NULL) return; g_signal_emit(wm, signals[SIG_CLOSE_WIN], 0, widget); g_hash_table_remove(wm->nodes, widget); if (wm->windows) { gnt_tree_remove(GNT_TREE(wm->windows->tree), widget); } pos = g_list_index(wm->list, widget); if (pos != -1) { wm->list = g_list_remove(wm->list, widget); wm->ordered = g_list_remove(wm->ordered, widget); if (wm->ordered) gnt_wm_raise_window(wm, wm->ordered->data); } update_screen(wm); draw_taskbar(wm, FALSE);}time_t gnt_wm_get_idle_time(){ return time(NULL) - last_active_time;}gboolean gnt_wm_process_input(GntWM *wm, const char *keys){ gboolean ret = FALSE; keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys); idle_update = TRUE; if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) { return TRUE; } /* Do some manual checking */ if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) { int xmin = 0, ymin = 0, xmax = getmaxx(stdscr), ymax = getmaxy(stdscr) - 1; int x, y, w, h; GntWidget *widget = GNT_WIDGET(wm->ordered->data); int ox, oy, ow, oh; gnt_widget_get_position(widget, &x, &y); gnt_widget_get_size(widget, &w, &h); ox = x; oy = y; ow = w; oh = h; if (wm->mode == GNT_KP_MODE_MOVE) { if (strcmp(keys, GNT_KEY_LEFT) == 0) { if (x > xmin) x--; } else if (strcmp(keys, GNT_KEY_RIGHT) == 0) { if (x + w < xmax) x++; } else if (strcmp(keys, GNT_KEY_UP) == 0) { if (y > ymin) y--; } else if (strcmp(keys, GNT_KEY_DOWN) == 0) { if (y + h < ymax) y++; } if (ox != x || oy != y) { gnt_screen_move_widget(widget, x, y); window_reverse(widget, TRUE, wm); return TRUE; } } else if (wm->mode == GNT_KP_MODE_RESIZE) { if (strcmp(keys, GNT_KEY_LEFT) == 0) { w--; } else if (strcmp(keys, GNT_KEY_RIGHT) == 0) { if (x + w < xmax) w++; } else if (strcmp(keys, GNT_KEY_UP) == 0) { h--; } else if (strcmp(keys, GNT_KEY_DOWN) == 0) { if (y + h < ymax) h++; } if (oh != h || ow != w) { gnt_screen_resize_widget(widget, w, h); window_reverse(widget, TRUE, wm); return TRUE; } } if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) { window_reverse(widget, FALSE, wm); wm->mode = GNT_KP_MODE_NORMAL; } return TRUE; } /* Escape to close the window-list or action-list window */ if (strcmp(keys, "\033") == 0) { if (wm->_list.window) { gnt_widget_destroy(wm->_list.window); return TRUE; } } else if (keys[0] == '\033' && isdigit(keys[1]) && keys[2] == '\0') { /* Alt+x for quick switch */ int n = *(keys + 1) - '0'; GList *list = NULL; if (n == 0) n = 10; list = g_list_append(list, GINT_TO_POINTER(n - 1)); switch_window_n(GNT_BINDABLE(wm), list); g_list_free(list); return TRUE; } if (wm->menu) ret = gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); else if (wm->_list.window) ret = gnt_widget_key_pressed(wm->_list.window, keys); else if (wm->ordered) ret = gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys); return ret;}static voidgnt_wm_win_resized(GntWM *wm, GntNode *node){ /*refresh_node(node->me, node, NULL);*/}static voidgnt_wm_win_moved(GntWM *wm, GntNode *node){ refresh_node(node->me, node, NULL);}void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height){ gboolean ret = TRUE; GntNode *node; int shadow; int maxx, maxy; while (widget->parent) widget = widget->parent; node = g_hash_table_lookup(wm->nodes, widget); if (!node) return; g_signal_emit(wm, signals[SIG_CONFIRM_RESIZE], 0, widget, &width, &height, &ret); if (!ret) return; /* resize is not permitted */ hide_panel(node->panel); gnt_widget_set_size(widget, width, height); gnt_widget_draw(widget); shadow = gnt_widget_has_shadow(widget) ? 1 : 0; maxx = getmaxx(stdscr) - shadow; maxy = getmaxy(stdscr) - 1 - shadow; height = MIN(height, maxy); width = MIN(width, maxx); wresize(node->window, height, width); replace_panel(node->panel, node->window); g_signal_emit(wm, signals[SIG_RESIZED], 0, node); show_panel(node->panel); update_screen(wm);}static voidwrite_gdi(gpointer key, gpointer value, gpointer data){ GntPosition *p = value; fprintf(data, ".%s = %d;%d\n", (char *)key, p->x, p->y);}static gbooleanwrite_already(gpointer data){ GntWM *wm = data; FILE *file; char *filename; filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); file = fopen(filename, "wb"); if (file == NULL) { g_printerr("GntWM: error opening file to save positions\n"); } else { fprintf(file, "[positions]\n"); g_hash_table_foreach(wm->positions, write_gdi, file); fclose(file); } g_free(filename); g_source_remove(write_timeout); write_timeout = 0; return FALSE;}static voidwrite_positions_to_file(GntWM *wm){ if (write_timeout) { g_source_remove(write_timeout); } write_timeout = g_timeout_add(10000, write_already, wm);}void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y){ gboolean ret = TRUE; GntNode *node; while (widget->parent) widget = widget->parent; node = g_hash_table_lookup(wm->nodes, widget); if (!node) return; g_signal_emit(wm, signals[SIG_CONFIRM_MOVE], 0, widget, &x, &y, &ret); if (!ret) return; /* resize is not permitted */ gnt_widget_set_position(widget, x, y); move_panel(node->panel, y, x); g_signal_emit(wm, signals[SIG_MOVED], 0, node); if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE) && GNT_IS_BOX(widget) && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { const char *title = GNT_BOX(widget)->title; if (title) { GntPosition *p = g_new0(GntPosition, 1); GntWidget *wid = node->me; p->x = wid->priv.x; p->y = wid->priv.y; g_hash_table_replace(wm->positions, g_strdup(title), p); write_positions_to_file(wm); } } update_screen(wm);}static voidgnt_wm_give_focus(GntWM *wm, GntWidget *widget){ GntNode *node = g_hash_table_lookup(wm->nodes, widget); if (!node) return; if (widget != wm->_list.window && !GNT_IS_MENU(widget) && wm->ordered->data != widget) { GntWidget *w = wm->ordered->data; wm->ordered = g_list_bring_to_front(wm->ordered, widget); gnt_widget_set_focus(w, FALSE); } gnt_widget_set_focus(widget, TRUE); GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_URGENT); gnt_widget_draw(widget); top_panel(node->panel); if (wm->_list.window) { GntNode *nd = g_hash_table_lookup(wm->nodes, wm->_list.window); top_panel(nd->panel); } update_screen(wm); draw_taskbar(wm, FALSE);}void gnt_wm_update_window(GntWM *wm, GntWidget *widget){ GntNode *node; while (widget->parent) widget = widget->parent; if (!GNT_IS_MENU(widget)) gnt_box_sync_children(GNT_BOX(widget)); node = g_hash_table_lookup(wm->nodes, widget); if (node == NULL) { gnt_wm_new_window(wm, widget); } else g_signal_emit(wm, signals[SIG_UPDATE_WIN], 0, node); copy_win(widget, node); update_screen(wm); draw_taskbar(wm, FALSE);}gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget){ gboolean ret = TRUE; idle_update = TRUE; g_signal_emit(wm, signals[SIG_MOUSE_CLICK], 0, event, x, y, widget, &ret); return ret;}void gnt_wm_raise_window(GntWM *wm, GntWidget *widget){ g_signal_emit(wm, signals[SIG_GIVE_FOCUS], 0, widget);}void gnt_wm_set_event_stack(GntWM *wm, gboolean set){ wm->event_stack = set;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -