static void update_mouse_cursor (GtkTextView *text_view, gint x, gint y) { static GdkCursor *hand_cursor = NULL; static GdkCursor *regular_cursor = NULL; gboolean hovering = FALSE, hovering_over_link = FALSE, hovering_real; guint32 state; GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view); GtkTextTagTable *tag_table; GtkTextTag *tag; GtkTextIter iter; if (!hand_cursor) { hand_cursor = gdk_cursor_new (GDK_HAND2); regular_cursor = gdk_cursor_new (GDK_XTERM); } g_return_if_fail (buffer != NULL); tag_table = gtk_text_buffer_get_tag_table (buffer); tag = gtk_text_tag_table_lookup (tag_table, E_BUFFER_TAGGER_LINK_TAG); g_return_if_fail (tag != NULL); state = get_state (buffer); gtk_text_view_get_iter_at_location (text_view, &iter, x, y); hovering_real = gtk_text_iter_has_tag (&iter, tag); hovering_over_link = (state & E_BUFFER_TAGGER_STATE_IS_HOVERING) != 0; if ((state & E_BUFFER_TAGGER_STATE_CTRL_DOWN) == 0) { hovering = FALSE; } else { hovering = hovering_real; } if (hovering != hovering_over_link) { update_state (buffer, E_BUFFER_TAGGER_STATE_IS_HOVERING, hovering); if (hovering && gtk_widget_has_focus (GTK_WIDGET (text_view))) gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor); else gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor); /* XXX Is this necessary? Appears to be a no-op. */ get_pointer_position (text_view, NULL, NULL); } hovering_over_link = (state & E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP) != 0; if (hovering_real != hovering_over_link) { update_state (buffer, E_BUFFER_TAGGER_STATE_IS_HOVERING_TOOLTIP, hovering_real); gtk_widget_trigger_tooltip_query (GTK_WIDGET (text_view)); } }
static void update_ctrl_state (GtkTextView *textview, gboolean ctrl_is_down) { GtkTextBuffer *buffer; gint x, y; buffer = gtk_text_view_get_buffer (textview); if (buffer) { if (((get_state (buffer) & E_BUFFER_TAGGER_STATE_CTRL_DOWN) != 0) != (ctrl_is_down != FALSE)) { update_state (buffer, E_BUFFER_TAGGER_STATE_CTRL_DOWN, ctrl_is_down != FALSE); } get_pointer_position (textview, &x, &y); gtk_text_view_window_to_buffer_coords (textview, GTK_TEXT_WINDOW_WIDGET, x, y, &x, &y); update_mouse_cursor (textview, x, y); } }
static gboolean textview_visibility_notify_event (GtkTextView *textview, GdkEventVisibility *event) { gint wx, wy, bx, by; g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); get_pointer_position (textview, &wx, &wy); gtk_text_view_window_to_buffer_coords ( textview, GTK_TEXT_WINDOW_WIDGET, wx, wy, &bx, &by); update_mouse_cursor (textview, bx, by); return FALSE; }
void setup(void) { ewmh_init(); screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; if (!screen) err("error: cannot aquire screen\n"); screen_width = screen->width_in_pixels; screen_height = screen->height_in_pixels; root_depth = screen->root_depth; xcb_atom_t net_atoms[] = {ewmh->_NET_SUPPORTED, ewmh->_NET_DESKTOP_NAMES, ewmh->_NET_NUMBER_OF_DESKTOPS, ewmh->_NET_CURRENT_DESKTOP, ewmh->_NET_CLIENT_LIST, ewmh->_NET_ACTIVE_WINDOW, ewmh->_NET_WM_DESKTOP, ewmh->_NET_WM_STATE, ewmh->_NET_WM_STATE_FULLSCREEN, ewmh->_NET_WM_WINDOW_TYPE, ewmh->_NET_WM_WINDOW_TYPE_DOCK, ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION, ewmh->_NET_WM_WINDOW_TYPE_DIALOG, ewmh->_NET_WM_WINDOW_TYPE_UTILITY, ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR}; xcb_ewmh_set_supported(ewmh, default_screen, LENGTH(net_atoms), net_atoms); monitor_uid = desktop_uid = client_uid = 0; mon = last_mon = mon_head = mon_tail = NULL; bool xinerama_is_active = false; if (xcb_get_extension_data(dpy, &xcb_xinerama_id)->present) { xcb_xinerama_is_active_reply_t *xia = xcb_xinerama_is_active_reply(dpy, xcb_xinerama_is_active(dpy), NULL); if (xia != NULL) { xinerama_is_active = xia->state; free(xia); } } if (xinerama_is_active) { xcb_xinerama_query_screens_reply_t *xsq = xcb_xinerama_query_screens_reply(dpy, xcb_xinerama_query_screens(dpy), NULL); xcb_xinerama_screen_info_t *xsi = xcb_xinerama_query_screens_screen_info(xsq); int n = xcb_xinerama_query_screens_screen_info_length(xsq); PRINTF("number of monitors: %d\n", n); for (int i = 0; i < n; i++) { xcb_xinerama_screen_info_t info = xsi[i]; xcb_rectangle_t rect = (xcb_rectangle_t) {info.x_org, info.y_org, info.width, info.height}; add_monitor(&rect); } free(xsq); } else { warn("Xinerama is inactive"); xcb_rectangle_t rect = (xcb_rectangle_t) {0, 0, screen_width, screen_height}; add_monitor(&rect); } for (monitor_t *m = mon_head; m != NULL; m = m->next) add_desktop(m, NULL); ewmh_update_number_of_desktops(); ewmh_update_desktop_names(); rule_head = make_rule(); frozen_pointer = make_pointer_state(); get_pointer_position(&pointer_position); split_mode = MODE_AUTOMATIC; }