]> Eric's Git Repo - ericdock.git/commitdiff
main and eric_window.h changes
authorEricDWertz <EricDWertz@gmail.com>
Mon, 19 Sep 2016 14:18:51 +0000 (10:18 -0400)
committerEricDWertz <EricDWertz@gmail.com>
Mon, 19 Sep 2016 14:18:51 +0000 (10:18 -0400)
eric_window.h
main.c

index 16e5b263663bea7eed437d87f229a2ed40147a06..155b76eff692155420981c25dc5b768a794bc8d1 100644 (file)
@@ -1,10 +1,9 @@
+#pragma once
 /*
  * eric_window.h
  * creates a transluscent window using the current theme color
  */
 
-#pragma once
-
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 #include <gio/gio.h>
  * TODO: add text color
  */
 
-typedef struct
+typedef struct eric_window eric_window;
+struct eric_window
 {
     GtkWidget* window;
     GdkRGBA background_color;
     GdkRGBA background_color_old;
     GdkRGBA background_color_new;
+    GdkRGBA text_color;
+    GdkRGBA text_color_old;
+    GdkRGBA text_color_new;
     double background_change_percentage;
-} eric_window;
+    gboolean (*draw_callback)( GtkWidget* widget, cairo_t* cr, eric_window* w );
+};
+
+double gdk_rgba_get_luminance( GdkRGBA *color )
+{
+       return  ( color->red ) * 0.2126 +
+               ( color->green ) * 0.7152 +
+               ( color->blue ) * 0.0722;
+}
 
 static void gdk_color_lerp( GdkRGBA* c1, GdkRGBA* c2, double s, GdkRGBA* out )
 {
@@ -38,6 +49,8 @@ static gboolean eric_window_animation_timer( eric_window* w )
        w->background_change_percentage += 0.05;
        gdk_color_lerp( &w->background_color_old, &w->background_color_new, 
                         w->background_change_percentage, &w->background_color);
+       gdk_color_lerp( &w->text_color_old, &w->text_color_new, 
+                        w->background_change_percentage, &w->text_color);
        gtk_widget_queue_draw( w->window );
 
        if( w->background_change_percentage >= 1.0 ) return FALSE;
@@ -52,7 +65,10 @@ static gboolean eric_window_draw( GtkWidget* widget, cairo_t* cr, eric_window* w
        gdk_cairo_set_source_rgba( cr, &w->background_color );
        cairo_paint( cr );      
        
-    return FALSE;
+    if( w->draw_callback == NULL )
+        return FALSE;
+    else
+        return w->draw_callback( widget, cr, w );
 }
 
 
@@ -75,6 +91,11 @@ void eric_window_gsettings_value_changed( GSettings *settings, const gchar *key,
     {
         w->background_color_old = w->background_color;
         gdk_rgba_parse( &w->background_color_new, g_settings_get_string( settings, "primary-color" ) );
+        w->text_color_old = w->text_color;
+        if( gdk_rgba_get_luminance( &w->background_color_new ) > 0.5 )
+            gdk_rgba_parse( &w->text_color_new, "#000000" );
+        else
+            gdk_rgba_parse( &w->text_color_new, "#FFFFFF" );
         
         w->background_change_percentage = 0.0;
         g_timeout_add( 32, (gpointer)eric_window_animation_timer, w );
@@ -84,6 +105,7 @@ void eric_window_gsettings_value_changed( GSettings *settings, const gchar *key,
 eric_window* eric_window_create( int width, int height, char* title )
 {
     eric_window* w = malloc( sizeof( eric_window ) );
+    w->draw_callback = NULL;
 
     if( title == NULL )
         title = "eric window";
@@ -117,6 +139,10 @@ eric_window* eric_window_create( int width, int height, char* title )
 
     g_signal_connect_data( gsettings, "changed", G_CALLBACK( eric_window_gsettings_value_changed ), (gpointer)w, 0, 0 );
     gdk_rgba_parse( &w->background_color, g_settings_get_string( gsettings, "primary-color" ) );
+    if( gdk_rgba_get_luminance( &w->background_color ) > 0.5 )
+        gdk_rgba_parse( &w->text_color, "#000000" );
+    else
+        gdk_rgba_parse( &w->text_color, "#FFFFFF" );
 
     return w;
 }
diff --git a/main.c b/main.c
index 3dab4513c360cfd7aac5f1212139752ad2d01167..6dba789988df3dc81adf3bb1864ef56d15809443 100644 (file)
--- a/main.c
+++ b/main.c
 #include <gdk/gdkx.h>
 #include <X11/Xlib.h>
+#include <math.h>
 
 #define WNCK_I_KNOW_THIS_IS_UNSTABLE
 #include <libwnck/libwnck.h>
 
 #include "eric_window.h"
 
+#define ERIC_DOCK_FONT "Source Sans Pro Regular" 
+#define ERIC_DOCK_TOOLTIP_SHADOW_RADIUS 16.0
+#define ERIC_DOCK_TOOLTIP_WIDTH ERIC_DOCK_TOOLTIP_SHADOW_RADIUS + 320.0
+#define ERIC_DOCK_TOOLTIP_ITEM_HEIGHT 24.0
+#define UI_SCALE 1.0
+#define SCALE_VALUE(x) (x)*UI_SCALE
+
+#define ICON_STATE_NORMAL 0
+#define ICON_STATE_HOVER 1
+#define ICON_STATE_ACTIVE 2
+
+GList* dock_icons = NULL;
+eric_window* dock_window = NULL;
+
+//Structure to hold actual pager items
+#include "pager_item.h"
+
+//Stucture to hold class groups... which are icons on the dock
+//Will need to have support for launchers and stuff in the future
+#include "dock_icon.h"
+
+#include "tooltip_window.h"
+
+//Logic to add a window to the pager items.
+//If a matching class group already exists it will be added to that, otherwise create
+//a new class group and add the window to that.
+void add_window_to_pager( WnckWindow* window )
+{
+    GList* icon_list;
+    int found_class_group = 0;
+    dock_icon *icon, *new_dock_icon;
+
+    WnckClassGroup* class = wnck_window_get_class_group( window );
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        icon = (dock_icon*)icon_list->data;
+        if( icon->class_group == class )
+        {
+            icon->pager_items = g_list_append( icon->pager_items, pager_item_create( window ) );
+            found_class_group = 1;
+            break;
+        }
+    }
+
+    if( !found_class_group )
+    {
+        //Add a new dock item
+        new_dock_icon = dock_icon_create( class );
+        new_dock_icon->pager_items = g_list_append( 
+            new_dock_icon->pager_items,
+            pager_item_create( window )
+        );
+
+        dock_icons = g_list_append( dock_icons, new_dock_icon );
+    }
+}
+
+dock_icon* get_dock_icon_at_position( int pos )
+{
+    GList* icon_list;
+    int i = 0;
+
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        if( i == pos )
+            return (dock_icon*)icon_list->data;
+        i++;
+    }
+    return NULL;
+}
+
 GdkFilterReturn handle_x11_event( GdkXEvent *xevent, GdkEvent *event, gpointer data )
 {
     XEvent* xev = (XEvent*)xevent;
+    dock_icon* icon;
+    pager_item* item;
+
+    Display* dpy = GDK_DISPLAY_XDISPLAY( gdk_display_get_default() );
+
     if( xev->type == KeyPress )
     {
-        printf( "Got a key press event!\n" );
+        if( xev->xkey.keycode == 133 || xev->xkey.keycode == 134 )
+        {
+            printf( "Got a super key press event!\n" );
+        }
+        else
+        {
+            printf( "Got a number key press event!\n" );
+
+            icon = get_dock_icon_at_position( xev->xkey.keycode - 10 );
+            if( icon )
+            {
+                dock_icon_activate( icon, xev->xkey.time, FALSE );
+            }
+        }
+    }
+    if( xev->type == KeyRelease )
+    {
+        if( xev->xkey.keycode >= 10 && xev->xkey.keycode <= 20 )
+        {
+            printf( "Got a number key release event!\n" );
+        }
+        else
+        {
+            if( xev->xkey.keycode == 133 || xev->xkey.keycode == 134 )
+            {
+                printf( "Got a super key release event!\n" );
+                tooltip_window_hide();
+            }
+            else
+            {
+                printf( "Flusing events\n" );
+                XAllowEvents( dpy, ReplayKeyboard, xev->xkey.time );
+                XFlush( dpy );
+            }
+        }
     }
 
     return GDK_FILTER_CONTINUE;
 }
 
-int main( int argc, char* argv[] )
+static gboolean draw_dock_window( GtkWidget* widget, cairo_t* cr, eric_window* w )
 {
-    int i;
+    GList* icon_list = dock_icons;
+    dock_icon* icon;
+    double x, y;
+    double rx, ry, width;
+    int i, pager_count, icon_count;
+    
+    icon_count = g_list_length( dock_icons );
+    x = floor( 960.0 - SCALE_VALUE( 47.0 * (double)icon_count / 2.0 ) );
+    y = SCALE_VALUE( 5.0 );
+    cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        icon = (dock_icon*)icon_list->data;
 
-    gtk_init( &argc, &argv );
+        w->text_color.alpha = 0.25;
+        gdk_cairo_set_source_rgba( cr, &w->text_color );
+        if( icon->icon_state == ICON_STATE_HOVER )
+        {
+            draw_rounded_rect( cr, x, y-SCALE_VALUE( 2.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 2.0 ) );
+            cairo_fill( cr );
+        }
+        if( icon->is_active )
+        {
+            draw_rounded_rect( cr, x, y-SCALE_VALUE( 2.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 2.0 ) );
+            cairo_fill( cr );
+        }
+        if( !GDK_IS_PIXBUF( icon->icon_pixbuf ) )
+            icon->icon_pixbuf = wnck_class_group_get_icon( icon->class_group );
+        gdk_cairo_set_source_pixbuf( cr, icon->icon_pixbuf, x+SCALE_VALUE( 4.0 ), y );
+        cairo_paint( cr );
 
-    eric_window* w = eric_window_create( 1920, 40, "" );
-    gtk_window_move( GTK_WINDOW( w->window ), 0, 1040 );
-    gtk_window_set_type_hint( GTK_WINDOW( w->window ), GDK_WINDOW_TYPE_HINT_DOCK );
+        pager_count = g_list_length( icon->pager_items );
+        if( pager_count > 0 )
+        {
+            //Draw rectangles
+            width = (SCALE_VALUE(32.0) / pager_count );  
+            rx = x + SCALE_VALUE(4.0);
+            ry = y + SCALE_VALUE(34.0);
+            w->text_color.alpha = 0.5;
+            gdk_cairo_set_source_rgba( cr, &w->text_color );
+            for( i = 0; i < pager_count; i++ )
+            {
+                cairo_rectangle( cr, rx+SCALE_VALUE( 1.0 ), ry, width-SCALE_VALUE( 2.0 ), SCALE_VALUE( 4.0 ) );
+                rx += width;
+            }
+            cairo_fill( cr );
+        }
+        icon->x = x;
+        icon->y = y;
 
-    gtk_widget_show_all( w->window );
+        x += SCALE_VALUE( 47.0 );
+    }
+    return FALSE;
+}
 
+void grab_keys()
+{
+    int i;
     Display* dpy = GDK_DISPLAY_XDISPLAY( gdk_display_get_default() );
     Window xwin = RootWindow( dpy, DefaultScreen( dpy ) );
 
@@ -38,19 +197,189 @@ int main( int argc, char* argv[] )
         XGrabKey( dpy, i, Mod4Mask | Mod2Mask, xwin, True, GrabModeAsync, GrabModeAsync );
         XGrabKey( dpy, i, Mod4Mask, xwin, True, GrabModeAsync, GrabModeAsync );
     }
+    XGrabKey( dpy, 133, AnyModifier, xwin, True, GrabModeAsync, GrabModeAsync );
+    XGrabKey( dpy, 134, AnyModifier, xwin, True, GrabModeAsync, GrabModeAsync );
 
     gdk_window_add_filter( NULL, handle_x11_event, NULL );
+}
+
+gboolean window_mouse_move( GtkWidget* widget, GdkEvent* event, gpointer user )
+{
+    double mx, my;
+    double it, ib, il, ir;
+    int old_state, state_changed;
+    dock_icon* icon;
+    pager_item* item;
+    GList *icon_list, *item_list;
+    GdkEventMotion* e = (GdkEventMotion*)event;
+
+    mx = e->x;
+    my = e->y;
+    if( widget == dock_window->window )
+    {
+        for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+        {
+            icon = (dock_icon*)icon_list->data;
+            old_state = icon->icon_state;
+            it = 0; ib = SCALE_VALUE( 48 ); 
+            il = icon->x; ir = icon->x + SCALE_VALUE( 42 );
+            if( il < mx && mx < ir && it < my && my < ib )
+            {
+                icon->icon_state = ICON_STATE_HOVER;
+            }
+            else
+            {
+                icon->icon_state = ICON_STATE_NORMAL;
+            }
+            if( old_state != icon->icon_state )
+                state_changed = 1;
+
+            if( state_changed )
+                gtk_widget_queue_draw( dock_window->window );
+        }
+    }
 
+    return FALSE;
+}
+
+void dock_window_mouse_down( GtkWidget* widget, GdkEvent* event, gpointer user )
+{
+    GdkEventButton* e = (GdkEventButton*)event;
+    if( e->button != 1 )
+        return;
+
+    double mx, my;
+    double it, ib, il, ir;
+    dock_icon* icon;
+    pager_item* item;
+    GList* icon_list;
+    int pager_count;
+
+    mx = e->x; my = e->y;
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        icon = (dock_icon*)icon_list->data;
+        dock_icon_mouse_down( icon, mx, my, e->time );
+    }
+}
+
+void setup_dock_window()
+{
+    GdkScreen* screen = gdk_screen_get_default();
+    int mon = gdk_screen_get_primary_monitor( screen );
+    GdkRectangle mon_geom;
+    gdk_screen_get_monitor_geometry( screen, mon, &mon_geom );
+    int sw, sh;
+    sw = mon_geom.width;
+    sh = mon_geom.height;
+
+    dock_window = eric_window_create( sw, 48 * UI_SCALE, "" );
+    gtk_window_move( GTK_WINDOW( dock_window->window ), 0, sh - 48 * UI_SCALE );
+    gtk_window_set_type_hint( GTK_WINDOW( dock_window->window ), GDK_WINDOW_TYPE_HINT_DOCK );
+
+    dock_window->draw_callback = draw_dock_window;
+
+    gtk_widget_add_events( dock_window->window, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK );
+    g_signal_connect( G_OBJECT( dock_window->window ), "motion-notify-event", G_CALLBACK(window_mouse_move), NULL );
+    g_signal_connect( G_OBJECT( dock_window->window ), "button-press-event", G_CALLBACK(dock_window_mouse_down), NULL );
+
+    gtk_widget_show_now( dock_window->window );
+}
+
+static void wnck_window_opened( WnckScreen* screen, WnckWindow* window, gpointer data )
+{
+    if( !wnck_window_is_skip_pager( window ) && !wnck_window_is_skip_tasklist( window ) )
+    {
+        add_window_to_pager( window );
+        gtk_widget_queue_draw( dock_window->window );
+    }
+}
+
+static void wnck_window_closed( WnckScreen* screen, WnckWindow* window, gpointer data )
+{
+    GList *icon_list, *pager_list;
+    dock_icon* icon;
+    pager_item* item;
+
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        icon = (dock_icon*)icon_list->data;
+        for( pager_list = icon->pager_items; pager_list != NULL; pager_list = pager_list->next )
+        {
+            item = (pager_item*)pager_list->data;
+            if( item->window == window )
+            {
+                icon->pager_items = g_list_remove( icon->pager_items, item );
+                free( item );
+                printf( "Removed pager item\n" );
+                break;
+            }
+        }
+        if( icon->pager_items == NULL )
+        {
+            dock_icons = g_list_remove( dock_icons, icon );
+            free( icon );
+            printf( "Removed dock icon\n" );
+            break;
+        }
+    }
+    gtk_widget_queue_draw( dock_window->window );
+}
+
+static void wnck_active_window_changed( WnckScreen* screen, WnckWindow* prev_window, gpointer user )
+{
+    GList *icon_list, *pager_list;
+    dock_icon* icon;
+    pager_item* item;
+    WnckWindow* active = wnck_screen_get_active_window( screen );
+    int old_state, state_changed;
+    int has_active;
+
+    state_changed = 0;
+    for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next )
+    {
+        icon = (dock_icon*)icon_list->data;
+        old_state = icon->is_active;
+        has_active = 0;
+        for( pager_list = icon->pager_items; pager_list != NULL; pager_list = pager_list->next )
+        {
+            item = (pager_item*)pager_list->data;
+            if( item->window == active )
+            {
+                has_active = 1;
+                break;
+            }
+        }
+        if( has_active )
+            icon->is_active = 1;
+        else
+            icon->is_active = 0;
+
+        if( icon->is_active != old_state )
+            state_changed = 1; 
+    }
+    if( state_changed )
+        gtk_widget_queue_draw( dock_window->window );
+}
+
+void init_wnck()
+{
     WnckScreen* screen;
     GList* window_list;
     screen = wnck_screen_get_default();
-    wnck_screen_force_update( screen );
+    g_signal_connect( screen, "window-opened", G_CALLBACK( wnck_window_opened ), NULL );
+    g_signal_connect( screen, "window-closed", G_CALLBACK( wnck_window_closed ), NULL );
+    g_signal_connect( screen, "active-window-changed", G_CALLBACK( wnck_active_window_changed ), NULL );
+}
 
-    for( window_list = wnck_screen_get_windows( screen ); window_list != NULL; window_list = window_list->next )
-    {
-        WnckWindow* window = WNCK_WINDOW( window_list->data );
-        printf( "%s%s\n", wnck_window_get_name( window ), wnck_class_group_get_name( wnck_window_get_class_group( window ) ) );
-    }
+int main( int argc, char* argv[] )
+{
+    gtk_init( &argc, &argv );
+
+    setup_dock_window();
+    tooltip_window_create( dock_window->window );
+    grab_keys();
+    init_wnck();
 
     gtk_main();
     return 0;