Changeset 398


Ignore:
Timestamp:
12/12/06 16:37:18 (6 years ago)
Author:
mickey
Message:

mokoui: add logics for keeping track of the current window.
NOTE: this logics is taken from Maemo and under construction

Location:
trunk/src/target/OM-2007/openmoko-libs/libmokoui
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/target/OM-2007/openmoko-libs/libmokoui/moko-application.c

    r355 r398  
    33 * 
    44 *  Authored By Michael 'Mickey' Lauer <mlauer@vanille-media.de> 
     5 *  Based on hildon-program.c (C) 2006 Nokia Corporation. 
    56 * 
    67 *  Copyright (C) 2006 First International Computer Inc. 
     
    4243typedef struct _MokoApplicationPrivate 
    4344{ 
    44     //FIXME hildon cruft, do we need all this? 
    4545    gboolean killable; 
    4646    gboolean is_topmost; 
     
    4949    GtkWidget *common_filter_menu; 
    5050    GtkWidget *common_toolbar; 
    51     GSList *windows; 
     51    GSList *windows; // all windows belonging to this application 
    5252    Window window_group; 
    5353    gchar *name; 
     
    6363    PROP_0, 
    6464    PROP_IS_TOPMOST, 
    65     PROP_KILLABLE 
     65    PROP_KILLABLE, 
    6666}; 
    6767 
     
    8585                                      NULL ); 
    8686#endif 
    87  
    88     // cruft necessary? 
    8987    priv->killable = FALSE; 
    9088    priv->window_count = 0; 
     
    9290    priv->window_group = GDK_WINDOW_XID(gdk_display_get_default_group(gdk_display_get_default())); 
    9391    priv->common_application_menu = NULL; 
    94     priv->common_toolbar = NULL; 
     92    priv->common_filter_menu = NULL; 
    9593    priv->common_toolbar = NULL; 
    9694    priv->name = NULL; 
     
    187185} 
    188186 
     187/* Utilities */ 
     188static gint 
     189moko_application_window_list_compare(gconstpointer window_a, gconstpointer window_b) 
     190{ 
     191    g_return_val_if_fail( 1, MOKO_IS_WINDOW(window_a) && MOKO_IS_WINDOW(window_b) ); 
     192    return window_a != window_b; 
     193} 
     194/* 
     195 * foreach function, checks if a window is topmost and acts consequently 
     196 */ 
     197static void 
     198moko_application_list_is_is_topmost(gpointer data, gpointer window_id_) 
     199{ 
     200    if ( data && MOKO_IS_WINDOW (data) ) 
     201    { 
     202        MokoWindow *window = MOKO_WINDOW(data); 
     203        Window window_id = * (Window*)window_id_; 
     204        moko_window_update_topmost(window, window_id); 
     205    } 
     206} 
     207 
     208/* 
     209 * Check the _MB_CURRENT_APP_WINDOW on the root window, and update 
     210 * the top_most status accordingly 
     211 */ 
     212static void 
     213moko_application_update_top_most(MokoApplication* self) 
     214{ 
     215    moko_debug( "moko_application_update_top_most" ); 
     216    moko_debug( "-- status has changed for '%s'", g_get_application_name() ); 
     217 
     218    MokoApplicationPrivate* priv = MOKO_APPLICATION_GET_PRIVATE(self); 
     219    Window active_window = moko_window_get_active_window(); 
     220 
     221    if (active_window) 
     222    { 
     223        XWMHints *wm_hints = XGetWMHints(GDK_DISPLAY(), active_window); 
     224 
     225        if (wm_hints) 
     226        { 
     227 
     228            if (wm_hints->window_group == priv->window_group) 
     229            { 
     230                if (!priv->is_topmost) 
     231                { 
     232                    moko_debug( "-- '%s' is now topmost :)", g_get_application_name() ); 
     233                    priv->is_topmost = TRUE; 
     234                    g_object_notify(G_OBJECT(self), "is-topmost"); 
     235                } 
     236            } 
     237            else if (priv->is_topmost) 
     238            { 
     239                moko_debug( "-- '%s' is no longer topmost :(", g_get_application_name() ); 
     240                priv->is_topmost = FALSE; 
     241                g_object_notify(G_OBJECT(self), "is-topmost"); 
     242            } 
     243        } 
     244        XFree (wm_hints); 
     245    } 
     246 
     247    /* Check each window if it was is_topmost */ 
     248    g_slist_foreach(priv->windows, (GFunc)moko_application_list_is_is_topmost, &active_window); 
     249} 
     250 
    189251/* Event filter */ 
    190  
    191252/* 
    192253 * We keep track of the _MB_CURRENT_APP_WINDOW property on the root window, 
     
    194255 * is based on the window group WM hint. 
    195256 */ 
    196 static GdkFilterReturn moko_application_root_window_event_filter( 
    197         GdkXEvent *xevent, 
    198         GdkEvent *event, 
    199         gpointer data) 
    200 { 
     257static GdkFilterReturn 
     258moko_application_root_window_event_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data) 
     259{ 
     260    moko_debug( "moko_application_root_window_event_filter" ); 
     261 
    201262    XAnyEvent *eventti = xevent; 
    202     MokoApplication *program = MOKO_APPLICATION (data); 
    203     Atom active_app_atom = 
    204             XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False); 
     263    MokoApplication *program = MOKO_APPLICATION(data); 
     264    Atom active_app_atom = XInternAtom( GDK_DISPLAY(), "_MB_CURRENT_APP_WINDOW", False ); 
    205265 
    206266    if (eventti->type == PropertyNotify) 
    207267    { 
    208         XPropertyEvent *pevent = xevent; 
     268        XPropertyEvent* pevent = xevent; 
     269        moko_debug( "-- got PropertyNotify for Atom '%s'", XGetAtomName( GDK_DISPLAY(), pevent->atom ) ); 
    209270 
    210271        if (pevent->atom == active_app_atom) 
    211272        { 
    212             g_warning( "NYI: moko_application_update_top_most(program)" ); 
    213             //moko_application_update_top_most( program ); 
     273            moko_debug( "-- ActiveAppAtom" ); 
     274            moko_application_update_top_most( program ); 
    214275        } 
    215276    } 
    216  
    217277    return GDK_FILTER_CONTINUE; 
    218278} 
     
    237297    return program; 
    238298} 
     299 
     300void 
     301moko_application_add_window(MokoApplication* self, MokoWindow* window) 
     302{ 
     303    MokoApplicationPrivate *priv = MOKO_APPLICATION_GET_PRIVATE(self); 
     304 
     305    g_return_if_fail (self && MOKO_IS_APPLICATION (self)); 
     306 
     307    if ( g_slist_find_custom(priv->windows, window, moko_application_window_list_compare) ) 
     308    { 
     309        /* We already have that window */ 
     310        g_warning( "moko_application_add_window: window added twice, fix your program" ); 
     311        return; 
     312    } 
     313 
     314    if (!priv->window_count) 
     315    { 
     316        moko_debug( "need to update top most window now..." ); 
     317        /* program_update_top_most (self); */ 
     318 
     319        /* Now that we have a window we should start keeping track of 
     320         * the root window */ 
     321        gdk_window_set_events( gdk_get_default_root_window(), gdk_window_get_events(gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK); 
     322        gdk_window_add_filter( gdk_get_default_root_window(), moko_application_root_window_event_filter, self ); 
     323    } 
     324 
     325    /*window_set_can_hibernate_property (window, &priv->killable);*/ 
     326    /*_window_set_program (window, G_OBJECT (self));*/ 
     327 
     328    priv->windows = g_slist_append (priv->windows, window); 
     329    priv->window_count ++; 
     330} 
     331 
    239332 
    240333/** moko_application_get_main_window 
     
    258351    priv->main_window = window; 
    259352    //FIXME g_object_ref the window? 
     353} 
     354/** 
     355 * moko_application_get_is_topmost 
     356 * @returns whether one of the program's windows or dialogs is currently 
     357 * activated by the window manager. 
     358 **/ 
     359gboolean 
     360moko_application_get_is_topmost(MokoApplication* self) 
     361{ 
     362    g_return_val_if_fail(self && MOKO_IS_APPLICATION(self), FALSE); 
     363    MokoApplicationPrivate* priv = MOKO_APPLICATION_GET_PRIVATE(self); 
     364    return priv->is_topmost; 
    260365} 
    261366 
  • trunk/src/target/OM-2007/openmoko-libs/libmokoui/moko-dialog-window.c

    r355 r398  
    2626#include <glib/gmain.h> 
    2727 
    28 #undef DEBUG_THIS_FILE 
     28#define DEBUG_THIS_FILE 
    2929#ifdef DEBUG_THIS_FILE 
    3030#define moko_debug(fmt,...) g_debug(fmt,##__VA_ARGS__) 
     
    143143    { 
    144144        gtk_window_set_transient_for( GTK_WINDOW(self), parent ); 
     145#ifndef DEBUG_THIS_FILE 
    145146        gtk_window_set_modal( GTK_WINDOW(self), TRUE ); 
     147#endif 
    146148        gtk_window_set_destroy_with_parent( GTK_WINDOW(self), TRUE ); 
    147149    } 
     
    202204    g_object_ref (dialog); 
    203205 
     206#ifndef DEBUG_THIS_FILE 
    204207    was_modal = GTK_WINDOW (dialog)->modal; 
    205208    if (!was_modal) 
    206209        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); 
     210#endif 
    207211 
    208212    if (!GTK_WIDGET_VISIBLE (dialog)) 
  • trunk/src/target/OM-2007/openmoko-libs/libmokoui/moko-finger-wheel.c

    r361 r398  
    8181moko_finger_wheel_class_init(MokoFingerWheelClass *klass) 
    8282{ 
    83     GObjectClass *object_class = G_OBJECT_CLASS (klass); 
     83    GObjectClass *object_class = G_OBJECT_CLASS(klass); 
    8484    parent_class = g_type_class_peek_parent(klass); 
    8585 
    8686    /* register private data */ 
    87     g_type_class_add_private (klass, sizeof (MokoFingerWheelPrivate)); 
     87    g_type_class_add_private( klass, sizeof(MokoFingerWheelPrivate) ); 
    8888 
    8989    /* hook virtual methods */ 
     
    180180    gint attributes_mask; 
    181181 
    182     GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); 
     182    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); 
    183183 
    184184    attributes.window_type = GDK_WINDOW_CHILD; 
     
    211211    { 
    212212        priv->popup = gtk_window_new(GTK_WINDOW_POPUP); 
     213        //gtk_window_set_decorated( priv->popup, FALSE ); 
    213214        //FIXME Setting it to transparent is probably not necessary since we issue a mask anyway, right? 
    214215        //gtk_widget_set_name( GTK_WIDGET(priv->popup), "transparent" ); 
     
    348349{ 
    349350    moko_debug( "moko_finger_wheel_button_press" ); 
    350      
     351 
    351352    MokoFingerWheelPrivate* priv = MOKO_FINGER_WHEEL_GET_PRIVATE(widget); 
    352      
     353 
    353354    gtk_grab_add( widget ); 
    354355    gtk_widget_set_state( widget, GTK_STATE_ACTIVE ); 
     
    356357 
    357358    moko_finger_wheel_button_check_area (widget, event); 
    358      
     359 
    359360    g_source_remove_by_user_data((gpointer) widget); 
    360361    g_timeout_add (FINGER_WHEEL_LONG_PRESS_TIMEOUT, (GSourceFunc) moko_finger_wheel_button_long_press, (gpointer) widget); 
    361      
     362 
    362363    return TRUE; 
    363364} 
     
    387388{ 
    388389    moko_debug( "moko_finger_wheel_button_release" ); 
    389      
     390 
    390391    gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); 
    391392    gtk_widget_set_state( widget, GTK_STATE_NORMAL ); 
     
    393394 
    394395    moko_finger_wheel_button_emit_signal (widget, event); 
    395      
     396 
    396397    g_source_remove_by_user_data((gpointer) widget); 
    397398    return TRUE; 
     
    401402static gboolean moko_finger_wheel_button_long_press(gpointer data) 
    402403{ 
    403      
     404 
    404405    GtkWidget* widget = (GtkWidget*) data; 
    405      
     406 
    406407    if (MOKO_FINGER_WHEEL (widget)->area_id == PRESS_LEFT_UP) 
    407408    { 
     
    421422        return TRUE; 
    422423    } 
    423      
     424 
    424425    return FALSE; 
    425426} 
  • trunk/src/target/OM-2007/openmoko-libs/libmokoui/moko-window.c

    r342 r398  
    33 * 
    44 *  Authored By Michael 'Mickey' Lauer <mlauer@vanille-media.de> 
     5 *  Based on hildon-window.c (C) 2006 Nokia Corporation. 
    56 * 
    67 *  Copyright (C) 2006 First International Computer Inc. 
     
    2122#include "moko-window.h" 
    2223 
    23 #undef DEBUG_THIS_FILE 
     24#include <gtk/gtkentry.h> 
     25#include <gtk/gtktextview.h> 
     26 
     27#include <gdk/gdkx.h> 
     28 
     29#include <X11/X.h> 
     30#include <X11/Xlib.h> 
     31#include <X11/Xatom.h> 
     32 
     33#define DEBUG_THIS_FILE 
    2434#ifdef DEBUG_THIS_FILE 
    2535#define moko_debug(fmt,...) g_debug(fmt,##__VA_ARGS__) 
     
    3444}; 
    3545 
    36 static void moko_window_class_init          (MokoWindowClass *klass); 
    37 static void moko_window_init                (MokoWindow      *self); 
     46enum { 
     47    PROP_0, 
     48    PROP_IS_TOPMOST, 
     49}; 
     50 
     51static void moko_window_class_init(MokoWindowClass *klass); 
     52static void moko_window_init(MokoWindow *self); 
     53static void moko_window_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec); 
     54static void moko_window_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec); 
     55static void moko_window_notify(GObject* gobject, GParamSpec* param); 
     56static void moko_window_is_topmost_notify(MokoWindow* self); 
    3857 
    3958static guint moko_window_signals[LAST_SIGNAL] = { 0 }; 
     59static GtkWindowClass* parent_class = NULL; 
    4060 
    4161G_DEFINE_TYPE (MokoWindow, moko_window, GTK_TYPE_WINDOW) 
    4262 
    43 static void moko_window_class_init (MokoWindowClass *klass) /* Class Initialization */ 
    44 { 
     63#define MOKO_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MOKO_TYPE_WINDOW, MokoWindowPrivate)); 
     64 
     65typedef struct _MokoWindowPrivate 
     66{ 
     67    gboolean is_fullscreen; 
     68    gboolean is_topmost; 
     69} MokoWindowPrivate; 
     70 
     71static void moko_window_class_init(MokoWindowClass *klass) /* Class Initialization */ 
     72{ 
     73    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); 
     74    GObjectClass *object_class = G_OBJECT_CLASS(klass); 
     75 
     76    /* Set the global parent_class here */ 
     77    parent_class = g_type_class_peek_parent(klass); 
     78 
     79    /* register private data */ 
     80    g_type_class_add_private( klass, sizeof(MokoWindowPrivate) ); 
     81 
     82    /* hook virtual methods */ 
     83    object_class->set_property = moko_window_set_property; 
     84    object_class->get_property = moko_window_get_property; 
     85    object_class->notify = moko_window_notify; 
     86 
     87    /* install signals */ 
    4588    moko_window_signals[MOKO_WINDOW_SIGNAL] = g_signal_new ("moko_window", 
    4689            G_TYPE_FROM_CLASS (klass), 
     
    5194            g_cclosure_marshal_VOID__VOID, 
    5295            G_TYPE_NONE, 0); 
    53 } 
    54  
    55 static void moko_window_init (MokoWindow *self) /* Instance Construction */ 
     96 
     97    /* install properties */ 
     98    g_object_class_install_property (object_class, PROP_IS_TOPMOST, 
     99                g_param_spec_boolean ("is-topmost", 
     100                "Is top-most", 
     101                "Whether the window is currently activated by the window " 
     102                "manager", 
     103                FALSE, 
     104                G_PARAM_READABLE)); 
     105} 
     106 
     107static void moko_window_init(MokoWindow *self) /* Instance Construction */ 
    56108{ 
    57109    moko_debug( "moko_window_init" ); 
     
    60112    if ( !moko_application_get_main_window( app ) ) 
    61113        moko_application_set_main_window( app, self ); 
     114    moko_application_add_window( app, self ); 
     115} 
     116 
     117GtkWidget* moko_window_new() /* Construction */ 
     118{ 
     119    return GTK_WIDGET(g_object_new(moko_window_get_type(), NULL)); 
     120} 
     121 
     122void moko_window_clear(MokoWindow *self) /* Destruction */ 
     123{ 
     124    /* destruct your widgets here */ 
     125} 
     126 
     127static void 
     128moko_window_set_property(GObject* object, guint property_id, const GValue* value, GParamSpec* pspec) 
     129{ 
     130    switch (property_id) { 
     131 
     132    default: 
     133        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 
     134        break; 
     135    } 
     136} 
     137 
     138static void 
     139moko_window_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec) 
     140{ 
     141    MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(object); 
     142 
     143    switch (property_id) { 
     144 
     145    case PROP_IS_TOPMOST: 
     146            g_value_set_boolean (value, priv->is_topmost); 
     147        break; 
     148 
     149    default: 
     150        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); 
     151        break; 
     152    } 
     153} 
     154 
     155static void 
     156moko_window_notify(GObject* gobject, GParamSpec* param) 
     157{ 
     158    moko_debug( "moko_window_notify" ); 
     159    MokoWindow* window = MOKO_WINDOW(gobject); 
     160 
     161    if (strcmp(param->name, "title") == 0) 
     162    { 
     163        moko_debug( "update window title" ); 
     164        //moko_window_update_title(window); 
     165    } 
     166    else if (strcmp(param->name, "is-topmost")) 
     167    { 
     168        moko_window_is_topmost_notify(window); 
     169    } 
     170 
     171    if (G_OBJECT_CLASS(parent_class)->notify) 
     172        G_OBJECT_CLASS(parent_class)->notify (gobject, param); 
     173} 
     174 
     175static void 
     176moko_window_is_topmost_notify(MokoWindow* self) 
     177{ 
     178    moko_debug( "moko_window_is_topmost_notify" ); 
     179    MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(self); 
     180    if (priv->is_topmost) 
     181    { 
     182        moko_debug( "-- I am topmost now :D" ); 
     183    } 
    62184    else 
    63         g_warning( "moko_window_init: there is already a main window" ); 
    64 } 
    65  
    66 GtkWidget* moko_window_new() /* Construction */ 
    67 { 
    68     return GTK_WIDGET(g_object_new(moko_window_get_type(), NULL)); 
    69 } 
    70  
    71 void moko_window_clear(MokoWindow *self) /* Destruction */ 
    72 { 
    73     /* destruct your widgets here */ 
    74 } 
     185    { 
     186        moko_debug( "-- I am no longer topmost :(" ); 
     187    } 
     188} 
     189 
     190/* 
     191 * Compare the window that was last topped, and act consequently 
     192 */ 
     193void 
     194moko_window_update_topmost(MokoWindow* self, Window window_id) 
     195{ 
     196    moko_debug( "moko_window_update_topmost" ); 
     197    MokoWindowPrivate* priv = MOKO_WINDOW_GET_PRIVATE(self); 
     198    Window my_window; 
     199 
     200    my_window = GDK_WINDOW_XID (GTK_WIDGET (self)->window); 
     201 
     202    if (window_id == my_window) 
     203    { 
     204        if (!priv->is_topmost) 
     205        { 
     206            priv->is_topmost = TRUE; 
     207            moko_window_is_topmost_notify( self ); 
     208            g_object_notify( G_OBJECT(self), "is-topmost" ); 
     209        } 
     210    } 
     211    else if (priv->is_topmost) 
     212    { 
     213        /* Should this go in the signal handler? */ 
     214        GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(self)); 
     215 
     216        if (GTK_IS_ENTRY(focus)) 
     217            gtk_im_context_focus_out(GTK_ENTRY(focus)->im_context); 
     218        if (GTK_IS_TEXT_VIEW (focus)) 
     219            gtk_im_context_focus_out(GTK_TEXT_VIEW(focus)->im_context); 
     220 
     221        priv->is_topmost = FALSE; 
     222        moko_window_is_topmost_notify(self); 
     223        g_object_notify( G_OBJECT(self), "is-topmost" ); 
     224    } 
     225} 
     226 
     227/* 
     228 * Checks the root window to know which is the topmost window 
     229 */ 
     230Window 
     231moko_window_get_active_window() 
     232{ 
     233    Atom realtype; 
     234    int format; 
     235    int status; 
     236    Window ret; 
     237    unsigned long n; 
     238    unsigned long extra; 
     239    union 
     240    { 
     241        Window *win; 
     242        unsigned char *char_pointer; 
     243    } win; 
     244    Atom active_app_atom = XInternAtom( GDK_DISPLAY(), "_MB_CURRENT_APP_WINDOW", False ); 
     245    win.win = NULL; 
     246 
     247    status = XGetWindowProperty( GDK_DISPLAY(), 
     248                                 GDK_ROOT_WINDOW(), 
     249                                 active_app_atom, 
     250                                 0L, 
     251                                 16L, 
     252                                 0, 
     253                                 XA_WINDOW, 
     254                                 &realtype, 
     255                                 &format, 
     256                                 &n, 
     257                                 &extra, 
     258                                 &win.char_pointer); 
     259    if ( !(status == Success && realtype == XA_WINDOW && format == 32 && n == 1 && win.win != NULL) ) 
     260    { 
     261        if (win.win != NULL) XFree (win.char_pointer); 
     262        return None; 
     263    } 
     264 
     265    ret = win.win[0]; 
     266 
     267    if (win.win != NULL) 
     268        XFree(win.char_pointer); 
     269 
     270    return ret; 
     271} 
  • trunk/src/target/OM-2007/openmoko-libs/libmokoui/moko-window.h

    r219 r398  
    2424#include <glib-object.h> 
    2525 
     26#include <X11/X.h> 
     27 
    2628G_BEGIN_DECLS 
    2729 
     
    4547} MokoWindowClass; 
    4648 
    47 GType          moko_window_get_type        (void); 
    48 GtkWidget*     moko_window_new             (void); 
    49 void           moko_window_clear           (MokoWindow *self); 
     49GType moko_window_get_type(); 
     50GtkWidget* moko_window_new(); 
     51void moko_window_clear(MokoWindow *self); 
    5052 
    51 /* add additional methods here */ 
     53Window moko_window_get_active_window(); 
    5254 
    5355G_END_DECLS 
Note: See TracChangeset for help on using the changeset viewer.