bool wxTopLevelWindowGTK::CanSetTransparent() { // allow to override automatic detection as it's far from perfect const wxString SYSOPT_TRANSPARENT = "gtk.tlw.can-set-transparent"; if ( wxSystemOptions::HasOption(SYSOPT_TRANSPARENT) ) { return wxSystemOptions::GetOptionInt(SYSOPT_TRANSPARENT) != 0; } #ifdef __WXGTK3__ return gtk_widget_is_composited(m_widget) != 0; #else #if GTK_CHECK_VERSION(2,10,0) if (!gtk_check_version(2,10,0)) { return gtk_widget_is_composited(m_widget) != 0; } else #endif // In case of lower versions than gtk+-2.10.0 we could look for _NET_WM_CM_Sn ourselves { return false; } #endif // !__WXGTK3__ #if 0 // Don't be optimistic here for the sake of wxAUI int opcode, event, error; // Check for the existence of a RGBA visual instead? return XQueryExtension(gdk_x11_get_default_xdisplay (), "Composite", &opcode, &event, &error); #endif }
static void timeline_frame_cb (GsdTimeline *timeline, gdouble progress, gpointer user_data) { GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; GdkScreen *screen; gint cursor_x, cursor_y; if (gtk_widget_is_composited (data->widget)) { gdk_window_invalidate_rect (data->window, NULL, FALSE); data->progress = progress; } else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL) { /* only invalidate window each circle interval */ update_shape (data); gdk_window_invalidate_rect (data->window, NULL, FALSE); data->progress += CIRCLES_PROGRESS_INTERVAL; } screen = gdk_drawable_get_screen (data->window); gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL); gdk_window_move (data->window, cursor_x - WINDOW_SIZE / 2, cursor_y - WINDOW_SIZE / 2); }
static void maybe_update_shape (GtkWidget *widget) { cairo_t *cr; cairo_surface_t *surface; cairo_region_t *region; /* fallback to XShape only for non-composited clients */ if (gtk_widget_is_composited (widget)) { gtk_widget_shape_combine_region (widget, NULL); return; } surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), CAIRO_CONTENT_COLOR_ALPHA, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget)); cr = cairo_create (surface); label_draw_background_and_frame (widget, cr, TRUE); cairo_destroy (cr); region = gdk_cairo_region_create_from_surface (surface); gtk_widget_shape_combine_region (widget, region); cairo_surface_destroy (surface); cairo_region_destroy (region); }
static void update_shape (GtkTooltip *tooltip) { GdkBitmap *mask; cairo_t *cr; gint width, height, tooltip_radius; gtk_widget_style_get (tooltip->window, "tooltip-radius", &tooltip_radius, NULL); if (tooltip_radius == 0 || gtk_widget_is_composited (tooltip->window)) { gtk_widget_shape_combine_mask (tooltip->window, NULL, 0, 0); return; } gtk_window_get_size (GTK_WINDOW (tooltip->window), &width, &height); mask = (GdkBitmap *) gdk_pixmap_new (NULL, width, height, 1); cr = gdk_cairo_create (mask); fill_background (tooltip->window, cr, &tooltip->window->style->black, &tooltip->window->style->black, 255); gtk_widget_shape_combine_mask (tooltip->window, mask, 0, 0); cairo_destroy (cr); g_object_unref (mask); }
static void maybe_update_shape (GtkTooltip *tooltip) { cairo_t *cr; cairo_surface_t *surface; cairo_region_t *region; /* fallback to XShape only for non-composited clients */ if (gtk_widget_is_composited (tooltip->window)) { gtk_widget_shape_combine_region (tooltip->window, NULL); return; } surface = gdk_window_create_similar_surface (gtk_widget_get_window (tooltip->window), CAIRO_CONTENT_COLOR_ALPHA, gtk_widget_get_allocated_width (tooltip->window), gtk_widget_get_allocated_height (tooltip->window)); cr = cairo_create (surface); paint_background_and_frame (tooltip, cr); cairo_destroy (cr); region = gdk_cairo_region_create_from_surface (surface); gtk_widget_shape_combine_region (tooltip->window, region); cairo_surface_destroy (surface); cairo_region_destroy (region); }
static void awn_tooltip_set_mask (AwnTooltip *tooltip, gint width, gint height) { GtkWidget *widget = GTK_WIDGET (tooltip); if (gtk_widget_is_composited (widget) == FALSE) { GdkBitmap *shaped_bitmap; shaped_bitmap = (GdkBitmap*) gdk_pixmap_new (NULL, width, height, 1); if (shaped_bitmap) { cairo_t *cr = gdk_cairo_create (shaped_bitmap); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_translate (cr, 0.5, 0.5); awn_cairo_rounded_rect (cr, 0, 0, width, height, TOOLTIP_ROUND_RADIUS, ROUND_ALL); cairo_fill (cr); cairo_destroy (cr); gtk_widget_shape_combine_mask (widget, NULL, 0, 0); gtk_widget_shape_combine_mask (widget, shaped_bitmap, 0, 0); g_object_unref (shaped_bitmap); } } }
static void gtk_bubble_window_update_shape (GtkBubbleWindow *window) { cairo_surface_t *surface; cairo_region_t *region; GdkWindow *win; cairo_t *cr; win = gtk_widget_get_window (GTK_WIDGET (window)); surface = gdk_window_create_similar_surface (win, CAIRO_CONTENT_COLOR_ALPHA, gdk_window_get_width (win), gdk_window_get_height (win)); cr = cairo_create (surface); gtk_bubble_window_apply_border_path (window, cr); cairo_fill (cr); cairo_destroy (cr); region = gdk_cairo_region_create_from_surface (surface); cairo_surface_destroy (surface); if (!gtk_widget_is_composited (GTK_WIDGET (window))) gtk_widget_shape_combine_region (GTK_WIDGET (window), region); gtk_widget_input_shape_combine_region (GTK_WIDGET (window), region); cairo_region_destroy (region); }
static void composited_changed (GtkWidget *widget, GsdLocatePointerData *data) { if (!gtk_widget_is_composited (widget)) set_transparent_shape (data->window); else unset_transparent_shape (data->window); }
static gboolean on_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, Starter *wcm) { GtkAllocation allocation; GdkWindow *window; cairo_t *cr; cairo_pattern_t *pattern; window = gtk_widget_get_window (widget); cr = gdk_cairo_create (window); gtk_widget_get_allocation (widget, &allocation); pattern = cairo_pattern_create_linear (0, 0, 0, allocation.height); if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) && gtk_widget_is_composited (widget)) cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */ else cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.6, 0.7, 0.9, 1.0); /* solid orange */ cairo_pattern_add_color_stop_rgba (pattern, 0.18, 1.0, 1.0, 1.0, 1.0); /* transparent orange */ cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); cairo_destroy (cr); cr = gdk_cairo_create (window); gdk_cairo_set_source_pixbuf (cr, wcm->priv->logo, 20, 20); cairo_paint (cr); cairo_destroy (cr); GList *l, *list = NULL; list = gtk_container_get_children (GTK_CONTAINER (widget)); for (l = list; l != NULL; l = g_list_next (l)) gtk_container_propagate_expose (GTK_CONTAINER (widget), l->data, event); g_list_free (list); return TRUE; }
static void window_composited_changed (GtkWidget *widget, gpointer user_data) { gboolean composited; composited = gtk_widget_is_composited (widget); gtk_widget_set_app_paintable (widget, composited); }
static gboolean locate_pointer_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) { CsdLocatePointerData *data = (CsdLocatePointerData *) user_data; if (gtk_cairo_should_draw_window (cr, data->window)) locate_pointer_paint (data, cr, gtk_widget_is_composited (data->widget)); return TRUE; }
static void timeline_finished_cb (GsdTimeline *timeline, gpointer user_data) { GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; /* set transparent shape and hide window */ if (!gtk_widget_is_composited (data->widget)) set_transparent_shape (data->window); gdk_window_hide (data->window); }
static void _on_composited_changed (GtkWidget *widget) { if (gtk_widget_is_composited (widget) == FALSE) { GtkAllocation alloc; gtk_widget_get_allocation (widget, &alloc); awn_tooltip_set_mask (AWN_TOOLTIP (widget), alloc.width, alloc.height); } else { gtk_widget_shape_combine_mask (widget, NULL, 0, 0); } }
static gboolean locate_pointer_expose (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; cairo_t *cr; if (event->window != data->window) return FALSE; cr = gdk_cairo_create (data->window); locate_pointer_paint (data, cr, gtk_widget_is_composited (data->widget)); cairo_destroy (cr); return TRUE; }
static void update_opacity_sensitivity (PanelPropertiesDialog *dialog) { GtkWidget *widget; GdkScreen *screen; GdkVisual *visual; widget = GTK_WIDGET (dialog); screen = gtk_widget_get_screen (widget); visual = gdk_screen_get_rgba_visual (screen); if (visual == NULL || gtk_widget_is_composited (widget) == FALSE) { gtk_widget_set_sensitive (dialog->priv->background_opacity_box, FALSE); } else { gtk_widget_set_sensitive (dialog->priv->background_opacity_box, TRUE); } }
static gboolean label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { if (gtk_widget_is_composited (widget)) { /* clear any content */ cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_paint (cr); cairo_restore (cr); } maybe_update_shape (widget); label_draw_background_and_frame (widget, cr, FALSE); return FALSE; }
static gboolean gtk_tooltip_paint_window (GtkTooltip *tooltip, cairo_t *cr) { if (gtk_widget_is_composited (tooltip->window)) { /* clear any background */ cairo_save (cr); cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); cairo_restore (cr); } maybe_update_shape (tooltip); paint_background_and_frame (tooltip, cr); return FALSE; }
bool wxTopLevelWindowGTK::CanSetTransparent() { #if GTK_CHECK_VERSION(2,10,0) if (!gtk_check_version(2,10,0)) { return (gtk_widget_is_composited (m_widget)); } else #endif // In case of lower versions than gtk+-2.10.0 we could look for _NET_WM_CM_Sn ourselves { return false; } #if 0 // Don't be optimistic here for the sake of wxAUI int opcode, event, error; // Check for the existence of a RGBA visual instead? return XQueryExtension(gdk_x11_get_default_xdisplay (), "Composite", &opcode, &event, &error); #endif }
static void fill_background (GtkWidget *widget, cairo_t *cr, GdkColor *bg_color, GdkColor *border_color, guchar alpha) { gint tooltip_radius; if (!gtk_widget_is_composited (widget)) alpha = 255; gtk_widget_style_get (widget, "tooltip-radius", &tooltip_radius, NULL); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); draw_round_rect (cr, 1.0, 0.5, 0.5, tooltip_radius, widget->allocation.width - 1, widget->allocation.height - 1); cairo_set_source_rgba (cr, (float) bg_color->red / 65535.0, (float) bg_color->green / 65535.0, (float) bg_color->blue / 65535.0, (float) alpha / 255.0); cairo_fill_preserve (cr); cairo_set_source_rgba (cr, (float) border_color->red / 65535.0, (float) border_color->green / 65535.0, (float) border_color->blue / 65535.0, (float) alpha / 255.0); cairo_set_line_width (cr, 1.0); cairo_stroke (cr); }
static void timeline_frame_cb (GsdTimeline *timeline, gdouble progress, gpointer user_data) { GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; gint cursor_x, cursor_y; if (gtk_widget_is_composited (data->widget)) { gdk_window_invalidate_rect (data->window, NULL, FALSE); data->progress = progress; } else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL) { /* only invalidate window each circle interval */ update_shape (data); gdk_window_invalidate_rect (data->window, NULL, FALSE); data->progress += CIRCLES_PROGRESS_INTERVAL; } // // gdk_window_get_pointer (gdk_screen_get_root_window (screen), // &cursor_x, &cursor_y, NULL); // use gdk_device_get_position instead of gdk_window_get_device_position // 'coz we use root window here. GdkDisplay *display; GdkDeviceManager * device_manager; GdkDevice* pointer_device; display = gdk_window_get_display (data->window); device_manager = gdk_display_get_device_manager (display); pointer_device = gdk_device_manager_get_client_pointer (device_manager); gdk_device_get_position (pointer_device, NULL, &cursor_x, &cursor_y); // gdk_window_move (data->window, cursor_x - WINDOW_SIZE / 2, cursor_y - WINDOW_SIZE / 2); }
void initWidgets(void) { guint i; GtkWidget *hboxWidget = NULL; GdkColor color = myTheme.win_bg_color; // TODO: Typ okna winWidget = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(winWidget), 8); gtk_window_set_title(GTK_WINDOW(winWidget), OBS_TITLE); gtk_widget_set_size_request(winWidget, myTheme.win_size_width, myTheme.win_size_heigh); if (myOptions.composite) gdk_color_parse("black", &color); gtk_widget_modify_bg(winWidget, GTK_STATE_NORMAL, &color); gtk_window_set_decorated(GTK_WINDOW(winWidget), myTheme.win_decor); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(winWidget), TRUE); gtk_window_set_skip_pager_hint(GTK_WINDOW(winWidget), TRUE); GTK_WIDGET_SET_FLAGS(winWidget, GTK_CAN_FOCUS); gtk_widget_set_app_paintable(winWidget, TRUE); if (myTheme.win_pos == T_WIN_POS_CENTER) /* Window position - center */ gtk_window_set_position(GTK_WINDOW(winWidget), GTK_WIN_POS_CENTER); else if (myTheme.win_pos == T_WIN_POS_CUSTOM) { /* Window position - custom */ gtk_window_set_position(GTK_WINDOW(winWidget), GTK_WIN_POS_NONE); gtk_window_move(GTK_WINDOW(winWidget), myTheme.win_pos_x, myTheme.win_pos_y); } if (myTheme.win_size == T_WIN_SIZE_FULLSCREEN) /* Window size - fullscreen */ gtk_window_resize(GTK_WINDOW(winWidget), gdk_screen_get_width(gdk_screen_get_default()), gdk_screen_get_height(gdk_screen_get_default())); else if (myTheme.win_size == T_WIN_SIZE_CUSTOM) /* Window size - custom */ gtk_window_resize(GTK_WINDOW(winWidget), myTheme.win_size_width, myTheme.win_size_heigh); g_signal_connect(winWidget, "destroy", G_CALLBACK(onDestroy), NULL); g_signal_connect(winWidget, "key_press_event", G_CALLBACK(onKeyPress), NULL); g_signal_connect(winWidget, "window_state_event", G_CALLBACK(onWindowStateChange), NULL); g_signal_connect(winWidget, "show", G_CALLBACK(onWindowShow), NULL); if (myOptions.composite) { if (gtk_widget_is_composited(winWidget)) { printMessage(MSG_VERB, "Compositing enabled.\n"); g_signal_connect(winWidget, "expose_event", G_CALLBACK(onExpose), NULL); g_signal_connect(winWidget, "screen-changed", G_CALLBACK(onScreenChanged), NULL); onScreenChanged(winWidget, NULL, NULL); } else { printMessage(MSG_WARN, "No compositing, enabling rendered effects!\n"); myOptions.composite = FALSE; } } else { printMessage(MSG_VERB, "Compositing disabled.\n"); } hboxWidget = gtk_hbox_new(FALSE, 0); hboxButtonWidget = gtk_hbutton_box_new(); /*gtk_hbutton_box_set_spacing_default(10);*/ gtk_box_pack_start(GTK_BOX(hboxWidget), gtk_vbox_new(TRUE, 0), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hboxWidget), hboxButtonWidget, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hboxWidget), gtk_vbox_new(TRUE, 0), TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(winWidget), hboxWidget); if (myOptions.buttons[0] != ACTION_NONE) { for (i = 0; i <= 8; i++) if (myOptions.buttons[i] != ACTION_NONE) addButton(myOptions.buttons[i]); } else { addButton(ACTION_CANCEL); addButton(ACTION_LOGOUT); addButton(ACTION_RESTART); addButton(ACTION_SHUTDOWN); } }
static VALUE rg_composited_p(VALUE self) { return CBOOL2RVAL(gtk_widget_is_composited(_SELF(self))); }
static gboolean gtk_bubble_window_draw (GtkWidget *widget, cairo_t *cr) { GtkStyleContext *context; GtkAllocation allocation; GtkWidget *child; GtkBorder border; GdkRGBA border_color; gint rect_x1, rect_x2, rect_y1, rect_y2; gint initial_x, initial_y, final_x, final_y; gint gap_start, gap_end; GtkPositionType gap_side; GtkStateFlags state; context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); gtk_widget_get_allocation (widget, &allocation); if (gtk_widget_is_composited (widget)) { cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_paint (cr); cairo_restore (cr); } gtk_bubble_window_get_rect_coords (GTK_BUBBLE_WINDOW (widget), &rect_x1, &rect_y1, &rect_x2, &rect_y2); /* Render the rect background */ gtk_render_background (context, cr, rect_x1, rect_y1, rect_x2 - rect_x1, rect_y2 - rect_y1); gtk_bubble_window_get_gap_coords (GTK_BUBBLE_WINDOW (widget), &initial_x, &initial_y, NULL, NULL, &final_x, &final_y, &gap_side); if (POS_IS_VERTICAL (gap_side)) { gap_start = initial_x; gap_end = final_x; } else { gap_start = initial_y; gap_end = final_y; } /* Now render the frame, without the gap for the arrow tip */ gtk_render_frame_gap (context, cr, rect_x1, rect_y1, rect_x2 - rect_x1, rect_y2 - rect_y1, gap_side, gap_start, gap_end); /* Clip to the arrow shape */ cairo_save (cr); gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr); cairo_clip (cr); /* Render the arrow background */ gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height); /* Render the border of the arrow tip */ gtk_style_context_get_border (context, state, &border); if (border.bottom > 0) { gtk_style_context_get_border_color (context, state, &border_color); gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr); gdk_cairo_set_source_rgba (cr, &border_color); cairo_set_line_width (cr, border.bottom); cairo_stroke (cr); } /* We're done */ cairo_restore (cr); child = gtk_bin_get_child (GTK_BIN (widget)); if (child) gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr); return TRUE; }