/* This is a _horrible_ hack to have this here. This needs to be added to the * GTK+ menuing code in some manner. */ static void drag_end_menu_cb (GtkWidget *widget, GdkDragContext *context) { GtkWidget *xgrab_shell; GtkWidget *parent; /* Find the last viewable ancestor, and make an X grab on it */ parent = gtk_widget_get_parent (widget); xgrab_shell = NULL; /* FIXME: workaround for a possible gtk+ bug * See bugs #92085(gtk+) and #91184(panel) for details. */ g_object_set (widget, "has-tooltip", TRUE, NULL); while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!gtk_widget_get_mapped (tmp)) { viewable = FALSE; break; } tmp = gtk_widget_get_parent (tmp); } if (viewable) xgrab_shell = parent; #if GTK_CHECK_VERSION (3, 0, 0) parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent)); #else parent = GTK_MENU_SHELL (parent)->parent_menu_shell; #endif } #if GTK_CHECK_VERSION (3, 0, 0) if (xgrab_shell) #else if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell))) #endif { #if GTK_CHECK_VERSION (3, 0, 0) gboolean status; GdkDisplay *display; GdkDevice *pointer; GdkDevice *keyboard; #if GTK_CHECK_VERSION(3, 20, 0) GdkSeat *seat; #else GdkDeviceManager *device_manager; #endif #endif GdkWindow *window = gtk_widget_get_window (xgrab_shell); GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_ARROW); #if GTK_CHECK_VERSION (3, 0, 0) display = gdk_window_get_display (window); #if GTK_CHECK_VERSION(3, 20, 0) seat = gdk_display_get_default_seat (display); pointer = gdk_seat_get_pointer (seat); #else device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); #endif keyboard = gdk_device_get_associated_device (pointer); /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW or GDK_OWNERSHIP_APPLICATION Idem for the keyboard below */ status = gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, cursor, GDK_CURRENT_TIME); if (!status) { if (gdk_device_grab (keyboard, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS) { #else if ((gdk_pointer_grab (window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, cursor, GDK_CURRENT_TIME) == 0)) { if (gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME) == 0) { #endif /* FIXME fix for GTK3 */ #if !GTK_CHECK_VERSION (3, 0, 0) GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE; #endif } else { #if GTK_CHECK_VERSION (3, 0, 0) gdk_device_ungrab (pointer, GDK_CURRENT_TIME); } } g_object_unref (cursor); #else gdk_pointer_ungrab (GDK_CURRENT_TIME); } } gdk_cursor_unref (cursor); #endif } }
static gboolean gnc_reconcile_view_tooltip_cb (GNCQueryView *qview, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer *user_data) { GtkTreeModel* model; GtkTreeIter iter; // If the Description is longer than can be display, show it in a tooltip if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (qview), &x, &y, keyboard_mode, &model, NULL, &iter)) { GtkTreeViewColumn *col; GList *cols; gint col_pos, col_width; gchar* desc_text = NULL; /* Are we in keyboard tooltip mode, displays tooltip below/above treeview CTRL+F1 */ if (keyboard_mode == FALSE) { if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (qview), x, y, NULL, &col, NULL, NULL) == FALSE) return FALSE; } else gtk_tree_view_get_cursor (GTK_TREE_VIEW (qview), NULL, &col); cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (qview)); col_width = gtk_tree_view_column_get_width (col); col_pos = g_list_index (cols, col); g_list_free (cols); /* If column is not description, do not show tooltip */ if (col_pos != (REC_DESC - 1)) // allow for the pointer model column at 0 return FALSE; gtk_tree_model_get (model, &iter, REC_DESC, &desc_text, -1); if (desc_text) { PangoLayout* layout; gint text_width; gint root_x, root_y; gint cur_x, cur_y; layout = gtk_widget_create_pango_layout (GTK_WIDGET (qview), desc_text); pango_layout_get_pixel_size (layout, &text_width, NULL); g_object_unref (layout); /* If text_width + 10 <= column_width, do not show tooltip */ if ((text_width + 10) <= col_width) { g_free (desc_text); return FALSE; } if (keyboard_mode == FALSE) { #if GTK_CHECK_VERSION(3,20,0) GdkSeat *seat; #else GdkDeviceManager *device_manager; #endif GdkDevice *pointer; GtkWindow *tip_win = NULL; GdkWindow *parent_window; GList *win_list, *node; parent_window = gtk_widget_get_parent_window (GTK_WIDGET (qview)); #if GTK_CHECK_VERSION(3,20,0) seat = gdk_display_get_default_seat (gdk_window_get_display (parent_window)); pointer = gdk_seat_get_pointer (seat); #else device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent_window)); pointer = gdk_device_manager_get_client_pointer (device_manager); #endif gdk_window_get_device_position (parent_window, pointer, &cur_x, &cur_y, NULL); gdk_window_get_origin (parent_window, &root_x, &root_y); /* Get a list of toplevel windows */ win_list = gtk_window_list_toplevels (); /* Look for the gtk-tooltip window, we do this as gtk_widget_get_tooltip_window does not seem to work for the default tooltip window, custom yes */ for (node = win_list; node != NULL; node = node->next) { if (g_strcmp0 (gtk_widget_get_name (node->data), "gtk-tooltip") == 0) tip_win = node->data; } g_list_free (win_list); gtk_tooltip_set_text (tooltip, desc_text); if (GTK_IS_WINDOW (tip_win)) { #if GTK_CHECK_VERSION(3,22,0) GdkMonitor *mon; #else GdkScreen *screen; gint monitor_num; #endif GdkRectangle monitor; GtkRequisition requisition; gint x, y; gtk_widget_get_preferred_size (GTK_WIDGET (tip_win), &requisition, NULL); x = root_x + cur_x + 10; y = root_y + cur_y + 10; #if GTK_CHECK_VERSION(3,22,0) mon = gdk_display_get_monitor_at_point (gdk_display_get_default(), x, y); gdk_monitor_get_geometry (mon, &monitor); #else screen = gtk_widget_get_screen (GTK_WIDGET (qview)); monitor_num = gdk_screen_get_monitor_at_point (screen, x, y); gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); #endif if (x + requisition.width > monitor.x + monitor.width) x -= x - (monitor.x + monitor.width) + requisition.width; else if (x < monitor.x) x = monitor.x; if (y + requisition.height > monitor.y + monitor.height) y -= y - (monitor.y + monitor.height) + requisition.height; gtk_window_move (tip_win, x, y); } } gtk_tooltip_set_text (tooltip, desc_text); g_free (desc_text); return TRUE; } } return FALSE; }
static gint target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data) { BalloonEval *beval = (BalloonEval *)data; switch (event->type) { case GDK_ENTER_NOTIFY: pointer_event(beval, (int)event->crossing.x, (int)event->crossing.y, event->crossing.state); break; case GDK_MOTION_NOTIFY: if (event->motion.is_hint) { int x; int y; GdkModifierType state; /* * GDK_POINTER_MOTION_HINT_MASK is set, thus we cannot obtain * the coordinates from the GdkEventMotion struct directly. */ # if GTK_CHECK_VERSION(3,0,0) { GdkWindow * const win = gtk_widget_get_window(widget); GdkDisplay * const dpy = gdk_window_get_display(win); # if GTK_CHECK_VERSION(3,20,0) GdkSeat * const seat = gdk_display_get_default_seat(dpy); GdkDevice * const dev = gdk_seat_get_pointer(seat); # else GdkDeviceManager * const mngr = gdk_display_get_device_manager(dpy); GdkDevice * const dev = gdk_device_manager_get_client_pointer(mngr); # endif gdk_window_get_device_position(win, dev , &x, &y, &state); } # else gdk_window_get_pointer(widget->window, &x, &y, &state); # endif pointer_event(beval, x, y, (unsigned int)state); } else { pointer_event(beval, (int)event->motion.x, (int)event->motion.y, event->motion.state); } break; case GDK_LEAVE_NOTIFY: /* * Ignore LeaveNotify events that are not "normal". * Apparently we also get it when somebody else grabs focus. */ if (event->crossing.mode == GDK_CROSSING_NORMAL) cancelBalloon(beval); break; case GDK_BUTTON_PRESS: case GDK_SCROLL: cancelBalloon(beval); break; case GDK_KEY_PRESS: key_event(beval, event->key.keyval, TRUE); break; case GDK_KEY_RELEASE: key_event(beval, event->key.keyval, FALSE); break; default: break; } return FALSE; /* continue emission */ }
void panel_force_quit (GdkScreen *screen, guint time) { GdkGrabStatus status; GdkCursor *cross; GtkWidget *popup; GdkWindow *root; #if GTK_CHECK_VERSION (3, 0, 0) GdkDisplay *display; GdkDevice *pointer; GdkDevice *keyboard; GdkDeviceManager *device_manager; #endif popup = display_popup_window (screen); root = gdk_screen_get_root_window (screen); gdk_window_add_filter (root, (GdkFilterFunc) popup_filter, popup); cross = gdk_cursor_new (GDK_CROSS); #if GTK_CHECK_VERSION (3, 0, 0) display = gdk_window_get_display (root); device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); keyboard = gdk_device_get_associated_device (pointer); status = gdk_device_grab (pointer, root, GDK_OWNERSHIP_NONE, FALSE, GDK_BUTTON_PRESS_MASK, cross, time); g_object_unref (cross); status = gdk_device_grab (keyboard, root, GDK_OWNERSHIP_NONE, FALSE, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL, time); if (status != GDK_GRAB_SUCCESS) { g_warning ("Pointer grab failed\n"); remove_popup (popup); return; } #else status = gdk_pointer_grab (root, FALSE, GDK_BUTTON_PRESS_MASK, NULL, cross, time); gdk_cursor_unref (cross); if (status != GDK_GRAB_SUCCESS) { g_warning ("Pointer grab failed\n"); remove_popup (popup); return; } status = gdk_keyboard_grab (root, FALSE, time); if (status != GDK_GRAB_SUCCESS) { g_warning ("Keyboard grab failed\n"); remove_popup (popup); return; } #endif gdk_flush (); }
void *wxGetDisplay() { return GDK_DISPLAY_XDISPLAY(gdk_window_get_display(wxGetTopLevelGDK())); }
static void generate_key_event (GdkWindow *window, GdkEventType type, guint state, guint keyval, guint16 keycode, gboolean is_modifier, guint32 event_time) { GdkEvent *event; event = gdk_event_new (type); event->key.state = state; event->key.keyval = keyval; event->key.hardware_keycode = keycode + 8; event->key.is_modifier = is_modifier; event->key.time = event_time; set_key_event_string (&event->key); send_event (window, _gdk_mir_device_manager_get_keyboard (gdk_display_get_device_manager (gdk_window_get_display (window))), event); }
static cairo_surface_t * snapshot_widget (GtkWidget *widget, SnapshotMode mode) { cairo_surface_t *surface; cairo_pattern_t *bg; GMainLoop *loop; cairo_t *cr; g_assert (gtk_widget_get_realized (widget)); surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), CAIRO_CONTENT_COLOR, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget)); loop = g_main_loop_new (NULL, FALSE); /* We wait until the widget is drawn for the first time. * We can not wait for a GtkWidget::draw event, because that might not * happen if the window is fully obscured by windowed child widgets. * Alternatively, we could wait for an expose event on widget's window. * Both of these are rather hairy, not sure what's best. */ gdk_event_handler_set (check_for_draw, loop, NULL); g_main_loop_run (loop); cr = cairo_create (surface); switch (mode) { case SNAPSHOT_WINDOW: { GdkWindow *window = gtk_widget_get_window (widget); if (gdk_window_get_window_type (window) == GDK_WINDOW_TOPLEVEL || gdk_window_get_window_type (window) == GDK_WINDOW_FOREIGN) { /* give the WM/server some time to sync. They need it. * Also, do use popups instead of toplevls in your tests * whenever you can. */ gdk_display_sync (gdk_window_get_display (window)); g_timeout_add (500, quit_when_idle, loop); g_main_loop_run (loop); } gdk_cairo_set_source_window (cr, window, 0, 0); cairo_paint (cr); } break; case SNAPSHOT_DRAW: bg = gdk_window_get_background_pattern (gtk_widget_get_window (widget)); if (bg) { cairo_set_source (cr, bg); cairo_paint (cr); } gtk_widget_draw (widget, cr); break; default: g_assert_not_reached(); break; } cairo_destroy (cr); g_main_loop_unref (loop); gtk_widget_destroy (widget); return surface; }
bool wxPopupTransientWindow::Show( bool show ) { #ifdef __WXGTK__ if (!show) { #ifdef __WXGTK3__ GdkDisplay* display = gtk_widget_get_display(m_widget); #ifdef __WXGTK4__ gdk_seat_ungrab(gdk_display_get_default_seat(display)); #else wxGCC_WARNING_SUPPRESS(deprecated-declarations) GdkDeviceManager* manager = gdk_display_get_device_manager(display); GdkDevice* device = gdk_device_manager_get_client_pointer(manager); gdk_device_ungrab(device, unsigned(GDK_CURRENT_TIME)); wxGCC_WARNING_RESTORE() #endif #else gdk_pointer_ungrab( (guint32)GDK_CURRENT_TIME ); #endif gtk_grab_remove( m_widget ); } #endif #ifdef __WXX11__ if (!show) { XUngrabPointer( wxGlobalDisplay(), CurrentTime ); } #endif #if defined( __WXMSW__ ) || defined( __WXMAC__) if (!show && m_child && m_child->HasCapture()) { m_child->ReleaseMouse(); } #endif bool ret = wxPopupWindow::Show( show ); #ifdef __WXGTK__ if (show) { gtk_grab_add( m_widget ); GdkWindow* window = gtk_widget_get_window(m_widget); #ifdef __WXGTK4__ GdkDisplay* display = gdk_window_get_display(window); GdkSeat* seat = gdk_display_get_default_seat(display); gdk_seat_grab(seat, window, GDK_SEAT_CAPABILITY_POINTER, false, NULL, NULL, NULL, 0); #else const GdkEventMask mask = GdkEventMask( GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK); #ifdef __WXGTK3__ GdkDisplay* display = gdk_window_get_display(window); wxGCC_WARNING_SUPPRESS(deprecated-declarations) GdkDeviceManager* manager = gdk_display_get_device_manager(display); GdkDevice* device = gdk_device_manager_get_client_pointer(manager); gdk_device_grab(device, window, GDK_OWNERSHIP_NONE, true, mask, NULL, unsigned(GDK_CURRENT_TIME)); wxGCC_WARNING_RESTORE() #else gdk_pointer_grab( window, true, mask, NULL, NULL, (guint32)GDK_CURRENT_TIME ); #endif #endif // !__WXGTK4__ } #endif #ifdef __WXX11__ if (show) { Window xwindow = (Window) m_clientWindow; /* int res =*/ XGrabPointer(wxGlobalDisplay(), xwindow, True, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime ); } #endif #if defined( __WXMSW__ ) || defined( __WXMAC__) if (show && m_child) { // Assume that the mouse is outside the popup to begin with m_child->CaptureMouse(); } #endif return ret; }
static GdkPixbuf * screenshot_fallback_get_pixbuf (GdkRectangle *rectangle) { GdkWindow *root, *wm_window = NULL; GdkPixbuf *screenshot; GdkRectangle real_coords, screenshot_coords; Window wm; GtkBorder frame_offset = { 0, 0, 0, 0 }; GdkWindow *window; window = screenshot_fallback_find_current_window (); screenshot_fallback_get_window_rect_coords (window, screenshot_config->include_border, &real_coords, &screenshot_coords); wm = find_wm_window (window); if (wm != None) { GdkRectangle wm_real_coords; wm_window = gdk_x11_window_foreign_new_for_display (gdk_window_get_display (window), wm); screenshot_fallback_get_window_rect_coords (wm_window, FALSE, &wm_real_coords, NULL); frame_offset.left = (gdouble) (real_coords.x - wm_real_coords.x); frame_offset.top = (gdouble) (real_coords.y - wm_real_coords.y); frame_offset.right = (gdouble) (wm_real_coords.width - real_coords.width - frame_offset.left); frame_offset.bottom = (gdouble) (wm_real_coords.height - real_coords.height - frame_offset.top); } if (rectangle) { screenshot_coords.x = rectangle->x - screenshot_coords.x; screenshot_coords.y = rectangle->y - screenshot_coords.y; screenshot_coords.width = rectangle->width; screenshot_coords.height = rectangle->height; } root = gdk_get_default_root_window (); screenshot = gdk_pixbuf_get_from_window (root, screenshot_coords.x, screenshot_coords.y, screenshot_coords.width, screenshot_coords.height); if (!screenshot_config->take_window_shot && !screenshot_config->take_area_shot) mask_monitors (screenshot, root); #ifdef HAVE_X11_EXTENSIONS_SHAPE_H if (screenshot_config->include_border && (wm != None)) { XRectangle *rectangles; GdkPixbuf *tmp; int rectangle_count, rectangle_order, i; /* we must use XShape to avoid showing what's under the rounder corners * of the WM decoration. */ rectangles = XShapeGetRectangles (GDK_DISPLAY_XDISPLAY (gdk_display_get_default()), wm, ShapeBounding, &rectangle_count, &rectangle_order); if (rectangles && rectangle_count > 0) { gboolean has_alpha = gdk_pixbuf_get_has_alpha (screenshot); tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, screenshot_coords.width, screenshot_coords.height); gdk_pixbuf_fill (tmp, 0); for (i = 0; i < rectangle_count; i++) { gint rec_x, rec_y; gint rec_width, rec_height; gint y; /* If we're using invisible borders, the ShapeBounding might not * have the same size as the frame extents, as it would include the * areas for the invisible borders themselves. * In that case, trim every rectangle we get by the offset between the * WM window size and the frame extents. */ rec_x = rectangles[i].x; rec_y = rectangles[i].y; rec_width = rectangles[i].width - (frame_offset.left + frame_offset.right); rec_height = rectangles[i].height - (frame_offset.top + frame_offset.bottom); if (real_coords.x < 0) { rec_x += real_coords.x; rec_x = MAX(rec_x, 0); rec_width += real_coords.x; } if (real_coords.y < 0) { rec_y += real_coords.y; rec_y = MAX(rec_y, 0); rec_height += real_coords.y; } if (screenshot_coords.x + rec_x + rec_width > gdk_screen_width ()) rec_width = gdk_screen_width () - screenshot_coords.x - rec_x; if (screenshot_coords.y + rec_y + rec_height > gdk_screen_height ()) rec_height = gdk_screen_height () - screenshot_coords.y - rec_y; for (y = rec_y; y < rec_y + rec_height; y++) { guchar *src_pixels, *dest_pixels; gint x; src_pixels = gdk_pixbuf_get_pixels (screenshot) + y * gdk_pixbuf_get_rowstride(screenshot) + rec_x * (has_alpha ? 4 : 3); dest_pixels = gdk_pixbuf_get_pixels (tmp) + y * gdk_pixbuf_get_rowstride (tmp) + rec_x * 4; for (x = 0; x < rec_width; x++) { *dest_pixels++ = *src_pixels++; *dest_pixels++ = *src_pixels++; *dest_pixels++ = *src_pixels++; if (has_alpha) *dest_pixels++ = *src_pixels++; else *dest_pixels++ = 255; } } } g_object_unref (screenshot); screenshot = tmp; XFree (rectangles); } } #endif /* HAVE_X11_EXTENSIONS_SHAPE_H */ /* if we have a selected area, there were by definition no cursor in the * screenshot */ if (screenshot_config->include_pointer && !rectangle) { GdkCursor *cursor; GdkPixbuf *cursor_pixbuf; cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_LEFT_PTR); cursor_pixbuf = gdk_cursor_get_image (cursor); if (cursor_pixbuf != NULL) { GdkDeviceManager *manager; GdkDevice *device; GdkRectangle rect; gint cx, cy, xhot, yhot; manager = gdk_display_get_device_manager (gdk_display_get_default ()); device = gdk_device_manager_get_client_pointer (manager); if (wm_window != NULL) gdk_window_get_device_position (wm_window, device, &cx, &cy, NULL); else gdk_window_get_device_position (window, device, &cx, &cy, NULL); sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "x_hot"), "%d", &xhot); sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "y_hot"), "%d", &yhot); /* in rect we have the cursor window coordinates */ rect.x = cx + real_coords.x; rect.y = cy + real_coords.y; rect.width = gdk_pixbuf_get_width (cursor_pixbuf); rect.height = gdk_pixbuf_get_height (cursor_pixbuf); /* see if the pointer is inside the window */ if (gdk_rectangle_intersect (&real_coords, &rect, &rect)) { gint cursor_x, cursor_y; cursor_x = cx - xhot - frame_offset.left; cursor_y = cy - yhot - frame_offset.top; gdk_pixbuf_composite (cursor_pixbuf, screenshot, cursor_x, cursor_y, rect.width, rect.height, cursor_x, cursor_y, 1.0, 1.0, GDK_INTERP_BILINEAR, 255); } g_object_unref (cursor_pixbuf); g_object_unref (cursor); } } screenshot_fallback_fire_flash (window, rectangle); return screenshot; }
void _gdk_x11_window_change_property (GdkWindow *window, GdkAtom property, GdkAtom type, gint format, GdkPropMode mode, const guchar *data, gint nelements) { GdkDisplay *display; Window xwindow; Atom xproperty; Atom xtype; g_return_if_fail (!window || GDK_WINDOW_IS_X11 (window)); if (!window) { GdkScreen *screen; screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n")); } else if (!GDK_WINDOW_IS_X11 (window)) return; if (GDK_WINDOW_DESTROYED (window)) return; gdk_window_ensure_native (window); display = gdk_window_get_display (window); xproperty = gdk_x11_atom_to_xatom_for_display (display, property); xtype = gdk_x11_atom_to_xatom_for_display (display, type); xwindow = GDK_WINDOW_XID (window); if (xtype == XA_ATOM || xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of GdkAtom, we need to convert it * to an array of X Atoms */ gint i; GdkAtom *atoms = (GdkAtom*) data; Atom *xatoms; xatoms = g_new (Atom, nelements); for (i = 0; i < nelements; i++) xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]); XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, xtype, format, mode, (guchar *)xatoms, nelements); g_free (xatoms); } else XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, xtype, format, mode, (guchar *)data, nelements); }
static gboolean panel_background_prepare (PanelBackground *background) { PanelBackgroundType effective_type; GtkWidget *widget = NULL; if (!background->transformed) return FALSE; effective_type = panel_background_effective_type (background); switch (effective_type) { case PANEL_BACK_NONE: if (background->default_pattern) { /* the theme background-image pattern must be scaled by * the width & height of the panel so that when the * backing region is cleared * (gdk_window_clear_backing_region), the correctly * scaled pattern is used */ cairo_matrix_t m; cairo_surface_t *surface; double width, height; surface = NULL; width = 1.0; height = 1.0; cairo_pattern_get_surface(background->default_pattern, &surface); /* catch invalid images (e.g. -gtk-gradient) before scaling and rendering */ if (surface != NULL ){ cairo_surface_reference(surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); cairo_matrix_init_translate (&m, 0, 0); cairo_matrix_scale (&m, width / background->region.width, height / background->region.height); cairo_pattern_set_matrix (background->default_pattern, &m); gdk_window_set_background_pattern (background->window, background->default_pattern); } else { g_warning ("%s", "unsupported value of 'background-image' in GTK+ theme (such as '-gtk-gradient')"); /* use any background color that has been set if image is invalid */ gdk_window_set_background_rgba ( background->window, &background->default_color); } cairo_surface_destroy(surface); } else gdk_window_set_background_rgba ( background->window, &background->default_color); break; case PANEL_BACK_COLOR: if (background->has_alpha && !gdk_window_check_composited_wm(background->window)) set_pixbuf_background (background); else { gdk_window_set_background_rgba (background->window, &background->color); } break; case PANEL_BACK_IMAGE: set_pixbuf_background (background); break; default: g_assert_not_reached (); break; } /* Panel applets may use the panel's background pixmap to * decide how to draw themselves. Therefore, we need to * make sure that all drawing has been completed before * the applet looks at the pixmap. */ gdk_display_sync (gdk_window_get_display (background->window)); gdk_window_get_user_data (GDK_WINDOW (background->window), (gpointer) &widget); if (GTK_IS_WIDGET (widget)) { panel_background_apply_css (background, gtk_widget_get_toplevel(widget)); gtk_widget_set_app_paintable(widget,TRUE); gtk_widget_queue_draw (widget); } background->notify_changed (background, background->user_data); return TRUE; }
gboolean _gdk_x11_window_get_property (GdkWindow *window, GdkAtom property, GdkAtom type, gulong offset, gulong length, gint pdelete, GdkAtom *actual_property_type, gint *actual_format_type, gint *actual_length, guchar **data) { GdkDisplay *display; Atom ret_prop_type; gint ret_format; gulong ret_nitems; gulong ret_bytes_after; gulong get_length; gulong ret_length; guchar *ret_data; Atom xproperty; Atom xtype; int res; g_return_val_if_fail (!window || GDK_WINDOW_IS_X11 (window), FALSE); if (!window) { GdkScreen *screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n")); } else if (!GDK_WINDOW_IS_X11 (window)) return FALSE; if (GDK_WINDOW_DESTROYED (window)) return FALSE; display = gdk_window_get_display (window); xproperty = gdk_x11_atom_to_xatom_for_display (display, property); if (type == GDK_NONE) xtype = AnyPropertyType; else xtype = gdk_x11_atom_to_xatom_for_display (display, type); ret_data = NULL; /* * Round up length to next 4 byte value. Some code is in the (bad?) * habit of passing G_MAXLONG as the length argument, causing an * overflow to negative on the add. In this case, we clamp the * value to G_MAXLONG. */ get_length = length + 3; if (get_length > G_MAXLONG) get_length = G_MAXLONG; /* To fail, either the user passed 0 or G_MAXULONG */ get_length = get_length / 4; if (get_length == 0) { g_warning ("gdk_propery-get(): invalid length 0"); return FALSE; } res = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), xproperty, offset, get_length, pdelete, xtype, &ret_prop_type, &ret_format, &ret_nitems, &ret_bytes_after, &ret_data); if (res != Success || (ret_prop_type == None && ret_format == 0)) { return FALSE; } if (actual_property_type) *actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type); if (actual_format_type) *actual_format_type = ret_format; if ((xtype != AnyPropertyType) && (ret_prop_type != xtype)) { XFree (ret_data); g_warning ("Couldn't match property type %s to %s\n", gdk_x11_get_xatom_name_for_display (display, ret_prop_type), gdk_x11_get_xatom_name_for_display (display, xtype)); return FALSE; } /* FIXME: ignoring bytes_after could have very bad effects */ if (data) { if (ret_prop_type == XA_ATOM || ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of X atom, we need to convert it * to an array of GDK Atoms */ gint i; GdkAtom *ret_atoms = g_new (GdkAtom, ret_nitems); Atom *xatoms = (Atom *)ret_data; *data = (guchar *)ret_atoms; for (i = 0; i < ret_nitems; i++) ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]); if (actual_length) *actual_length = ret_nitems * sizeof (GdkAtom); } else { switch (ret_format) { case 8: ret_length = ret_nitems; break; case 16: ret_length = sizeof(short) * ret_nitems; break; case 32: ret_length = sizeof(long) * ret_nitems; break; default: g_warning ("unknown property return format: %d", ret_format); XFree (ret_data); return FALSE; } *data = g_new (guchar, ret_length); memcpy (*data, ret_data, ret_length); if (actual_length) *actual_length = ret_length; } } XFree (ret_data); return TRUE; }
struct wl_data_source * gdk_wayland_selection_get_data_source (GdkWindow *owner, GdkAtom selection) { GdkDisplay *display = gdk_window_get_display (owner); GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); gpointer source = NULL; GdkWaylandDisplay *display_wayland; if (selection == atoms[ATOM_DND]) { if (wayland_selection->dnd_source && (!owner || owner == wayland_selection->dnd_owner)) return wayland_selection->dnd_source; } else if (selection == atoms[ATOM_PRIMARY]) { if (wayland_selection->primary_source && (!owner || owner == wayland_selection->primary_owner)) return (gpointer) wayland_selection->primary_source; if (wayland_selection->primary_source) { gtk_primary_selection_source_destroy (wayland_selection->primary_source); wayland_selection->primary_source = NULL; } } else if (selection == atoms[ATOM_CLIPBOARD]) { if (wayland_selection->clipboard_source && (!owner || owner == wayland_selection->clipboard_owner)) return wayland_selection->clipboard_source; if (wayland_selection->clipboard_source) { wl_data_source_destroy (wayland_selection->clipboard_source); wayland_selection->clipboard_source = NULL; } } else return NULL; if (!owner) return NULL; display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (owner)); if (selection == atoms[ATOM_PRIMARY]) { if (display_wayland->primary_selection_manager) { source = gtk_primary_selection_device_manager_create_source (display_wayland->primary_selection_manager); gtk_primary_selection_source_add_listener (source, &primary_source_listener, wayland_selection); } } else { source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager); wl_data_source_add_listener (source, &data_source_listener, wayland_selection); } if (selection == atoms[ATOM_DND]) wayland_selection->dnd_source = source; else if (selection == atoms[ATOM_PRIMARY]) wayland_selection->primary_source = source; else if (selection == atoms[ATOM_CLIPBOARD]) wayland_selection->clipboard_source = source; return source; }
static void hd_home_plugin_item_realize (GtkWidget *widget) { HDHomePluginItemPrivate *priv = HD_HOME_PLUGIN_ITEM (widget)->priv; GdkDisplay *display; Atom atom, wm_type; gchar *applet_id; GdkRGBA transparent = {0.0, 0.0, 0.0, 0.0}; GdkWindow *window; GTK_WIDGET_CLASS (hd_home_plugin_item_parent_class)->realize (widget); window = gtk_widget_get_window (widget); /* No border as decoration */ gdk_window_set_decorations (window, 0); /* Set the _NET_WM_WINDOW_TYPE property to _HILDON_WM_WINDOW_TYPE_HOME_APPLET */ display = gdk_window_get_display (window); atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"); wm_type = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_WM_WINDOW_TYPE_HOME_APPLET"); XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_type, 1); applet_id = hd_home_plugin_item_get_applet_id (HD_HOME_PLUGIN_ITEM (widget)); XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_APPLET_ID"), gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, PropModeReplace, (guchar *) applet_id, strlen (applet_id)); g_free (applet_id); /* Set or remove settings property */ if (priv->settings) XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_APPLET_SETTINGS"), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &(priv->settings), 1); else XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_APPLET_SETTINGS")); /* Set display on all views property */ if (priv->display_on_all_views) XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_APPLET_DISPLAY_ON_ALL_VIEWS"), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &(priv->display_on_all_views), 1); else XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_APPLET_DISPLAY_ON_ALL_VIEWS")); /* Install client message filter */ if (show_settings_atom == GDK_NONE) show_settings_atom = gdk_atom_intern_static_string ("_HILDON_APPLET_SHOW_SETTINGS"); gdk_window_add_filter (window, hd_home_plugin_item_event_filter, widget); /* Set background to transparent */ gdk_window_set_background_rgba (window, &transparent); }
void _gtk_tooltip_handle_event (GdkEvent *event) { gint x, y; gboolean return_value = FALSE; GtkWidget *has_tooltip_widget = NULL; GdkDisplay *display; GtkTooltip *current_tooltip; if (!tooltips_enabled (event)) return; /* Returns coordinates relative to has_tooltip_widget's allocation. */ has_tooltip_widget = find_topmost_widget_coords_from_event (event, &x, &y); display = gdk_window_get_display (event->any.window); current_tooltip = g_object_get_data (G_OBJECT (display), "gdk-display-current-tooltip"); if (current_tooltip) { gtk_tooltip_set_last_window (current_tooltip, event->any.window); } if (current_tooltip && current_tooltip->keyboard_mode_enabled) { has_tooltip_widget = current_tooltip->keyboard_widget; if (!has_tooltip_widget) return; return_value = gtk_tooltip_run_requery (&has_tooltip_widget, current_tooltip, &x, &y); if (!return_value) gtk_tooltip_hide_tooltip (current_tooltip); else gtk_tooltip_start_delay (display); return; } #ifdef DEBUG_TOOLTIP if (has_tooltip_widget) g_print ("%p (%s) at (%d, %d) %dx%d pointer: (%d, %d)\n", has_tooltip_widget, gtk_widget_get_name (has_tooltip_widget), has_tooltip_widget->allocation.x, has_tooltip_widget->allocation.y, has_tooltip_widget->allocation.width, has_tooltip_widget->allocation.height, x, y); #endif /* DEBUG_TOOLTIP */ /* Always poll for a next motion event */ gdk_event_request_motions (&event->motion); /* Hide the tooltip when there's no new tooltip widget */ if (!has_tooltip_widget) { if (current_tooltip) gtk_tooltip_hide_tooltip (current_tooltip); return; } switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_KEY_PRESS: case GDK_DRAG_ENTER: case GDK_GRAB_BROKEN: case GDK_SCROLL: gtk_tooltip_hide_tooltip (current_tooltip); break; case GDK_MOTION_NOTIFY: case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: if (current_tooltip) { gboolean tip_area_set; GdkRectangle tip_area; gboolean hide_tooltip; tip_area_set = current_tooltip->tip_area_set; tip_area = current_tooltip->tip_area; return_value = gtk_tooltip_run_requery (&has_tooltip_widget, current_tooltip, &x, &y); /* Requested to be hidden? */ hide_tooltip = !return_value; /* Leave notify should override the query function */ hide_tooltip = (event->type == GDK_LEAVE_NOTIFY); /* Is the pointer above another widget now? */ if (GTK_TOOLTIP_VISIBLE (current_tooltip)) hide_tooltip |= has_tooltip_widget != current_tooltip->tooltip_widget; /* Did the pointer move out of the previous "context area"? */ if (tip_area_set) hide_tooltip |= (x <= tip_area.x || x >= tip_area.x + tip_area.width || y <= tip_area.y || y >= tip_area.y + tip_area.height); if (hide_tooltip) gtk_tooltip_hide_tooltip (current_tooltip); else gtk_tooltip_start_delay (display); } else { /* Need a new tooltip for this display */ current_tooltip = g_object_new (GTK_TYPE_TOOLTIP, NULL); g_object_set_data_full (G_OBJECT (display), "gdk-display-current-tooltip", current_tooltip, g_object_unref); g_signal_connect (display, "closed", G_CALLBACK (gtk_tooltip_display_closed), current_tooltip); gtk_tooltip_set_last_window (current_tooltip, event->any.window); gtk_tooltip_start_delay (display); } break; default: break; } }
static gboolean find_eglconfig_for_window (GdkWindow *window, EGLConfig *egl_config_out, GError **error) { GdkDisplay *display = gdk_window_get_display (window); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); GdkVisual *visual = gdk_window_get_visual (window); EGLint attrs[MAX_EGL_ATTRS]; EGLint count; EGLConfig *configs; gboolean use_rgba; int i = 0; attrs[i++] = EGL_SURFACE_TYPE; attrs[i++] = EGL_WINDOW_BIT; attrs[i++] = EGL_COLOR_BUFFER_TYPE; attrs[i++] = EGL_RGB_BUFFER; attrs[i++] = EGL_RED_SIZE; attrs[i++] = 1; attrs[i++] = EGL_GREEN_SIZE; attrs[i++] = 1; attrs[i++] = EGL_BLUE_SIZE; attrs[i++] = 1; use_rgba = (visual == gdk_screen_get_rgba_visual (gdk_display_get_default_screen (display))); if (use_rgba) { attrs[i++] = EGL_ALPHA_SIZE; attrs[i++] = 1; } else { attrs[i++] = EGL_ALPHA_SIZE; attrs[i++] = 0; } attrs[i++] = EGL_NONE; g_assert (i < MAX_EGL_ATTRS); if (!eglChooseConfig (display_wayland->egl_display, attrs, NULL, 0, &count) || count < 1) { g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_UNSUPPORTED_FORMAT, _("No available configurations for the given pixel format")); return FALSE; } configs = g_new (EGLConfig, count); if (!eglChooseConfig (display_wayland->egl_display, attrs, configs, count, &count) || count < 1) { g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_UNSUPPORTED_FORMAT, _("No available configurations for the given pixel format")); return FALSE; } /* Pick first valid configuration i guess? */ if (egl_config_out != NULL) *egl_config_out = configs[0]; g_free (configs); return TRUE; }
bool ev_UnixKeyboard::keyPressEvent(AV_View* pView, GdkEventKey* e) { EV_EditBits state = 0; EV_EditEventMapperResult result; EV_EditMethod * pEM; UT_uint32 charData = e->keyval; if (e->state & GDK_SHIFT_MASK) state |= EV_EMS_SHIFT; if (e->state & GDK_CONTROL_MASK) { state |= EV_EMS_CONTROL; // Gdk does us the favour of working out a translated keyvalue for us, // but with the Ctrl keys, we do not want that -- see bug 9545 Display * display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(e->window)); KeySym sym = XKeycodeToKeysym(display, e->hardware_keycode, e->state & GDK_SHIFT_MASK ? 1 : 0); xxx_UT_DEBUGMSG(("ev_UnixKeyboard::keyPressEvent: keyval %d, hardware_keycode %d\n" " sym: 0x%x\n", e->keyval, e->hardware_keycode, sym)); charData = sym; } if (e->state & (s_alt_mask)) state |= EV_EMS_ALT; if (s_isVirtualKeyCode(charData)) { EV_EditBits nvk = s_mapVirtualKeyCodeToNVK(charData); switch (nvk) { case EV_NVK__IGNORE__: return false; default: result = m_pEEM->Keystroke(static_cast<UT_uint32>(EV_EKP_PRESS|state|nvk),&pEM); switch (result) { case EV_EEMR_BOGUS_START: // If it is a bogus key and we don't have a sequence in // progress, we should let the system handle it // (this lets things like ALT-F4 work). return false; case EV_EEMR_BOGUS_CONT: // If it is a bogus key but in the middle of a sequence, // we should silently eat it (this is to prevent things // like Control-X ALT-F4 from killing us -- if they want // to kill us, fine, but they shouldn't be in the middle // of a sequence). return true; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM,0,0); // no char data to offer return true; case EV_EEMR_INCOMPLETE: return true; default: UT_ASSERT(0); return true; } } } else { // TODO: is this necessary? charData = gdk_keyval_to_unicode (charData); UT_UTF8String utf8 (static_cast<const UT_UCS4Char *>(&charData), 1); return charDataEvent (pView, state, utf8.utf8_str(), utf8.byteLength()); } return false; }
void gdk_wayland_window_invalidate_for_new_frame (GdkWindow *window, cairo_region_t *update_area) { cairo_rectangle_int_t window_rect; GdkDisplay *display = gdk_window_get_display (window); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); GdkWaylandGLContext *context_wayland; int buffer_age; gboolean invalidate_all; EGLSurface egl_surface; /* Minimal update is ok if we're not drawing with gl */ if (window->gl_paint_context == NULL) return; context_wayland = GDK_WAYLAND_GL_CONTEXT (window->gl_paint_context); buffer_age = 0; egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config); if (display_wayland->have_egl_buffer_age) { gdk_gl_context_make_current (window->gl_paint_context); eglQuerySurface (display_wayland->egl_display, egl_surface, EGL_BUFFER_AGE_EXT, &buffer_age); } invalidate_all = FALSE; if (buffer_age == 0 || buffer_age >= 4) invalidate_all = TRUE; else { if (buffer_age >= 2) { if (window->old_updated_area[0]) cairo_region_union (update_area, window->old_updated_area[0]); else invalidate_all = TRUE; } if (buffer_age >= 3) { if (window->old_updated_area[1]) cairo_region_union (update_area, window->old_updated_area[1]); else invalidate_all = TRUE; } } if (invalidate_all) { window_rect.x = 0; window_rect.y = 0; window_rect.width = gdk_window_get_width (window); window_rect.height = gdk_window_get_height (window); /* If nothing else is known, repaint everything so that the back * buffer is fully up-to-date for the swapbuffer */ cairo_region_union_rectangle (update_area, &window_rect); } }
static GdkDevice * get_pointer (GdkWindow *window) { return gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (gdk_window_get_display (window))); }
static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data; dt_iop_lowlight_params_t *p = (dt_iop_lowlight_params_t *)self->params; const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; if(!c->dragging) c->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; c->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; if(c->dragging) { *p = c->drag_params; if(c->x_move >= 0) { const float mx = CLAMP(event->x - inset, 0, width) / (float)width; if(c->x_move > 0 && c->x_move < DT_IOP_LOWLIGHT_BANDS - 1) { const float minx = p->transition_x[c->x_move - 1] + 0.001f; const float maxx = p->transition_x[c->x_move + 1] - 0.001f; p->transition_x[c->x_move] = fminf(maxx, fmaxf(minx, mx)); } } else { dt_iop_lowlight_get_params(p, c->mouse_x, c->mouse_y + c->mouse_pick, c->mouse_radius); } dt_dev_add_history_item(darktable.develop, self, TRUE); } else if(event->y > height) { c->x_move = 0; float dist = fabs(p->transition_x[0] - c->mouse_x); for(int k = 1; k < DT_IOP_LOWLIGHT_BANDS; k++) { float d2 = fabs(p->transition_x[k] - c->mouse_x); if(d2 < dist) { c->x_move = k; dist = d2; } } } else { c->x_move = -1; } gtk_widget_queue_draw(widget); gint x, y; #if GTK_CHECK_VERSION(3, 20, 0) gdk_window_get_device_position(event->window, gdk_seat_get_pointer(gdk_display_get_default_seat( gdk_window_get_display(event->window))), &x, &y, 0); #else gdk_window_get_device_position(event->window, gdk_device_manager_get_client_pointer( gdk_display_get_device_manager(gdk_window_get_display(event->window))), &x, &y, NULL); #endif return TRUE; }
bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); #ifdef GDK_WINDOWING_X11 bool deferShow = show && !m_isShown && m_deferShow; if (deferShow) { deferShow = m_deferShowAllowed && gs_requestFrameExtentsStatus != 2 && !gtk_widget_get_realized(m_widget) && g_signal_handler_find(m_widget, GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET), 0, NULL, NULL, this); if (deferShow) { GdkScreen* screen = gtk_widget_get_screen(m_widget); GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false); deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0; // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes // to m_decorSize, it breaks saving/restoring window size with // GetSize()/SetSize() because it makes window bigger between each // restore and save. m_updateDecorSize = deferShow; } m_deferShow = deferShow; } if (deferShow) { // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer // calling gtk_widget_show() until _NET_FRAME_EXTENTS property // notification is received, so correct frame extents are known. // This allows resizing m_widget to keep the overall size in sync with // what wxWidgets expects it to be without an obvious change in the // window size immediately after it becomes visible. // Realize m_widget, so m_widget->window can be used. Realizing normally // causes the widget tree to be size_allocated, which generates size // events in the wrong order. However, the size_allocates will not be // done if the allocation is not the default (1,1). GtkAllocation alloc; gtk_widget_get_allocation(m_widget, &alloc); const int alloc_width = alloc.width; if (alloc_width == 1) { alloc.width = 2; gtk_widget_set_allocation(m_widget, &alloc); } gtk_widget_realize(m_widget); if (alloc_width == 1) { alloc.width = 1; gtk_widget_set_allocation(m_widget, &alloc); } // send _NET_REQUEST_FRAME_EXTENTS XClientMessageEvent xevent; memset(&xevent, 0, sizeof(xevent)); xevent.type = ClientMessage; GdkWindow* window = gtk_widget_get_window(m_widget); xevent.window = GDK_WINDOW_XID(window); xevent.message_type = gdk_x11_atom_to_xatom_for_display( gdk_window_get_display(window), gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)); xevent.format = 32; Display* display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(window)); XSendEvent(display, DefaultRootWindow(display), false, SubstructureNotifyMask | SubstructureRedirectMask, (XEvent*)&xevent); if (gs_requestFrameExtentsStatus == 0) { // if WM does not respond to request within 1 second, // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working m_netFrameExtentsTimerId = g_timeout_add(1000, request_frame_extents_timeout, this); } // defer calling gtk_widget_show() m_isShown = true; return true; } #endif // GDK_WINDOWING_X11 if (show && !gtk_widget_get_realized(m_widget)) { // size_allocate signals occur in reverse order (bottom to top). // Things work better if the initial wxSizeEvents are sent (from the // top down), before the initial size_allocate signals occur. wxSizeEvent event(GetSize(), GetId()); event.SetEventObject(this); HandleWindowEvent(event); } bool change = base_type::Show(show); if (change && !show) { // make sure window has a non-default position, so when it is shown // again, it won't be repositioned by WM as if it were a new window // Note that this must be done _after_ the window is hidden. gtk_window_move((GtkWindow*)m_widget, m_x, m_y); } return change; }
/* This is a _horrible_ hack to have this here. This needs to be added to the * GTK+ menuing code in some manner. */ static void drag_end_menu_cb (GtkWidget *widget, GdkDragContext *context) { GtkWidget *xgrab_shell; GtkWidget *parent; /* Find the last viewable ancestor, and make an X grab on it */ parent = gtk_widget_get_parent (widget); xgrab_shell = NULL; /* FIXME: workaround for a possible gtk+ bug * See bugs #92085(gtk+) and #91184(panel) for details. */ g_object_set (widget, "has-tooltip", TRUE, NULL); while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!gtk_widget_get_mapped (tmp)) { viewable = FALSE; break; } tmp = gtk_widget_get_parent (tmp); } if (viewable) xgrab_shell = parent; parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent)); } if (xgrab_shell) { gboolean status; GdkDisplay *display; GdkDevice *pointer; GdkDevice *keyboard; GdkDeviceManager *device_manager; GdkWindow *window = gtk_widget_get_window (xgrab_shell); GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_ARROW); display = gdk_window_get_display (window); device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); keyboard = gdk_device_get_associated_device (pointer); /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW or GDK_OWNERSHIP_APPLICATION. Idem for the keyboard below */ status = gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, cursor, GDK_CURRENT_TIME); if (!status) { if (gdk_device_grab (keyboard, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS) { /* FIXMEgpoo: We need either accessors or a workaround to grab the focus */ #if 0 GTK_MENU_SHELL (xgrab_shell)->GSEAL(have_xgrab) = TRUE; #endif } else { gdk_device_ungrab (pointer, GDK_CURRENT_TIME); } } g_object_unref (cursor); } }
const guint16 const *vnc_display_keymap_gdk2xtkbd_table(GdkWindow *window, size_t *maplen) { #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_WINDOW(window)) { XkbDescPtr desc; const gchar *keycodes = NULL; GdkDisplay *dpy = gdk_window_get_display(window); /* There is no easy way to determine what X11 server * and platform & keyboard driver is in use. Thus we * do best guess heuristics. * * This will need more work for people with other * X servers..... patches welcomed. */ desc = XkbGetKeyboard(gdk_x11_display_get_xdisplay(dpy), XkbGBN_AllComponentsMask, XkbUseCoreKbd); if (desc) { if (desc->names) { keycodes = gdk_x11_get_xatom_name(desc->names->keycodes); if (!keycodes) g_warning("could not lookup keycode name"); } XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); } if (check_for_xwin(dpy)) { VNC_DEBUG("Using xwin keycode mapping"); *maplen = G_N_ELEMENTS(keymap_xorgxwin2xtkbd); return keymap_xorgxwin2xtkbd; } else if (check_for_xquartz(dpy)) { VNC_DEBUG("Using xquartz keycode mapping"); *maplen = G_N_ELEMENTS(keymap_xorgxquartz2xtkbd); return keymap_xorgxquartz2xtkbd; } else if (keycodes && STRPREFIX(keycodes, "evdev_")) { VNC_DEBUG("Using evdev keycode mapping"); *maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd); return keymap_xorgevdev2xtkbd; } else if (keycodes && STRPREFIX(keycodes, "xfree86_")) { VNC_DEBUG("Using xfree86 keycode mapping"); *maplen = G_N_ELEMENTS(keymap_xorgkbd2xtkbd); return keymap_xorgkbd2xtkbd; } else { g_warning("Unknown keycode mapping '%s'.\n" "Please report to [email protected]\n" "including the following information:\n" "\n" " - Operating system\n" " - GDK build\n" " - X11 Server\n" " - xprop -root\n" " - xdpyinfo\n", keycodes); return NULL; } } #endif #ifdef GDK_WINDOWING_WIN32 if (GDK_IS_WIN32_WINDOW(window)) { VNC_DEBUG("Using Win32 virtual keycode mapping"); *maplen = G_N_ELEMENTS(keymap_win322xtkbd); return keymap_win322xtkbd; } #endif #ifdef GDK_WINDOWING_QUARTZ if (GDK_IS_QUARTZ_WINDOW(window)) { VNC_DEBUG("Using OS-X virtual keycode mapping"); *maplen = G_N_ELEMENTS(keymap_osx2xtkbd); return keymap_osx2xtkbd; } #endif #ifdef GDK_WINDOWING_WAYLAND if (GDK_IS_WAYLAND_WINDOW(window)) { VNC_DEBUG("Using Wayland Xorg/evdev virtual keycode mapping"); *maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd); return keymap_xorgevdev2xtkbd; } #endif #ifdef GDK_WINDOWING_BROADWAY if (GDK_IS_BROADWAY_WINDOW(window)) { g_warning("experimental: using broadway, x11 virtual keysym mapping - with very limited support. See also https://bugzilla.gnome.org/show_bug.cgi?id=700105"); *maplen = G_N_ELEMENTS(keymap_x112xtkbd); return keymap_x112xtkbd; } #endif g_warning("Unsupported GDK Windowing platform.\n" "Disabling extended keycode tables.\n" "Please report to [email protected]\n" "including the following information:\n" "\n" " - Operating system\n" " - GDK Windowing system build\n"); return NULL; }
RedirectedXCompositeWindow::RedirectedXCompositeWindow(WebPageProxy& webPage, const IntSize& initialSize, std::function<void()>&& damageNotify) : m_webPage(webPage) , m_display(GDK_DISPLAY_XDISPLAY(gdk_window_get_display(gtk_widget_get_parent_window(webPage.viewWidget())))) , m_size(initialSize) { m_size.scale(m_webPage.deviceScaleFactor()); ASSERT(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native() == m_display); Screen* screen = DefaultScreenOfDisplay(m_display); GdkVisual* visual = gdk_window_get_visual(gtk_widget_get_parent_window(webPage.viewWidget())); XUniqueColormap colormap(XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone)); // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc XSetWindowAttributes windowAttributes; windowAttributes.override_redirect = True; windowAttributes.colormap = colormap.get(); // CWBorderPixel must be present when the depth doesn't match the parent's one. // See http://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?id=xorg-server-1.16.0#n703. windowAttributes.border_pixel = 0; m_parentWindow = XCreateWindow(m_display, RootWindowOfScreen(screen), WidthOfScreen(screen) + 1, 0, 1, 1, 0, gdk_visual_get_depth(visual), InputOutput, GDK_VISUAL_XVISUAL(visual), CWOverrideRedirect | CWColormap | CWBorderPixel, &windowAttributes); XMapWindow(m_display, m_parentWindow.get()); windowAttributes.event_mask = StructureNotifyMask; windowAttributes.override_redirect = False; // Create the window of at last 1x1 since X doesn't allow to create empty windows. m_window = XCreateWindow(m_display, m_parentWindow.get(), 0, 0, std::max(1, m_size.width()), std::max(1, m_size.height()), 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &windowAttributes); XMapWindow(m_display, m_window.get()); xDamageNotifier().add(m_window.get(), WTFMove(damageNotify)); while (1) { XEvent event; XWindowEvent(m_display, m_window.get(), StructureNotifyMask, &event); if (event.type == MapNotify && event.xmap.window == m_window.get()) break; } XSelectInput(m_display, m_window.get(), NoEventMask); XCompositeRedirectWindow(m_display, m_window.get(), CompositeRedirectManual); if (!m_size.isEmpty()) createNewPixampAndPixampSurface(); m_damage = XDamageCreate(m_display, m_window.get(), XDamageReportNonEmpty); }
gboolean _gdk_input_other_event (GdkEvent *event, MSG *msg, GdkWindow *window) { GdkDisplay *display; GdkDeviceWintab *device = NULL; GdkDeviceGrabInfo *last_grab; GdkEventMask masktest; guint key_state; POINT pt; PACKET packet; gdouble root_x, root_y; gint num_axes; gint x, y; guint translated_buttons, button_diff, button_mask; /* Translation from tablet button state to GDK button state for * buttons 1-3 - swap button 2 and 3. */ static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7}; if (event->any.window != wintab_window) { g_warning ("_gdk_input_other_event: not wintab_window?"); return FALSE; } window = gdk_window_at_pointer (&x, &y); if (window == NULL) window = _gdk_root; g_object_ref (window); display = gdk_window_get_display (window); GDK_NOTE (EVENTS_OR_INPUT, g_print ("_gdk_input_other_event: window=%p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); if (msg->message == WT_PACKET) { if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet)) return FALSE; } switch (msg->message) { case WT_PACKET: /* Don't produce any button or motion events while a window is being * moved or resized, see bug #151090. */ if (_modal_operation_in_progress) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n")); return FALSE; } if ((device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (device)) == GDK_MODE_DISABLED) return FALSE; last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (device)); if (last_grab && last_grab->window) { g_object_unref (window); window = g_object_ref (last_grab->window); } if (window == _gdk_root) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n")); return FALSE; } num_axes = 0; if (device->pktdata & PK_X) device->last_axis_data[num_axes++] = packet.pkX; if (device->pktdata & PK_Y) device->last_axis_data[num_axes++] = packet.pkY; if (device->pktdata & PK_NORMAL_PRESSURE) device->last_axis_data[num_axes++] = packet.pkNormalPressure; if (device->pktdata & PK_ORIENTATION) { decode_tilt (device->last_axis_data + num_axes, device->orientation_axes, &packet); num_axes += 2; } translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07); if (translated_buttons != device->button_state) { /* At least one button has changed state so produce a button event * If more than one button has changed state (unlikely), * just care about the first and act on the next the next time * we get a packet */ button_diff = translated_buttons ^ device->button_state; /* Gdk buttons are numbered 1.. */ event->button.button = 1; for (button_mask = 1; button_mask != 0x80000000; button_mask <<= 1, event->button.button++) { if (button_diff & button_mask) { /* Found a button that has changed state */ break; } } if (!(translated_buttons & button_mask)) { event->any.type = GDK_BUTTON_RELEASE; masktest = GDK_BUTTON_RELEASE_MASK; } else { event->any.type = GDK_BUTTON_PRESS; masktest = GDK_BUTTON_PRESS_MASK; } device->button_state ^= button_mask; } else { event->any.type = GDK_MOTION_NOTIFY; masktest = GDK_POINTER_MOTION_MASK; if (device->button_state & (1 << 0)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK; if (device->button_state & (1 << 1)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK; if (device->button_state & (1 << 2)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK; } /* Now we can check if the window wants the event, and * propagate if necessary. */ while (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n")); if (window->parent == GDK_WINDOW (_gdk_root)) return FALSE; /* It is not good to propagate the extended events up to the parent * if this window wants normal (not extended) motion/button events */ if (window->event_mask & masktest) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... wants ordinary event, ignoring this\n")); return FALSE; } pt.x = x; pt.y = y; ClientToScreen (GDK_WINDOW_HWND (window), &pt); g_object_unref (window); window = window->parent; g_object_ref (window); ScreenToClient (GDK_WINDOW_HWND (window), &pt); x = pt.x; y = pt.y; GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); } if (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0) return FALSE; event->any.window = window; key_state = get_modifier_key_state (); if (event->any.type == GDK_BUTTON_PRESS || event->any.type == GDK_BUTTON_RELEASE) { event->button.time = _gdk_win32_get_next_tick (msg->time); gdk_event_set_device (event, GDK_DEVICE (device)); event->button.axes = g_new (gdouble, num_axes); _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (device, window, event->button.axes, &event->button.x, &event->button.y); event->button.x_root = event->button.x + root_x; event->button.y_root = event->button.y + root_y; event->button.state = key_state | ((device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB button %s:%d %g,%g\n", (event->button.type == GDK_BUTTON_PRESS ? "press" : "release"), event->button.button, event->button.x, event->button.y)); } else { event->motion.time = _gdk_win32_get_next_tick (msg->time); event->motion.is_hint = FALSE; gdk_event_set_device (event, GDK_DEVICE (device)); event->motion.axes = g_new (gdouble, num_axes); _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (device, window, event->motion.axes, &event->motion.x, &event->motion.y); event->motion.x_root = event->motion.x + root_x; event->motion.y_root = event->motion.y + root_y; event->motion.state = key_state | ((device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB motion: %g,%g\n", event->motion.x, event->motion.y)); } return TRUE; case WT_PROXIMITY: if (LOWORD (msg->lParam) == 0) { event->proximity.type = GDK_PROXIMITY_OUT; set_ignore_core (FALSE); } else { event->proximity.type = GDK_PROXIMITY_IN; set_ignore_core (TRUE); } event->proximity.time = _gdk_win32_get_next_tick (msg->time); gdk_event_set_device (event, GDK_DEVICE (device)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB proximity %s\n", (event->proximity.type == GDK_PROXIMITY_IN ? "in" : "out"))); return TRUE; } return FALSE; }
static gboolean _lib_histogram_motion_notify_callback(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data; /* check if exposure hooks are available */ gboolean hooks_available = dt_dev_exposure_hooks_available(darktable.develop); if(!hooks_available) return TRUE; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if(d->dragging && d->highlight == 2) { float exposure = d->exposure + (event->x - d->button_down_x) * 4.0f / (float)allocation.width; dt_dev_exposure_set_exposure(darktable.develop, exposure); } else if(d->dragging && d->highlight == 1) { float black = d->black - (event->x - d->button_down_x) * .1f / (float)allocation.width; dt_dev_exposure_set_black(darktable.develop, black); } else { const float offs = 4 * DT_HIST_INSET; const float x = event->x - offs; const float y = event->y - DT_HIST_INSET; const float pos = x / (float)(allocation.width - 2 * offs); if(pos < 0 || pos > 1.0) ; else if(x > d->mode_x && x < d->mode_x + d->mode_w && y > d->button_y && y < d->button_y + d->button_h) { d->highlight = 3; switch(darktable.develop->histogram_type) { case DT_DEV_HISTOGRAM_LOGARITHMIC: gtk_widget_set_tooltip_text(widget, _("set histogram mode to linear")); break; case DT_DEV_HISTOGRAM_LINEAR: gtk_widget_set_tooltip_text(widget, _("set histogram mode to waveform")); break; case DT_DEV_HISTOGRAM_WAVEFORM: gtk_widget_set_tooltip_text(widget, _("set histogram mode to logarithmic")); break; case DT_DEV_HISTOGRAM_N: g_assert_not_reached(); } } else if(x > d->red_x && x < d->red_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h) { d->highlight = 4; gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide red channel") : _("click to show red channel")); } else if(x > d->green_x && x < d->green_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h) { d->highlight = 5; gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide green channel") : _("click to show green channel")); } else if(x > d->blue_x && x < d->blue_x + d->color_w && y > d->button_y && y < d->button_y + d->button_h) { d->highlight = 6; gtk_widget_set_tooltip_text(widget, d->red ? _("click to hide blue channel") : _("click to show blue channel")); } else if(pos < 0.2) { d->highlight = 1; gtk_widget_set_tooltip_text(widget, _("drag to change black point,\ndoubleclick resets")); } else { d->highlight = 2; gtk_widget_set_tooltip_text(widget, _("drag to change exposure,\ndoubleclick resets")); } gtk_widget_queue_draw(widget); } gint x, y; // notify gtk for motion_hint. gdk_window_get_device_position(event->window, gdk_device_manager_get_client_pointer( gdk_display_get_device_manager(gdk_window_get_display(event->window))), &x, &y, NULL); return TRUE; }
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win ) { GdkWindow *window = NULL; if (win) window = gtk_widget_get_window(win->GetHandle()); switch (index) { case wxSYS_BORDER_X: case wxSYS_BORDER_Y: case wxSYS_EDGE_X: case wxSYS_EDGE_Y: case wxSYS_FRAMESIZE_X: case wxSYS_FRAMESIZE_Y: if (win) { wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow); if (!tlw) return GetBorderWidth(index, win); else if (window) { // Get the frame extents from the windowmanager. // In most cases the top extent is the titlebar, so we use the bottom extent // for the heights. int right, bottom; if (wxGetFrameExtents(window, NULL, &right, NULL, &bottom)) { switch (index) { case wxSYS_BORDER_X: case wxSYS_EDGE_X: case wxSYS_FRAMESIZE_X: return right; // width of right extent default: return bottom; // height of bottom extent } } } } return -1; // no window specified case wxSYS_CURSOR_X: case wxSYS_CURSOR_Y: return gdk_display_get_default_cursor_size( window ? gdk_window_get_display(window) : gdk_display_get_default()); case wxSYS_DCLICK_X: case wxSYS_DCLICK_Y: gint dclick_distance; g_object_get(GetSettingsForWindowScreen(window), "gtk-double-click-distance", &dclick_distance, NULL); return dclick_distance * 2; case wxSYS_DCLICK_MSEC: gint dclick; g_object_get(GetSettingsForWindowScreen(window), "gtk-double-click-time", &dclick, NULL); return dclick; case wxSYS_DRAG_X: case wxSYS_DRAG_Y: gint drag_threshold; g_object_get(GetSettingsForWindowScreen(window), "gtk-dnd-drag-threshold", &drag_threshold, NULL); // The correct thing here would be to double the value // since that is what the API wants. But the values // are much bigger under GNOME than under Windows and // just seem to much in many cases to be useful. // drag_threshold *= 2; return drag_threshold; case wxSYS_ICON_X: case wxSYS_ICON_Y: return 32; case wxSYS_SCREEN_X: if (window) return gdk_screen_get_width(gdk_window_get_screen(window)); else return gdk_screen_width(); case wxSYS_SCREEN_Y: if (window) return gdk_screen_get_height(gdk_window_get_screen(window)); else return gdk_screen_height(); case wxSYS_HSCROLL_Y: case wxSYS_VSCROLL_X: return 15; case wxSYS_CAPTION_Y: if (!window) // No realized window specified, and no implementation for that case yet. return -1; wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow), wxT("Asking for caption height of a non toplevel window") ); // Get the height of the top windowmanager border. // This is the titlebar in most cases. The titlebar might be elsewhere, and // we could check which is the thickest wm border to decide on which side the // titlebar is, but this might lead to interesting behaviours in used code. // Reconsider when we have a way to report to the user on which side it is. { int top; if (wxGetFrameExtents(window, NULL, NULL, &top, NULL)) { return top; // top frame extent } } // Try a default approach without a window pointer, if possible // ... return -1; case wxSYS_PENWINDOWS_PRESENT: // No MS Windows for Pen computing extension available in X11 based gtk+. return 0; default: return -1; // metric is unknown } }
static void _gtk_pixel_cache_create_surface_if_needed (GtkPixelCache *cache, GdkWindow *window, cairo_rectangle_int_t *view_rect, cairo_rectangle_int_t *canvas_rect) { cairo_rectangle_int_t rect; int surface_w, surface_h; cairo_content_t content; #ifdef G_ENABLE_DEBUG if (GTK_DISPLAY_DEBUG_CHECK (gdk_window_get_display (window), NO_PIXEL_CACHE)) return; #endif content = cache->content; if (!content) { if (cache->is_opaque) content = CAIRO_CONTENT_COLOR; else content = CAIRO_CONTENT_COLOR_ALPHA; } surface_w = view_rect->width; if (canvas_rect->width > surface_w) surface_w = MIN (surface_w + cache->extra_width, canvas_rect->width); surface_h = view_rect->height; if (canvas_rect->height > surface_h) surface_h = MIN (surface_h + cache->extra_height, canvas_rect->height); /* If current surface can't fit view_rect or is too large, kill it */ if (cache->surface != NULL && (cairo_surface_get_content (cache->surface) != content || cache->surface_w < MAX(view_rect->width, surface_w * ALLOW_SMALLER_SIZE_FACTOR) || cache->surface_w > surface_w * ALLOW_LARGER_SIZE_FACTOR || cache->surface_h < MAX(view_rect->height, surface_h * ALLOW_SMALLER_SIZE_FACTOR) || cache->surface_h > surface_h * ALLOW_LARGER_SIZE_FACTOR || cache->surface_scale != gdk_window_get_scale_factor (window))) { cairo_surface_destroy (cache->surface); cache->surface = NULL; if (cache->surface_dirty) cairo_region_destroy (cache->surface_dirty); cache->surface_dirty = NULL; } /* Don't allocate a surface if view >= canvas, as we won't * be scrolling then anyway, unless the widget requested it. */ if (cache->surface == NULL && (cache->always_cache || (view_rect->width < canvas_rect->width || view_rect->height < canvas_rect->height))) { cache->surface_x = -canvas_rect->x; cache->surface_y = -canvas_rect->y; cache->surface_w = surface_w; cache->surface_h = surface_h; cache->surface_scale = gdk_window_get_scale_factor (window); cache->surface = gdk_window_create_similar_surface (window, content, surface_w, surface_h); rect.x = 0; rect.y = 0; rect.width = surface_w; rect.height = surface_h; cache->surface_dirty = cairo_region_create_rectangle (&rect); } }
bool show(Display* parent) override { static std::string s_lastUsedDir; if (s_lastUsedDir.empty()) s_lastUsedDir = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP); const char* okLabel; GtkFileChooserAction action; switch (m_type) { case Type::OpenFile: case Type::OpenFiles: action = GTK_FILE_CHOOSER_ACTION_OPEN; okLabel = "_Open"; break; case Type::OpenFolder: action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; okLabel = "_Open Folder"; break; case Type::SaveFile: action = GTK_FILE_CHOOSER_ACTION_SAVE; okLabel = "_Save"; break; } // GtkWindow* gtkParent = nullptr; GtkWidget* dialog = gtk_file_chooser_dialog_new( m_title.c_str(), nullptr, action, "_Cancel", GTK_RESPONSE_CANCEL, okLabel, GTK_RESPONSE_ACCEPT, nullptr); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); GtkFileChooser* chooser = GTK_FILE_CHOOSER(dialog); m_chooser = chooser; if (m_type == Type::SaveFile) gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE); else if (m_type == Type::OpenFiles) gtk_file_chooser_set_select_multiple(chooser, true); if (m_type != Type::OpenFolder) { setupFilters(base::get_file_extension(m_filename)); setupPreview(); } if (m_initialDir.empty()) gtk_file_chooser_set_current_folder(chooser, s_lastUsedDir.c_str()); else gtk_file_chooser_set_current_folder(chooser, m_initialDir.c_str()); if (!m_filename.empty()) { std::string fn = m_filename; // Add default extension if (m_type == Type::SaveFile && base::get_file_extension(fn).empty()) { fn.push_back('.'); fn += m_defExtension; } gtk_file_chooser_set_current_name(chooser, fn.c_str()); } // Setup the "parent" display as the parent of the dialog (we've // to convert a X11 Window into a GdkWindow to do this). GdkWindow* gdkParentWindow = nullptr; if (parent) { GdkWindow* gdkWindow = gtk_widget_get_root_window(dialog); gdkParentWindow = gdk_x11_window_foreign_new_for_display( gdk_window_get_display(gdkWindow), (::Window)parent->nativeHandle()); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gdk_window_set_transient_for(gdkWindow, gdkParentWindow); } else { gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); } // Show the dialog gint res = gtk_dialog_run(GTK_DIALOG(dialog)); if (res == GTK_RESPONSE_ACCEPT) { s_lastUsedDir = gtk_file_chooser_get_current_folder(chooser); m_filename = gtk_file_chooser_get_filename(chooser); if (m_type == Type::OpenFiles) { GSList* list = gtk_file_chooser_get_filenames(chooser); g_slist_foreach( list, [](void* fn, void* userdata){ auto self = (FileDialogGTK*)userdata; self->m_filenames.push_back((char*)fn); g_free(fn); }, this); g_slist_free(list); } } gtk_widget_destroy(dialog); if (gdkParentWindow) g_object_unref(gdkParentWindow); // Pump gtk+ events to finally hide the dialog from the screen while (gtk_events_pending()) gtk_main_iteration(); return (res == GTK_RESPONSE_ACCEPT); }
void ImGui_ImplGtk3Cogl_NewFrame() { if (!g_ColorPipeline) ImGui_ImplGtk3Cogl_CreateDeviceObjects(); bool next_redraw = false; if (g_NumRedraws > 0) { GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow); gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT); g_NumRedraws--; next_redraw = true; } ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) int w, h; gdk_window_get_geometry(g_GdkWindow, NULL, NULL, &w, &h); io.DisplaySize = ImVec2((float)w, (float)h); io.DisplayFramebufferScale = g_Callbacks->get_scale(g_GdkWindow); // Setup time step guint64 current_time = g_get_monotonic_time(); io.DeltaTime = g_Time > 0 ? ((float)(current_time - g_Time) / 1000000) : (float)(1.0f/60.0f); g_Time = current_time; // Setup inputs if (gdk_window_get_state(g_GdkWindow) & GDK_WINDOW_STATE_FOCUSED) { io.MousePos = g_MousePosition; // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) } else { io.MousePos = ImVec2(-1,-1); } GdkDevice *pointer = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default())); GdkModifierType modifiers; gdk_device_get_state(pointer, g_GdkWindow, NULL, &modifiers); for (int i = 0; i < 3; i++) { io.MouseDown[i] = g_MousePressed[i] || (modifiers & (GDK_BUTTON1_MASK << i)) != 0; g_MousePressed[i] = false; } io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it GdkDisplay *display = gdk_window_get_display(g_GdkWindow); GdkCursor *cursor = gdk_cursor_new_from_name(display, io.MouseDrawCursor ? "none" : "default"); gdk_window_set_cursor(g_GdkWindow, cursor); g_object_unref(cursor); // Start the frame ImGui::NewFrame(); if (!next_redraw && io.WantTextInput) kick_timeout_redraw(0.2); }