Skip to content
Snippets Groups Projects
events.c 92.4 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
Olivier Fourdan's avatar
Olivier Fourdan committed
        Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
        MA 02110-1301, USA.

Olivier Fourdan's avatar
Olivier Fourdan committed
        oroborus - (c) 2001 Ken Lynch
Olivier Fourdan's avatar
Olivier Fourdan committed
        xfwm4    - (c) 2002-2011 Olivier Fourdan
Olivier Fourdan's avatar
Olivier Fourdan committed
 */

#ifdef HAVE_CONFIG_H
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "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>
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"
#include "moveresize.h"
#include "cycle.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

#ifndef CHECK_BUTTON_TIME
#define CHECK_BUTTON_TIME 0
#endif

#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 DOUBLE_CLICK_GRAB       (ButtonMotionMask | \
                                 PointerMotionMask | \
                                 ButtonPressMask | \
                                 ButtonReleaseMask)
Olivier Fourdan's avatar
Olivier Fourdan committed
static GdkAtom atom_rcfiles = GDK_NONE;
static xfwmWindow menu_event_window;
Olivier Fourdan's avatar
Olivier Fourdan committed

static eventFilterStatus handleEvent (DisplayInfo *display_info,
                                      XEvent * ev);
static void menu_callback            (Menu * menu,
                                      MenuOp op,
                                      Window xid,
                                      gpointer menu_data,
                                      gpointer item_data);
static void show_window_menu         (Client *c,
                                      gint px,
                                      gint py,
                                      guint button,
                                      guint32 time);
static gboolean show_popup_cb        (GtkWidget * widget,
                                      GdkEventButton * ev,
                                      gpointer data);
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
{
    DisplayInfo *display_info;
Olivier Fourdan's avatar
Olivier Fourdan committed
    gint  x0;
    gint  y0;
    guint t0;
    gint  xcurrent;
    gint  ycurrent;
    guint tcurrent;
    gint  double_click_time;
    gint  double_click_distance;
Olivier Fourdan's avatar
Olivier Fourdan committed
    gboolean allow_double_click;
static gboolean
typeOfClick_end (gpointer data)
{
    XfwmButtonClickData *passdata;

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

    gtk_main_quit ();

    return (FALSE);
}

static eventFilterStatus
typeOfClick_event_filter (XEvent * xevent, gpointer data)
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    XfwmButtonClickData *passdata;
    eventFilterStatus status;
Olivier Fourdan's avatar
Olivier Fourdan committed
    guint32 timestamp;
Olivier Fourdan's avatar
Olivier Fourdan committed
    gboolean keep_going;

    keep_going = TRUE;
    passdata = (XfwmButtonClickData *) data;
Olivier Fourdan's avatar
Olivier Fourdan committed

    /* Update the display time */
Olivier Fourdan's avatar
Olivier Fourdan committed
    timestamp = myDisplayUpdateCurrentTime (passdata->display_info, xevent);
Olivier Fourdan's avatar
Olivier Fourdan committed
    if (timestamp)
Olivier Fourdan's avatar
Olivier Fourdan committed
        passdata->tcurrent = timestamp;
        if (((gint) passdata->tcurrent - (gint) passdata->t0) > passdata->double_click_time)
        {
            keep_going = FALSE;
        }
    }
    if ((xevent->type == ButtonRelease) || (xevent->type == ButtonPress))
    {
        if (xevent->xbutton.button == passdata->button)
        {
            passdata->clicks++;
        }
        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;

        if ((ABS (passdata->x0 - passdata->xcurrent) > passdata->double_click_distance) ||
            (ABS (passdata->y0 - passdata->ycurrent) > passdata->double_click_distance))
        {
            keep_going = FALSE;
Loading
Loading full blame...