Skip to content
Snippets Groups Projects
events.c 71.6 KiB
Newer Older
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2, or (at your option)
        any later version.
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Olivier Fourdan's avatar
Olivier Fourdan committed
        oroborus - (c) 2001 Ken Lynch
        xfwm4    - (c) 2002-2004 Olivier Fourdan
Olivier Fourdan's avatar
Olivier Fourdan committed
 */

#ifdef HAVE_CONFIG_H
Olivier Fourdan's avatar
Olivier Fourdan committed
#endif

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
Olivier Fourdan's avatar
Olivier Fourdan committed
#include <gdk/gdk.h>
Olivier Fourdan's avatar
Olivier Fourdan committed
#include <gdk/gdkx.h>
Olivier Fourdan's avatar
Olivier Fourdan committed
#ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h>
#endif
#include <libxfce4util/libxfce4util.h> 
#include <libxfcegui4/libxfcegui4.h>
#include <string.h>

Olivier Fourdan's avatar
Olivier Fourdan committed
#include "misc.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "workspaces.h"
#include "settings.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "mywindow.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "frame.h"
#include "client.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "menu.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "hints.h"
#include "startup_notification.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "compositor.h"
Olivier Fourdan's avatar
Olivier Fourdan committed

#define WIN_IS_BUTTON(win)      ((win == MYWINDOW_XWINDOW(c->buttons[HIDE_BUTTON])) || \
                                 (win == MYWINDOW_XWINDOW(c->buttons[CLOSE_BUTTON])) || \
                                 (win == MYWINDOW_XWINDOW(c->buttons[MAXIMIZE_BUTTON])) || \
                                 (win == MYWINDOW_XWINDOW(c->buttons[SHADE_BUTTON])) || \
                                 (win == MYWINDOW_XWINDOW(c->buttons[STICK_BUTTON])))

#define DBL_CLICK_GRAB          (ButtonMotionMask | \
                                 PointerMotionMask | \
                                 ButtonPressMask | \
                                 ButtonReleaseMask)
                                 
#define MODIFIER_MASK           (ShiftMask | \
                                 ControlMask | \
                                 AltMask | \
                                 MetaMask | \
                                 SuperMask | \
                                 HyperMask)
extern gboolean xfwm4_quit;
extern gboolean xfwm4_reload;

Olivier Fourdan's avatar
Olivier Fourdan committed
static guint raise_timeout = 0;
static GdkAtom atom_rcfiles = GDK_NONE;
static xfwmWindow menu_event_window;
Olivier Fourdan's avatar
Olivier Fourdan committed

static void handleEvent (DisplayInfo *display_info, XEvent * ev);
static void menu_callback (Menu * menu, MenuOp op, Window client_xwindow,
    gpointer menu_data, gpointer item_data);
static gboolean show_popup_cb (GtkWidget * widget, GdkEventButton * ev,
static gboolean client_event_cb (GtkWidget * widget, GdkEventClient * ev, gpointer data);
Olivier Fourdan's avatar
Olivier Fourdan committed

typedef enum
{
    XFWM_BUTTON_UNDEFINED = 0,
    XFWM_BUTTON_DRAG = 1,
    XFWM_BUTTON_CLICK = 2,
    XFWM_BUTTON_CLICK_AND_DRAG = 3,
    XFWM_BUTTON_DOUBLE_CLICK = 4
}
XfwmButtonClickType;
typedef struct _XfwmButtonClickData XfwmButtonClickData;
struct _XfwmButtonClickData
{
    Time event_time;
    Window w;
    guint button;
    gboolean allow_double_click;
    guint clicks;
    gint x;
    gint y;
    gint xcurrent;
    gint ycurrent;
    guint timeout;
};

static gboolean
typeOfClick_break (gpointer data)
{
    XfwmButtonClickData *passdata = (XfwmButtonClickData *) data;
    if (passdata->timeout)
    {
        g_source_remove (passdata->timeout);
        passdata->timeout = 0;
    }

    gtk_main_quit ();

    return (TRUE);
}

static XfceFilterStatus
typeOfClick_event_filter (XEvent * xevent, gpointer data)
{
    gboolean keep_going = TRUE;
    XfceFilterStatus status = XEV_FILTER_STOP;
    XfwmButtonClickData *passdata = (XfwmButtonClickData *) data;
    
    if ((xevent->type == ButtonRelease) || (xevent->type == ButtonPress))
    {
        if (xevent->xbutton.button == passdata->button)
        {
            passdata->clicks++;
        }
        passdata->event_time = xevent->xbutton.time;
        if (((XfwmButtonClickType) passdata->clicks == XFWM_BUTTON_DOUBLE_CLICK)
            || (!(passdata->allow_double_click) && 
                 (XfwmButtonClickType) passdata->clicks == XFWM_BUTTON_CLICK))
        {
            keep_going = FALSE;
        }
    }
    else if (xevent->type == MotionNotify)
    {
        passdata->xcurrent = xevent->xmotion.x_root;
        passdata->ycurrent = xevent->xmotion.y_root;
    }
    else if ((xevent->type == DestroyNotify) || (xevent->type == UnmapNotify))
    {
        if (xevent->xany.window == passdata->w)
        {
            /* Discard, mark the click as undefined */
            passdata->clicks = (guint) XFWM_BUTTON_UNDEFINED;
            keep_going = FALSE;
        }
        status = XEV_FILTER_CONTINUE;
    }
    else
    {
        status = XEV_FILTER_CONTINUE;
    }

    if ((ABS (passdata->x - passdata->xcurrent) > 1) || 
        (ABS (passdata->y - passdata->ycurrent) > 1) ||
        (!keep_going))
    {
        TRACE ("event loop now finished");
        typeOfClick_break (data);
    }

    return status;
}

static XfwmButtonClickType
typeOfClick (ScreenInfo *screen_info, Window w, XEvent * ev, gboolean allow_double_click)
    DisplayInfo *display_info;
    XfwmButtonClickData passdata;
    g_return_val_if_fail (screen_info != NULL, XFWM_BUTTON_UNDEFINED);
    g_return_val_if_fail (ev != NULL, XFWM_BUTTON_UNDEFINED);
    g_return_val_if_fail (w != None, XFWM_BUTTON_UNDEFINED);
    display_info = screen_info->display_info;    
    XFlush (display_info->dpy);
    g = XGrabPointer (display_info->dpy, screen_info->gnome_win, 
                      FALSE, DBL_CLICK_GRAB, GrabModeAsync,
                      GrabModeAsync, None, None, ev->xbutton.time);
Loading
Loading full blame...