📄 gtkmain.c
字号:
} if (quit_functions) { GList *reinvoke_list = NULL; GtkQuitFunction *quitf; while (quit_functions) { quitf = quit_functions->data; tmp_list = quit_functions; quit_functions = g_list_remove_link (quit_functions, quit_functions); g_list_free_1 (tmp_list); if ((quitf->main_level && quitf->main_level != gtk_main_loop_level) || gtk_quit_invoke_function (quitf)) { reinvoke_list = g_list_prepend (reinvoke_list, quitf); } else { gtk_quit_destroy (quitf); } } if (reinvoke_list) { GList *work; work = g_list_last (reinvoke_list); if (quit_functions) quit_functions->prev = work; work->next = quit_functions; quit_functions = work; } gdk_flush (); } main_loops = g_slist_remove (main_loops, loop); g_main_destroy (loop); gtk_main_loop_level--;}guintgtk_main_level (void){ return gtk_main_loop_level;}voidgtk_main_quit (void){ g_return_if_fail (main_loops != NULL); g_main_quit (main_loops->data);}gintgtk_events_pending (void){ gboolean result; GDK_THREADS_LEAVE (); result = g_main_pending(); GDK_THREADS_ENTER (); return result;}gint gtk_main_iteration (void){ GDK_THREADS_LEAVE (); g_main_iteration (TRUE); GDK_THREADS_ENTER (); if (main_loops) return !g_main_is_running (main_loops->data); else return TRUE;}gint gtk_main_iteration_do (gboolean blocking){ GDK_THREADS_LEAVE (); g_main_iteration (blocking); GDK_THREADS_ENTER (); if (main_loops) return !g_main_is_running (main_loops->data); else return TRUE;}void gtk_main_do_event (GdkEvent *event){ GtkWidget *event_widget; GtkWidget *grab_widget; GdkEvent *next_event; GList *tmp_list; /* If there are any events pending then get the next one. */ next_event = gdk_event_peek (); /* Try to compress enter/leave notify events. These event * pairs occur when the mouse is dragged quickly across * a window with many buttons (or through a menu). Instead * of highlighting and de-highlighting each widget that * is crossed it is better to simply de-highlight the widget * which contained the mouse initially and highlight the * widget which ends up containing the mouse. */ if (next_event) if (((event->type == GDK_ENTER_NOTIFY) || (event->type == GDK_LEAVE_NOTIFY)) && ((next_event->type == GDK_ENTER_NOTIFY) || (next_event->type == GDK_LEAVE_NOTIFY)) && (next_event->type != event->type) && (next_event->any.window == event->any.window)) { /* Throw both the peeked copy and the queued copy away */ gdk_event_free (next_event); next_event = gdk_event_get (); gdk_event_free (next_event); return; } if (next_event) gdk_event_free (next_event); /* Find the widget which got the event. We store the widget * in the user_data field of GdkWindow's. * Ignore the event if we don't have a widget for it, except * for GDK_PROPERTY_NOTIFY events which are handled specialy. * Though this happens rarely, bogus events can occour * for e.g. destroyed GdkWindows. */ event_widget = gtk_get_event_widget (event); if (!event_widget) { /* To handle selection INCR transactions, we select * PropertyNotify events on the requestor window and create * a corresponding (fake) GdkWindow so that events get * here. There won't be a widget though, so we have to handle * them specially */ if (event->type == GDK_PROPERTY_NOTIFY) gtk_selection_incr_event (event->any.window, &event->property); return; } /* Push the event onto a stack of current events for * gtk_current_event_get(). */ current_events = g_list_prepend (current_events, event); /* If there is a grab in effect... */ if (grabs) { grab_widget = grabs->data; /* If the grab widget is an ancestor of the event widget * then we send the event to the original event widget. * This is the key to implementing modality. */ if (GTK_WIDGET_IS_SENSITIVE (event_widget) && gtk_widget_is_ancestor (event_widget, grab_widget)) grab_widget = event_widget; } else { grab_widget = event_widget; } /* Not all events get sent to the grabbing widget. * The delete, destroy, expose, focus change and resize * events still get sent to the event widget because * 1) these events have no meaning for the grabbing widget * and 2) redirecting these events to the grabbing widget * could cause the display to be messed up. * * Drag events are also not redirected, since it isn't * clear what the semantics of that would be. */ switch (event->type) { case GDK_NOTHING: break; case GDK_DELETE: gtk_widget_ref (event_widget); if (!gtk_widget_event (event_widget, event) && !GTK_OBJECT_DESTROYED (event_widget)) gtk_widget_destroy (event_widget); gtk_widget_unref (event_widget); break; case GDK_DESTROY: /* Unexpected GDK_DESTROY from the outside, ignore for * child windows, handle like a GDK_DELETE for toplevels */ if (!event_widget->parent) { gtk_widget_ref (event_widget); if (!gtk_widget_event (event_widget, event) && !GTK_OBJECT_DESTROYED (event_widget)) gtk_widget_destroy (event_widget); gtk_widget_unref (event_widget); } break; case GDK_PROPERTY_NOTIFY: case GDK_EXPOSE: case GDK_NO_EXPOSE: case GDK_FOCUS_CHANGE: case GDK_CONFIGURE: case GDK_MAP: case GDK_UNMAP: case GDK_SELECTION_CLEAR: case GDK_SELECTION_REQUEST: case GDK_SELECTION_NOTIFY: case GDK_CLIENT_EVENT: case GDK_VISIBILITY_NOTIFY: gtk_widget_event (event_widget, event); break; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: /* We treat button 4-5 specially, assume we have * a MS-style scrollwheel mouse, and try to find * a plausible widget to scroll. We also trap * button 4-5 double and triple clicks here, since * they will be generated if the user scrolls quickly. */ if ((grab_widget == event_widget) && (event->button.button == 4 || event->button.button == 5)) { GtkWidget *range = NULL; GtkWidget *scrollwin; if (GTK_IS_RANGE (event_widget)) range = event_widget; else { scrollwin = gtk_widget_get_ancestor (event_widget, GTK_TYPE_SCROLLED_WINDOW); if (scrollwin) range = GTK_SCROLLED_WINDOW (scrollwin)->vscrollbar; } if (range && GTK_WIDGET_VISIBLE (range)) { if (event->type == GDK_BUTTON_PRESS) { GtkAdjustment *adj = GTK_RANGE (range)->adjustment; gfloat new_value = adj->value + ((event->button.button == 4) ? -adj->page_increment / 2: adj->page_increment / 2); new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); gtk_adjustment_set_value (adj, new_value); } break; } } gtk_propagate_event (grab_widget, event); break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: if (key_snoopers) { if (gtk_invoke_key_snoopers (grab_widget, event)) break; } /* else fall through */ case GDK_MOTION_NOTIFY: case GDK_BUTTON_RELEASE: case GDK_PROXIMITY_IN: case GDK_PROXIMITY_OUT: gtk_propagate_event (grab_widget, event); break; case GDK_ENTER_NOTIFY: if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) { gtk_widget_event (grab_widget, event); if (event_widget == grab_widget) GTK_PRIVATE_SET_FLAG (event_widget, GTK_LEAVE_PENDING); } break; case GDK_LEAVE_NOTIFY: if (GTK_WIDGET_LEAVE_PENDING (event_widget)) { GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING); gtk_widget_event (event_widget, event); } else if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) gtk_widget_event (grab_widget, event); break; case GDK_DRAG_STATUS: case GDK_DROP_FINISHED: gtk_drag_source_handle_event (event_widget, event); break; case GDK_DRAG_ENTER: case GDK_DRAG_LEAVE: case GDK_DRAG_MOTION: case GDK_DROP_START: gtk_drag_dest_handle_event (event_widget, event); break; } tmp_list = current_events; current_events = g_list_remove_link (current_events, tmp_list); g_list_free_1 (tmp_list);}gintgtk_true (void){ return TRUE;}gintgtk_false (void){ return FALSE;}voidgtk_grab_add (GtkWidget *widget){ g_return_if_fail (widget != NULL); if (!GTK_WIDGET_HAS_GRAB (widget)) { GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_GRAB); grabs = g_slist_prepend (grabs, widget); gtk_widget_ref (widget); }}GtkWidget*gtk_grab_get_current (void){ if (grabs) return GTK_WIDGET (grabs->data); return NULL;}voidgtk_grab_remove (GtkWidget *widget){ g_return_if_fail (widget != NULL); if (GTK_WIDGET_HAS_GRAB (widget)) { GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_GRAB); grabs = g_slist_remove (grabs, widget); gtk_widget_unref (widget); }}voidgtk_init_add (GtkFunction function, gpointer data){ GtkInitFunction *init; init = g_new (GtkInitFunction, 1); init->function = function; init->data = data; init_functions = g_list_prepend (init_functions, init);}guintgtk_key_snooper_install (GtkKeySnoopFunc snooper, gpointer func_data){ GtkKeySnooperData *data; static guint snooper_id = 1; g_return_val_if_fail (snooper != NULL, 0); data = g_new (GtkKeySnooperData, 1); data->func = snooper; data->func_data = func_data; data->id = snooper_id++; key_snoopers = g_slist_prepend (key_snoopers, data); return data->id;}voidgtk_key_snooper_remove (guint snooper_id){ GtkKeySnooperData *data = NULL; GSList *slist; slist = key_snoopers; while (slist) { data = slist->data; if (data->id == snooper_id) break; slist = slist->next; data = NULL; } if (data) key_snoopers = g_slist_remove (key_snoopers, data);}static gintgtk_invoke_key_snoopers (GtkWidget *grab_widget, GdkEvent *event){ GSList *slist; gint return_val = FALSE; slist = key_snoopers; while (slist && !return_val) { GtkKeySnooperData *data; data = slist->data; slist = slist->next; return_val = (*data->func) (grab_widget, (GdkEventKey*) event, data->func_data); } return return_val;}guintgtk_quit_add_full (guint main_level, GtkFunction function, GtkCallbackMarshal marshal, gpointer data, GtkDestroyNotify destroy){ static guint quit_id = 1; GtkQuitFunction *quitf; g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0); if (!quit_mem_chunk) quit_mem_chunk = g_mem_chunk_new ("quit mem chunk", sizeof (GtkQuitFunction), 512, G_ALLOC_AND_FREE); quitf = g_chunk_new (GtkQuitFunction, quit_mem_chunk); quitf->id = quit_id++; quitf->main_level = main_level; quitf->function = function; quitf->marshal = marshal; quitf->data = data; quitf->destroy = destroy; quit_functions = g_list_prepend (quit_functions, quitf); return quitf->id;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -