Add auto-hide animation for GTK desktop panel

  For add auto-hide animation for GTK desktop panel, the key word is gdk_window_move() and set widget as GDK_WINDOW_TYPE_HINT_DOCK(or use Xlib to set Atom). For fix the panel icon filcker we have to use gdk_window_set_back_pixmap().

 

gdk-move.c:

/**
* gcc -g -o gdk-move gdk-move.c `pkg-config gtk+-2.0 --cflags --libs gthread-2.0`
*/

#include <gtk/gtk.h>

guint animation_hidden = 0;
guint animation_show = 0;
gboolean hidden = FALSE;
gboolean processing = FALSE;
int y_pos = 0;

gboolean
panel_toplevel_animation_show (GtkWidget *toplevel)
{
    y_pos += 1;
    if (y_pos <= 0) {
      processing = TRUE;
      gdk_window_move (toplevel->window, toplevel->allocation.x, y_pos);
    } else {
      y_pos = 0;
      processing = FALSE;
      hidden = FALSE;
      return FALSE;
    }
    //g_message ("show %d", y_pos);
    return TRUE;
}

gboolean
panel_toplevel_animation_hidden (GtkWidget *toplevel)
{
    y_pos -= 1;
    if (toplevel->allocation.height + y_pos > 1) {
      processing = TRUE;
      gdk_window_move (toplevel->window, toplevel->allocation.x, y_pos);
    } else {
      processing = FALSE;
      hidden = TRUE;
      return FALSE;
    }
    //g_message ("hidden %d", y_pos);
    return TRUE;
}

void panel_hidden (GtkWidget *widget)
{
    animation_hidden = g_timeout_add (20, (GSourceFunc) panel_toplevel_animation_hidden, widget);
}

void panel_show (GtkWidget *widget)
{
    animation_show = g_timeout_add (20, (GSourceFunc) panel_toplevel_animation_show, widget);
}

gboolean enter_event (GtkWidget         *widget,
                      GdkEventCrossing  *event,
                      gpointer           data)
{
    if (!processing && hidden && event->detail != GDK_NOTIFY_INFERIOR) {
        g_message ("show");
        panel_show (widget);
    }
    return FALSE;
}

gboolean leave_event (GtkWidget         *widget,
                      GdkEventCrossing  *event,
                      gpointer           data)
{
    if (!processing && !hidden && event->detail != GDK_NOTIFY_INFERIOR){
        g_message ("hidden");
        panel_hidden (widget);
    }

    return FALSE;
}

void size_allocate (GtkWidget     *widget,
                    GtkAllocation *allocation,
                    gpointer       user_data)
{
  g_message ("size_allocate");
}

void size_request (GtkWidget      *widget,
                   GtkRequisition *requisition,
                   gpointer        user_data)   
{
  g_message ("size_request");
}

gboolean expose_event (GtkWidget      *widget,
                       GdkEventExpose *event,
                       gpointer        user_data)
{
  g_message ("expose_event");
  return FALSE;
}

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;
    GtkWidget *box;

    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DOCK);
    gtk_window_set_default_size (GTK_WINDOW (window), gdk_screen_get_width (gdk_screen_get_default ()), 100);

    box = gtk_vbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (window), box);
    GtkWidget *image = gtk_image_new_from_file ("/home/john/Pictures/test.png");
    gtk_box_pack_start (GTK_BOX(box), image, TRUE, TRUE, 0);
  
    gtk_widget_set_double_buffered (window, FALSE);
  
    g_signal_connect (G_OBJECT (window), "size_allocate",
                      G_CALLBACK (size_allocate), NULL);
    g_signal_connect (G_OBJECT (window), "size-request",
                      G_CALLBACK (size_request), NULL);
    g_signal_connect (G_OBJECT (window), "expose-event",
                      G_CALLBACK (expose_event), NULL);
    g_signal_connect (G_OBJECT (window), "enter_notify_event",
                      G_CALLBACK (enter_event), NULL);
    g_signal_connect (G_OBJECT (window), "leave_notify_event",
                      G_CALLBACK (leave_event), NULL);

    gtk_widget_show_all (window);
    gdk_window_set_back_pixmap(window->window,NULL,FALSE);
    gtk_main ();

    return 0;
}

 

 

use Xlib to set window as DOCK(from gnome-panel-2.30.0):

 

static Atom net_wm_window_type        = None;
static Atom net_wm_window_type_dock   = None;
static Atom net_wm_window_type_normal = None;

void
panel_xutils_set_window_type (GdkWindow             *gdk_window,
                              PanelXUtilsWindowType  type)
{
        Display *display;
        Window   window;
        Atom     atoms [2];
        int      i = 0;

        g_return_if_fail (GDK_IS_WINDOW (gdk_window));

        display = GDK_WINDOW_XDISPLAY (gdk_window);
        window  = GDK_WINDOW_XWINDOW (gdk_window);

        if (net_wm_window_type == None)
                net_wm_window_type = XInternAtom (display,
                                                  "_NET_WM_WINDOW_TYPE",
                                                  False);

        switch (type) {
        case PANEL_XUTILS_TYPE_DOCK:
                if (net_wm_window_type_dock == None)
                        net_wm_window_type_dock = XInternAtom (display,
                                                               "_NET_WM_WINDOW_TYPE_DOCK",
                                                               False);
                atoms [i++] = net_wm_window_type_dock;
                break;
        case PANEL_XUTILS_TYPE_NORMAL:
                if (net_wm_window_type_normal == None)
                        net_wm_window_type_normal = XInternAtom (display,
                                                                 "_NET_WM_WINDOW_TYPE_NORMAL",
                                                                 False);
                atoms [i++] = net_wm_window_type_normal;
                break;
        default:
                g_assert_not_reached ();
                break;
        }

        gdk_error_trap_push ();
        XChangeProperty (display, window, net_wm_window_type,
                         XA_ATOM, 32, PropModeReplace,
                         (guchar *) &atoms, i);
        gdk_error_trap_pop ();
}
 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(.net,gcc)