--- libwnck-2.18.0/libwnck/xutils.h.appearance 2007-03-28 18:37:42.000000000 -0400 +++ libwnck-2.18.0/libwnck/xutils.h 2007-03-28 18:38:33.000000000 -0400 @@ -109,6 +109,16 @@ int x, int y); +void _wnck_change_opacity (Screen *screen, + Window xwindow, + guint32 opacity); +void _wnck_change_saturation (Screen *screen, + Window xwindow, + guint32 saturation); +void _wnck_change_brightness (Screen *screen, + Window xwindow, + guint32 brightness); + char* _wnck_get_session_id (Window xwindow); int _wnck_get_pid (Window xwindow); char* _wnck_get_name (Window xwindow); @@ -117,6 +127,12 @@ char **res_class, char **res_name); +guint32 _wnck_get_opacity (Window xwindow); + +guint32 _wnck_get_saturation (Window xwindow); + +guint32 _wnck_get_brightness (Window xwindow); + void _wnck_select_input (Window xwindow, int mask); --- libwnck-2.18.0/libwnck/window.c.appearance 2007-03-28 18:37:42.000000000 -0400 +++ libwnck-2.18.0/libwnck/window.c 2007-03-28 18:38:33.000000000 -0400 @@ -91,6 +91,10 @@ char *res_class; char *res_name; + guint32 opacity; + guint32 saturation; + guint32 brightness; + /* true if transient_for points to root window, * not another app window */ @@ -134,6 +138,10 @@ guint need_update_startup_id : 1; guint need_update_wmclass : 1; guint need_update_wmhints : 1; + + guint need_update_opacity : 1; + guint need_update_saturation : 1; + guint need_update_brightness : 1; guint need_emit_name_changed : 1; guint need_emit_icon_changed : 1; @@ -146,6 +154,9 @@ ICON_CHANGED, ACTIONS_CHANGED, GEOMETRY_CHANGED, + OPACITY_CHANGED, + SATURATION_CHANGED, + BRIGHTNESS_CHANGED, LAST_SIGNAL }; @@ -174,6 +185,9 @@ static void update_transient_for (WnckWindow *window); static void update_startup_id (WnckWindow *window); static void update_wmclass (WnckWindow *window); +static void update_opacity (WnckWindow *window); +static void update_saturation (WnckWindow *window); +static void update_brightness (WnckWindow *window); static void unqueue_update (WnckWindow *window); static void queue_update (WnckWindow *window); static void force_update_now (WnckWindow *window); @@ -293,6 +307,33 @@ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[OPACITY_CHANGED] = + g_signal_new ("opacity_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (WnckWindowClass, opacity_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[SATURATION_CHANGED] = + g_signal_new ("saturation_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (WnckWindowClass, saturation_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[BRIGHTNESS_CHANGED] = + g_signal_new ("brightness_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (WnckWindowClass, brightness_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -421,6 +462,9 @@ window->priv->need_update_startup_id = TRUE; window->priv->need_update_wmclass = TRUE; window->priv->need_update_wmhints = TRUE; + window->priv->need_update_opacity = TRUE; + window->priv->need_update_saturation = TRUE; + window->priv->need_update_brightness = TRUE; window->priv->need_emit_name_changed = FALSE; window->priv->need_emit_icon_changed = FALSE; force_update_now (window); @@ -1633,6 +1677,77 @@ gravity_and_flags, x, y, width, height); } +guint +wnck_window_get_opacity (WnckWindow *window) +{ + guint64 o; + + g_return_val_if_fail (WNCK_IS_WINDOW (window), 0); + + o = ((guint64) window->priv->opacity * 1005) / G_MAXUINT32; + + return o / 10; +} + +void +wnck_window_set_opacity (WnckWindow *window, + guint opacity) +{ + g_return_if_fail (WNCK_IS_WINDOW (window)); + + _wnck_change_opacity (WNCK_SCREEN_XSCREEN (window->priv->screen), + wnck_window_get_xid (window), + (((guint64) opacity * G_MAXUINT32) / 100)); +} + + +guint +wnck_window_get_saturation (WnckWindow *window) +{ + guint64 o; + + g_return_val_if_fail (WNCK_IS_WINDOW (window), 0); + + o = ((guint64) window->priv->saturation * 1005) / G_MAXUINT32; + + return o / 10; +} + +void +wnck_window_set_saturation (WnckWindow *window, + guint saturation) +{ + g_return_if_fail (WNCK_IS_WINDOW (window)); + + _wnck_change_saturation (WNCK_SCREEN_XSCREEN (window->priv->screen), + wnck_window_get_xid (window), + (((guint64) saturation * G_MAXUINT32) / 100)); +} + + +guint +wnck_window_get_brightness (WnckWindow *window) +{ + guint64 o; + + g_return_val_if_fail (WNCK_IS_WINDOW (window), 0); + + o = ((guint64) window->priv->brightness * 1005) / G_MAXUINT32; + + return o / 10; +} + +void +wnck_window_set_brightness (WnckWindow *window, + guint brightness) +{ + g_return_if_fail (WNCK_IS_WINDOW (window)); + + _wnck_change_brightness (WNCK_SCREEN_XSCREEN (window->priv->screen), + wnck_window_get_xid (window), + (((guint64) brightness * G_MAXUINT32) / 100)); +} + /** * wnck_window_is_visible_on_workspace: * @window: a #WnckWindow @@ -1866,6 +1981,26 @@ window->priv->need_update_wmhints = TRUE; queue_update (window); } + else if (xevent->xproperty.atom == + _wnck_atom_get ("_NET_WM_WINDOW_OPACITY")) + { + window->priv->need_update_opacity = TRUE; + queue_update (window); + } + + else if (xevent->xproperty.atom == + _wnck_atom_get ("_NET_WM_WINDOW_SATURATION")) + { + window->priv->need_update_saturation = TRUE; + queue_update (window); + } + + else if (xevent->xproperty.atom == + _wnck_atom_get ("_NET_WM_WINDOW_BRIGHTNESS")) + { + window->priv->need_update_brightness = TRUE; + queue_update (window); + } } void @@ -2386,6 +2521,39 @@ } static void +update_opacity (WnckWindow *window) +{ + if (!window->priv->need_update_opacity) + return; + + window->priv->need_update_opacity = FALSE; + + window->priv->opacity = _wnck_get_opacity (window->priv->xwindow); +} + +static void +update_saturation (WnckWindow *window) +{ + if (!window->priv->need_update_saturation) + return; + + window->priv->need_update_saturation = FALSE; + + window->priv->saturation = _wnck_get_saturation (window->priv->xwindow); +} + +static void +update_brightness (WnckWindow *window) +{ + if (!window->priv->need_update_brightness) + return; + + window->priv->need_update_brightness = FALSE; + + window->priv->brightness = _wnck_get_brightness (window->priv->xwindow); +} + +static void force_update_now (WnckWindow *window) { WnckWindowState old_state; @@ -2420,6 +2588,9 @@ */ update_workspace (window); /* emits signals */ update_actions (window); + update_opacity (window); + update_saturation (window); + update_brightness (window); get_icons (window); --- libwnck-2.18.0/libwnck/window.h.appearance 2007-03-28 18:37:42.000000000 -0400 +++ libwnck-2.18.0/libwnck/window.h 2007-03-28 18:38:33.000000000 -0400 @@ -149,6 +149,15 @@ /* Changed size/position */ void (* geometry_changed) (WnckWindow *window); + + /* Changed opacity */ + void (* opacity_changed) (WnckWindow *window); + + /* Changed saturation */ + void (* saturation_changed) (WnckWindow *window); + + /* Changed brightness */ + void (* brightness_changed) (WnckWindow *window); }; GType wnck_window_get_type (void) G_GNUC_CONST; @@ -263,6 +272,15 @@ int width, int height); +guint wnck_window_get_opacity (WnckWindow *window); +void wnck_window_set_opacity (WnckWindow *window, guint opacity); + +guint wnck_window_get_saturation (WnckWindow *window); +void wnck_window_set_saturation (WnckWindow *window, guint saturation); + +guint wnck_window_get_brightness (WnckWindow *window); +void wnck_window_set_brightness (WnckWindow *window, guint brightness); + gboolean wnck_window_is_visible_on_workspace (WnckWindow *window, WnckWorkspace *workspace); gboolean wnck_window_is_on_workspace (WnckWindow *window, --- libwnck-2.18.0/libwnck/window-action-menu.c.appearance 2007-03-12 14:48:28.000000000 -0400 +++ libwnck-2.18.0/libwnck/window-action-menu.c 2007-03-28 18:38:33.000000000 -0400 @@ -36,6 +36,10 @@ ABOVE, MOVE, RESIZE, + CHANGE_OPACITY, + CHANGE_SATURATION, + CHANGE_BRIGHTNESS, + RESET, PIN, LEFT, RIGHT, @@ -55,6 +59,11 @@ GtkWidget *above_item; GtkWidget *move_item; GtkWidget *resize_item; + GtkWidget *appearance_item; + GtkWidget *opacity_item; + GtkWidget *saturation_item; + GtkWidget *brightness_item; + GtkWidget *reset_item; GtkWidget *close_item; GtkWidget *workspace_separator; GtkWidget *pin_item; @@ -151,6 +160,46 @@ case RESIZE: wnck_window_keyboard_size (amd->window); break; + case CHANGE_OPACITY: + { + int opacity_value; + + opacity_value = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), + "opacity")); + + wnck_window_set_opacity (amd->window, opacity_value); + break; + } + case CHANGE_SATURATION: + { + int saturation_value; + + saturation_value = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), + "saturation")); + + wnck_window_set_saturation (amd->window, saturation_value); + break; + } + case CHANGE_BRIGHTNESS: + { + int brightness_value; + + brightness_value = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), + "brightness")); + + wnck_window_set_brightness (amd->window, brightness_value); + break; + } + case RESET: + { + wnck_window_set_brightness (amd->window, 100); + wnck_window_set_saturation (amd->window, 100); + wnck_window_set_opacity (amd->window, 100); + break; + } case PIN: if (wnck_window_is_pinned (amd->window)) wnck_window_unpin (amd->window); @@ -250,6 +299,10 @@ WnckWindowActions actions; WnckScreen *screen; + guint present_opacity; + guint present_saturation; + guint present_brightness; + amd->idle_handler = 0; actions = wnck_window_get_actions (amd->window); @@ -297,6 +350,20 @@ gtk_widget_set_sensitive (amd->above_item, (actions & WNCK_WINDOW_ACTION_ABOVE) != 0); + present_opacity = wnck_window_get_opacity (amd->window); + present_saturation = wnck_window_get_saturation (amd->window); + present_brightness = wnck_window_get_brightness (amd->window); + + if (present_opacity == 100 && present_saturation == 100 && present_brightness == 100) + { + gtk_widget_set_sensitive (amd->reset_item, FALSE); + } + else + { + gtk_widget_set_sensitive (amd->reset_item, TRUE); + } + + if (wnck_window_is_pinned (amd->window)) { set_item_text (amd->pin_item, _("_Only on This Workspace")); @@ -525,7 +592,7 @@ GtkWidget* wnck_create_window_action_menu (WnckWindow *window) { - GtkWidget *menu, *submenu; + GtkWidget *menu, *submenu, *submenu2; ActionMenuData *amd; GtkWidget *separator; int num_workspaces, present_workspace, i; @@ -579,6 +646,154 @@ set_item_text (amd->resize_item, _("_Resize")); set_item_stock (amd->move_item, NULL); + if (wnck_screen_net_wm_supports (wnck_window_get_screen (amd->window), + "_NET_WM_WINDOW_OPACITY")) + { + + amd->appearance_item = gtk_menu_item_new_with_mnemonic (_("_Appearance")); + gtk_widget_show (amd->appearance_item); + + submenu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (amd->appearance_item), + submenu); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), amd->appearance_item); + + } + + if (wnck_screen_net_wm_supports (wnck_window_get_screen (amd->window), + "_NET_WM_WINDOW_OPACITY")) + { + guint present_opacity; + gint j; + + amd->opacity_item = gtk_menu_item_new_with_mnemonic (_("_Opacity")); + gtk_widget_show (amd->opacity_item); + + submenu2 = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (amd->opacity_item), + submenu2); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), amd->opacity_item); + + present_opacity = wnck_window_get_opacity (window); + for (j = 0; j < 4; j++) + { + GtkWidget *item; + gchar *label; + guint o; + + label = g_strdup_printf ("%d%%", (j + 1) * 25); + + item = make_menu_item (amd, CHANGE_OPACITY); + + o = (j + 1) * 25; + g_object_set_data (G_OBJECT (item), "opacity", GINT_TO_POINTER (o)); + + if (o == present_opacity) + gtk_widget_set_sensitive (item, FALSE); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu2), item); + + set_item_text (item, label); + set_item_stock (item, NULL); + + g_free (label); + } + } + + if (wnck_screen_net_wm_supports (wnck_window_get_screen (amd->window), + "_NET_WM_WINDOW_SATURATION")) + { + guint present_saturation; + gint j; + + amd->saturation_item = gtk_menu_item_new_with_mnemonic (_("_Saturation")); + gtk_widget_show (amd->saturation_item); + + submenu2 = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (amd->saturation_item), + submenu2); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), amd->saturation_item); + + present_saturation = wnck_window_get_saturation (window); + for (j = 0; j < 4; j++) + { + GtkWidget *item; + gchar *label; + guint o; + + label = g_strdup_printf ("%d%%", (j + 1) * 25); + + item = make_menu_item (amd, CHANGE_SATURATION); + + o = (j + 1) * 25; + g_object_set_data (G_OBJECT (item), "saturation", GINT_TO_POINTER (o)); + + if (o == present_saturation) + gtk_widget_set_sensitive (item, FALSE); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu2), item); + + set_item_text (item, label); + set_item_stock (item, NULL); + + g_free (label); + } + } + + if (wnck_screen_net_wm_supports (wnck_window_get_screen (amd->window), + "_NET_WM_WINDOW_BRIGHTNESS")) + { + guint present_brightness; + gint j; + + amd->brightness_item = gtk_menu_item_new_with_mnemonic (_("_Brightness")); + gtk_widget_show (amd->brightness_item); + + submenu2 = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (amd->brightness_item), + submenu2); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), amd->brightness_item); + + present_brightness = wnck_window_get_brightness (window); + for (j = 0; j < 4; j++) + { + GtkWidget *item; + gchar *label; + guint o; + + label = g_strdup_printf ("%d%%", (j + 1) * 25); + + item = make_menu_item (amd, CHANGE_BRIGHTNESS); + + o = (j + 1) * 25; + g_object_set_data (G_OBJECT (item), "brightness", GINT_TO_POINTER (o)); + + if (o == present_brightness) + gtk_widget_set_sensitive (item, FALSE); + + gtk_menu_shell_append (GTK_MENU_SHELL (submenu2), item); + + set_item_text (item, label); + set_item_stock (item, NULL); + + g_free (label); + } + } + + if (wnck_screen_net_wm_supports (wnck_window_get_screen (amd->window), + "_NET_WM_WINDOW_OPACITY")) + { + amd->reset_item = make_menu_item (amd, RESET); + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), amd->reset_item); + + set_item_text (amd->reset_item, _("_Reset settings")); + } + + separator = gtk_separator_menu_item_new (); gtk_widget_show (separator); gtk_menu_shell_append (GTK_MENU_SHELL (menu), --- libwnck-2.18.0/libwnck/xutils.c.appearance 2007-03-28 18:37:42.000000000 -0400 +++ libwnck-2.18.0/libwnck/xutils.c 2007-03-28 18:38:33.000000000 -0400 @@ -1121,6 +1121,87 @@ &xev); } +void +_wnck_change_opacity (Screen *screen, + Window xwindow, + guint32 opacity) +{ + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = gdk_display; + xev.xclient.window = xwindow; + xev.xclient.message_type = _wnck_atom_get ("_NET_WM_WINDOW_OPACITY"); + xev.xclient.format = 32; + xev.xclient.data.l[0] = opacity; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent (gdk_display, + RootWindowOfScreen (screen), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +void +_wnck_change_saturation (Screen *screen, + Window xwindow, + guint32 saturation) +{ + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = gdk_display; + xev.xclient.window = xwindow; + xev.xclient.message_type = _wnck_atom_get ("_NET_WM_WINDOW_SATURATION"); + xev.xclient.format = 32; + xev.xclient.data.l[0] = saturation; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent (gdk_display, + RootWindowOfScreen (screen), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +void +_wnck_change_brightness (Screen *screen, + Window xwindow, + guint32 brightness) +{ + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = gdk_display; + xev.xclient.window = xwindow; + xev.xclient.message_type = _wnck_atom_get ("_NET_WM_WINDOW_BRIGHTNESS"); + xev.xclient.format = 32; + xev.xclient.data.l[0] = brightness; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent (gdk_display, + RootWindowOfScreen (screen), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + char* _wnck_get_session_id (Window xwindow) { @@ -1241,6 +1322,45 @@ } } +guint32 +_wnck_get_opacity (Window xwindow) +{ + int val; + + if (_wnck_get_cardinal (xwindow, + _wnck_atom_get ("_NET_WM_WINDOW_OPACITY"), + &val)) + return val; + + return G_MAXUINT32; +} + +guint32 +_wnck_get_saturation (Window xwindow) +{ + int val; + + if (_wnck_get_cardinal (xwindow, + _wnck_atom_get ("_NET_WM_WINDOW_SATURATION"), + &val)) + return val; + + return G_MAXUINT32; +} + +guint32 +_wnck_get_brightness (Window xwindow) +{ + int val; + + if (_wnck_get_cardinal (xwindow, + _wnck_atom_get ("_NET_WM_WINDOW_BRIGHTNESS"), + &val)) + return val; + + return G_MAXUINT32; +} + void _wnck_select_input (Window xwindow, int mask)