GdkMonitor * gimp_widget_get_monitor (GtkWidget *widget) { GdkWindow *window; GtkAllocation allocation; gint x, y; g_return_val_if_fail (GTK_IS_WIDGET (widget), 0); window = gtk_widget_get_window (widget); if (! window) return gimp_get_monitor_at_pointer (); gdk_window_get_origin (window, &x, &y); gtk_widget_get_allocation (widget, &allocation); if (! gtk_widget_get_has_window (widget)) { x += allocation.x; y += allocation.y; } x += allocation.width / 2; y += allocation.height / 2; return gdk_display_get_monitor_at_point (gdk_display_get_default (), x, y); }
static gboolean manager_maybe_grab_window (GSManager *manager, GSWindow *window) { GdkDisplay *display; GdkDevice *device; GdkMonitor *monitor; int x, y; gboolean grabbed; display = gdk_display_get_default (); device = gdk_seat_get_pointer (gdk_display_get_default_seat (display)); gdk_device_get_position (device, NULL, &x, &y); monitor = gdk_display_get_monitor_at_point (display, x, y); gdk_display_flush (display); grabbed = FALSE; if (gs_window_get_display (window) == display && gs_window_get_monitor (window) == monitor) { gs_debug ("Initiate grab move to %p", window); gs_grab_move_to_window (manager->priv->grab, gs_window_get_gdk_window (window), gs_window_get_display (window), FALSE, FALSE); grabbed = TRUE; } return grabbed; }
static void nimf_candidate_show (NimfCandidatable *candidatable, NimfServiceIC *target, gboolean show_entry) { g_debug (G_STRLOC ": %s", G_STRFUNC); NimfCandidate *candidate = NIMF_CANDIDATE (candidatable); GtkRequisition natural_size; int x, y, w, h; GdkRectangle geometry; const NimfRectangle *cursor_area; cursor_area = nimf_service_ic_get_cursor_location (target); #if GTK_CHECK_VERSION (3, 22, 0) GdkDisplay *display = gtk_widget_get_display (candidate->window); GdkMonitor *monitor; monitor = gdk_display_get_monitor_at_point (display, cursor_area->x, cursor_area->y); gdk_monitor_get_geometry (monitor, &geometry); #else GdkScreen *screen = gtk_widget_get_screen (candidate->window); gint monitor_num = gdk_screen_get_monitor_at_point (screen, cursor_area->x, cursor_area->y); gdk_screen_get_monitor_geometry (screen, monitor_num, &geometry); #endif candidate->target = target; if (show_entry) gtk_widget_show (candidate->entry); else gtk_widget_hide (candidate->entry); gtk_widget_show_all (candidate->window); gtk_widget_get_preferred_size (candidate->window, NULL, &natural_size); gtk_window_resize (GTK_WINDOW (candidate->window), natural_size.width, natural_size.height); gtk_window_get_size (GTK_WINDOW (candidate->window), &w, &h); x = cursor_area->x - cursor_area->width; y = cursor_area->y + cursor_area->height; if (x + w > geometry.x + geometry.width) x = geometry.x + geometry.width - w; if ((y + h > geometry.y + geometry.height) && ((cursor_area->y - h) >= geometry.y)) y = cursor_area->y - h; gtk_window_move (GTK_WINDOW (candidate->window), x, y); }
/** * gdk_screen_get_monitor_at_point: * @screen: a #GdkScreen. * @x: the x coordinate in the virtual screen. * @y: the y coordinate in the virtual screen. * * Returns the monitor number in which the point (@x,@y) is located. * * Returns: the monitor number in which the point (@x,@y) lies, or * a monitor close to (@x,@y) if the point is not in any monitor. * * Since: 2.2 **/ gint gdk_screen_get_monitor_at_point (GdkScreen *screen, gint x, gint y) { GdkDisplay *display; GdkMonitor *monitor; g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); display = gdk_screen_get_display (screen); monitor = gdk_display_get_monitor_at_point (display, x, y); return get_monitor_num (monitor); }
GdkMonitor * gimp_get_monitor_at_pointer (void) { GdkDisplay *display; GdkSeat *seat; gint x, y; display = gdk_display_get_default (); seat = gdk_display_get_default_seat (display); gdk_device_get_position (gdk_seat_get_pointer (seat), NULL, &x, &y); return gdk_display_get_monitor_at_point (display, x, y); }
static GSWindow * find_window_at_pointer (GSManager *manager) { GdkDisplay *display; GdkDevice *device; GdkMonitor *monitor; int x, y; GSWindow *window; GSList *l; display = gdk_display_get_default (); device = gdk_seat_get_pointer (gdk_display_get_default_seat (display)); gdk_device_get_position (device, NULL, &x, &y); monitor = gdk_display_get_monitor_at_point (display, x, y); /* Find the gs-window that is on that monitor */ window = NULL; for (l = manager->priv->windows; l; l = l->next) { GSWindow *win = GS_WINDOW (l->data); if (gs_window_get_display (win) == display && gs_window_get_monitor (win) == monitor) { window = win; } } if (window == NULL) { gs_debug ("WARNING: Could not find the GSWindow for display %s", gdk_display_get_name (display)); /* take the first one */ window = manager->priv->windows->data; } else { gs_debug ("Requesting unlock for display %s", gdk_display_get_name (display)); } return window; }
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; }
void create_main_window (GsmApplication *app) { GtkApplicationWindow *main_window; GtkStack *stack; GtkMenuButton *process_menu_button; GMenuModel *process_menu_model; GdkDisplay *display; GdkMonitor *monitor; GdkRectangle monitor_geometry; const char* session; int width, height, xpos, ypos; GtkBuilder *builder = gtk_builder_new(); gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/interface.ui", NULL); gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/menus.ui", NULL); main_window = GTK_APPLICATION_WINDOW (gtk_builder_get_object (builder, "main_window")); gtk_window_set_application (GTK_WINDOW (main_window), app->gobj()); gtk_widget_set_name (GTK_WIDGET (main_window), "gnome-system-monitor"); app->main_window = main_window; session = g_getenv ("XDG_CURRENT_DESKTOP"); if (session && !strstr (session, "GNOME")){ GtkBox *mainbox; GtkHeaderBar *headerbar; mainbox = GTK_BOX (gtk_builder_get_object (builder, "main_box")); headerbar = GTK_HEADER_BAR (gtk_builder_get_object (builder, "header_bar")); gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (headerbar)), "titlebar"); gtk_window_set_titlebar (GTK_WINDOW (main_window), NULL); gtk_header_bar_set_show_close_button (headerbar, FALSE); gtk_box_pack_start (mainbox, GTK_WIDGET (headerbar), FALSE, FALSE, 0); } g_settings_get (app->settings->gobj(), GSM_SETTING_WINDOW_STATE, "(iiii)", &width, &height, &xpos, &ypos); display = gdk_display_get_default (); monitor = gdk_display_get_monitor_at_point (display, xpos, ypos); if (monitor == NULL) { monitor = gdk_display_get_monitor (display, 0); } gdk_monitor_get_geometry (monitor, &monitor_geometry); width = CLAMP (width, 50, monitor_geometry.width); height = CLAMP (height, 50, monitor_geometry.height); xpos = CLAMP (xpos, 0, monitor_geometry.width - width); ypos = CLAMP (ypos, 0, monitor_geometry.height - height); gtk_window_set_default_size (GTK_WINDOW (main_window), width, height); gtk_window_move (GTK_WINDOW (main_window), xpos, ypos); if (app->settings->get_boolean (GSM_SETTING_MAXIMIZED)) gtk_window_maximize (GTK_WINDOW (main_window)); app->process_menu_button = process_menu_button = GTK_MENU_BUTTON (gtk_builder_get_object (builder, "process_menu_button")); process_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "process-window-menu")); gtk_menu_button_set_menu_model (process_menu_button, process_menu_model); app->end_process_button = GTK_BUTTON (gtk_builder_get_object (builder, "end_process_button")); app->search_button = GTK_BUTTON (gtk_builder_get_object (builder, "search_button")); GActionEntry win_action_entries[] = { { "about", on_activate_about, NULL, NULL, NULL }, { "search", on_activate_search, "b", "false", NULL }, { "send-signal-stop", on_activate_send_signal, "i", NULL, NULL }, { "send-signal-cont", on_activate_send_signal, "i", NULL, NULL }, { "send-signal-end", on_activate_send_signal, "i", NULL, NULL }, { "send-signal-kill", on_activate_send_signal, "i", NULL, NULL }, { "priority", on_activate_priority, "i", "@i 0", change_priority_state }, { "memory-maps", on_activate_memory_maps, NULL, NULL, NULL }, { "open-files", on_activate_open_files, NULL, NULL, NULL }, { "process-properties", on_activate_process_properties, NULL, NULL, NULL }, { "refresh", on_activate_refresh, NULL, NULL, NULL }, { "show-page", on_activate_radio, "s", "'resources'", change_show_page_state }, { "show-whose-processes", on_activate_radio, "s", "'all'", change_show_processes_state }, { "show-dependencies", on_activate_toggle, NULL, "false", change_show_dependencies_state } }; g_action_map_add_action_entries (G_ACTION_MAP (main_window), win_action_entries, G_N_ELEMENTS (win_action_entries), app); GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET (main_window)); GdkVisual* visual = gdk_screen_get_rgba_visual(screen); /* use visual, if available */ if (visual) gtk_widget_set_visual(GTK_WIDGET (main_window), visual); /* create the main stack */ app->stack = stack = GTK_STACK (gtk_builder_get_object (builder, "stack")); create_proc_view(app, builder); create_sys_view (app, builder); create_disk_view (app, builder); g_settings_bind (app->settings->gobj (), GSM_SETTING_CURRENT_TAB, stack, "visible-child-name", G_SETTINGS_BIND_DEFAULT); g_signal_connect (G_OBJECT (stack), "notify::visible-child", G_CALLBACK (cb_change_current_page), app); g_signal_connect (G_OBJECT (main_window), "delete_event", G_CALLBACK (cb_main_window_delete), app); g_signal_connect (G_OBJECT (main_window), "window-state-event", G_CALLBACK (cb_main_window_state_changed), app); GAction *action; action = g_action_map_lookup_action (G_ACTION_MAP (main_window), "show-dependencies"); g_action_change_state (action, g_settings_get_value (app->settings->gobj (), GSM_SETTING_SHOW_DEPENDENCIES)); action = g_action_map_lookup_action (G_ACTION_MAP (main_window), "show-whose-processes"); g_action_change_state (action, g_settings_get_value (app->settings->gobj (), GSM_SETTING_SHOW_WHOSE_PROCESSES)); gtk_widget_show (GTK_WIDGET (main_window)); update_page_activities (app); g_object_unref (G_OBJECT (builder)); }
static void gimp_pick_button_pick (GimpPickButton *button, GdkEvent *event) { GdkScreen *screen = gdk_event_get_screen (event); GimpColorProfile *monitor_profile; GdkMonitor *monitor; GimpRGB rgb; gint x_root; gint y_root; gdouble x_win; gdouble y_win; gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root); gdk_event_get_coords (event, &x_win, &y_win); x_root += x_win; y_root += y_win; #ifdef G_OS_WIN32 { HDC hdc; RECT rect; COLORREF win32_color; /* For MS Windows, use native GDI functions to get the pixel, as * cairo does not handle the case where you have multiple monitors * with a monitor on the left or above the primary monitor. That * scenario create a cairo primary surface with negative extent, * which is not handled properly (bug 740634). */ hdc = GetDC (HWND_DESKTOP); GetClipBox (hdc, &rect); win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top); ReleaseDC (HWND_DESKTOP, hdc); gimp_rgba_set_uchar (&rgb, GetRValue (win32_color), GetGValue (win32_color), GetBValue (win32_color), 255); } #else { GdkWindow *window; gint x_window; gint y_window; cairo_surface_t *image; cairo_t *cr; guchar *data; guchar color[3]; /* we try to pick from the local window under the cursor, and fall * back to picking from the root window if this fails (i.e., if * the cursor is not under a local window). on wayland, picking * from the root window is not supported, so this at least allows * us to pick from local windows. see bug #780375. */ window = gdk_device_get_window_at_position (gdk_event_get_device (event), &x_window, &y_window); if (! window) { window = gdk_screen_get_root_window (screen); x_window = x_root; y_window = y_root; } image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1); cr = cairo_create (image); gdk_cairo_set_source_window (cr, window, -x_window, -y_window); cairo_paint (cr); cairo_destroy (cr); data = cairo_image_surface_get_data (image); GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]); cairo_surface_destroy (image); gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255); } #endif monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), x_root, y_root); monitor_profile = gimp_monitor_get_color_profile (monitor); if (monitor_profile) { GimpColorProfile *srgb_profile; GimpColorTransform *transform; const Babl *format; GimpColorTransformFlags flags = 0; format = babl_format ("R'G'B'A double"); flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; srgb_profile = gimp_color_profile_new_rgb_srgb (); transform = gimp_color_transform_new (monitor_profile, format, srgb_profile, format, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, flags); g_object_unref (srgb_profile); if (transform) { gimp_color_transform_process_pixels (transform, format, &rgb, format, &rgb, 1); gimp_rgb_clamp (&rgb); g_object_unref (transform); } } g_signal_emit_by_name (button, "color-picked", &rgb); }
/** * gimp_session_info_read_geometry: * @info: A #GimpSessionInfo * @cevent A #GdkEventConfigure. If set, use the size from here * instead of from the window allocation. * * Read geometry related information from the associated widget. **/ void gimp_session_info_read_geometry (GimpSessionInfo *info, GdkEventConfigure *cevent) { GdkWindow *window; GdkDisplay *display; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); window = gtk_widget_get_window (info->p->widget); display = gtk_widget_get_display (info->p->widget); if (window) { gint x, y; GdkMonitor *monitor; GdkRectangle geometry; gtk_window_get_position (GTK_WINDOW (info->p->widget), &x, &y); /* Don't write negative values to the sessionrc, they are * interpreted as relative to the right, respective bottom edge * of the display. */ info->p->x = MAX (0, x); info->p->y = MAX (0, y); monitor = gdk_display_get_monitor_at_point (display, info->p->x, info->p->y); gdk_monitor_get_geometry (monitor, &geometry); /* Always store window coordinates relative to the monitor */ info->p->x -= geometry.x; info->p->y -= geometry.y; if (gimp_session_info_get_remember_size (info)) { gtk_window_get_size (GTK_WINDOW (info->p->widget), &info->p->width, &info->p->height); } else { info->p->width = 0; info->p->height = 0; } info->p->monitor = DEFAULT_MONITOR; if (monitor != gdk_display_get_primary_monitor (display)) info->p->monitor = monitor; } info->p->open = FALSE; if (gimp_session_info_get_remember_if_open (info)) { GimpDialogVisibilityState visibility; visibility = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info->p->widget), GIMP_DIALOG_VISIBILITY_KEY)); switch (visibility) { case GIMP_DIALOG_VISIBILITY_UNKNOWN: info->p->open = gtk_widget_get_visible (info->p->widget); break; case GIMP_DIALOG_VISIBILITY_INVISIBLE: info->p->open = FALSE; break; case GIMP_DIALOG_VISIBILITY_HIDDEN: case GIMP_DIALOG_VISIBILITY_VISIBLE: /* Even if a dialog is hidden (with Windows->Hide docks) it * is still considered open. It will be restored the next * time GIMP starts */ info->p->open = TRUE; break; } } }