Newer
Older
if ((ev->message_type == display_info->atoms[WM_CHANGE_STATE]) && (ev->format == 32) && (ev->data.l[0] == IconicState))
TRACE ("client \"%s\" (0x%lx) has received a wm_change_state event", c->name, c->window);
if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && CLIENT_CAN_HIDE_WINDOW (c))
{
clientHide (c, c->win_workspace, TRUE);
}
}
else if ((ev->message_type == display_info->atoms[WIN_STATE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_state event", c->name, c->window);
clientUpdateWinState (c, ev);
}
else if ((ev->message_type == display_info->atoms[WIN_LAYER]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_layer event", c->name, c->window);
if ((ev->data.l[0] != c->win_layer) && !is_transient)
{
clientSetLayer (c, ev->data.l[0]);
}
}
else if ((ev->message_type == display_info->atoms[WIN_WORKSPACE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a win_workspace event", c->name, c->window);
if ((ev->data.l[0] != c->win_workspace) && !is_transient)
{
clientSetWorkspace (c, ev->data.l[0], TRUE);
}
}
else if ((ev->message_type == display_info->atoms[NET_WM_DESKTOP]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_desktop event", c->name, c->window);
{
if (ev->data.l[0] == ALL_WORKSPACES)
{
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
clientStick (c, TRUE);
Olivier Fourdan
committed
frameDraw (c, FALSE);
}
}
else
{
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
clientUnstick (c, TRUE);
Olivier Fourdan
committed
frameDraw (c, FALSE);
}
if (ev->data.l[0] != c->win_workspace)
{
clientSetWorkspace (c, ev->data.l[0], TRUE);
}
}
}
}
else if ((ev->message_type == display_info->atoms[NET_CLOSE_WINDOW]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_close_window event", c->name, c->window);
clientClose (c);
}
else if ((ev->message_type == display_info->atoms[NET_WM_STATE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_state event", c->name, c->window);
clientUpdateNetState (c, ev);
}
else if ((ev->message_type == display_info->atoms[NET_WM_MOVERESIZE]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_wm_moveresize event", c->name, c->window);
else if ((ev->message_type == display_info->atoms[NET_ACTIVE_WINDOW]) && (ev->format == 32))
TRACE ("client \"%s\" (0x%lx) has received a net_active_window event", c->name, c->window);
Olivier Fourdan
committed
Time current = myDisplayGetLastUserTime (screen_info->display_info);
TRACE ("Time of event received is %u, current XServer time is %u", (unsigned int) ev_time, (unsigned int) current);
Olivier Fourdan
committed
if ((screen_info->params->prevent_focus_stealing) && (ev_time != (Time) 0) && TIMESTAMP_IS_BEFORE(ev_time, current))
{
FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
clientSetNetState (c);
}
else
{
clientActivate (c, (Time) ev_time);
clientActivate (c, myDisplayGetCurrentTime (screen_info->display_info));
else if (ev->message_type == display_info->atoms[NET_REQUEST_FRAME_EXTENTS])
Olivier Fourdan
committed
{
TRACE ("client \"%s\" (0x%lx) has received a net_request_frame_extents event", c->name, c->window);
setNetFrameExtents (display_info, c->window, frameTop (c), frameLeft (c),
frameRight (c), frameBottom (c));
Olivier Fourdan
committed
}
screen_info = myDisplayGetScreenFromWindow (display_info, ev->window);
if (!screen_info)
{
return;
}
if (((ev->message_type == display_info->atoms[WIN_WORKSPACE]) ||
(ev->message_type == display_info->atoms[NET_CURRENT_DESKTOP])) && (ev->format == 32))
TRACE ("root has received a win_workspace or a net_current_desktop event %li", ev->data.l[0]);
Olivier Fourdan
committed
if ((ev->data.l[0] >= 0) && (ev->data.l[0] < screen_info->workspace_count) && (ev->data.l[0] != screen_info->current_ws))
Olivier Fourdan
committed
workspaceSwitch (screen_info, ev->data.l[0], NULL, TRUE);
else if (((ev->message_type == display_info->atoms[WIN_WORKSPACE_COUNT]) ||
(ev->message_type == display_info->atoms[NET_NUMBER_OF_DESKTOPS])) && (ev->format == 32))
{
TRACE ("root has received a win_workspace_count event");
if (ev->data.l[0] != screen_info->workspace_count)
workspaceSetCount (screen_info, ev->data.l[0]);
getDesktopLayout(display_info, screen_info->xroot, screen_info->workspace_count, &screen_info->desktop_layout);
#ifdef ENABLE_KDE_SYSTRAY_PROXY
else if ((ev->message_type == display_info->atoms[MANAGER]) && (ev->data.l[1] == screen_info->net_system_tray_selection) && (ev->format == 32))
{
TRACE ("root has received a net_system_tray_manager event");
screen_info->systray = getSystrayWindow (display_info, screen_info->net_system_tray_selection);
#endif
else if ((ev->message_type == display_info->atoms[NET_SHOWING_DESKTOP]) && (ev->format == 32))
{
TRACE ("root has received a net_showing_desktop event");
Olivier Fourdan
committed
screen_info->show_desktop = (ev->data.l[0] != 0);
clientToggleShowDesktop (screen_info);
setHint (display_info, screen_info->xroot, NET_SHOWING_DESKTOP, ev->data.l[0]);
else if (ev->message_type == display_info->atoms[NET_REQUEST_FRAME_EXTENTS])
Olivier Fourdan
committed
{
TRACE ("window (0x%lx) has received a net_request_frame_extents event", ev->window);
Olivier Fourdan
committed
/* Size estimate from the decoration extents */
setNetFrameExtents (display_info, ev->window,
Olivier Fourdan
committed
frameDecorationTop (screen_info),
frameDecorationLeft (screen_info),
frameDecorationRight (screen_info),
frameDecorationBottom (screen_info));
}
Olivier Fourdan
committed
else if (ev->message_type == display_info->atoms[MANAGER])
{
TRACE ("window (0x%lx) has received a manager event", ev->window);
display_info->quit = TRUE;
}
TRACE ("unidentified client message for window 0x%lx", ev->window);
handleShape (DisplayInfo *display_info, XShapeEvent * ev)
Olivier Fourdan
committed
gboolean update;
TRACE ("entering handleShape");
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
Olivier Fourdan
committed
update = FALSE;
if (ev->kind == ShapeBounding)
{
if ((ev->shaped) && !FLAG_TEST (c->flags, CLIENT_FLAG_HAS_SHAPE))
{
FLAG_SET (c->flags, CLIENT_FLAG_HAS_SHAPE);
Olivier Fourdan
committed
clientGetMWMHints (c, TRUE);
update = TRUE;
}
else if (!(ev->shaped) && FLAG_TEST (c->flags, CLIENT_FLAG_HAS_SHAPE))
{
FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_SHAPE);
Olivier Fourdan
committed
clientGetMWMHints (c, TRUE);
update = TRUE;
Olivier Fourdan
committed
if (!update)
{
Olivier Fourdan
committed
frameDraw (c, FALSE);
Olivier Fourdan
committed
}
handleColormapNotify (DisplayInfo *display_info, XColormapEvent * ev)
Olivier Fourdan
committed
TRACE ("entering handleColormapNotify");
Olivier Fourdan
committed
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
if ((c) && (ev->window == c->window) && (ev->new))
if (c == clientGetFocus ())
{
clientInstallColormaps (c);
}
static void
handleMappingNotify (DisplayInfo *display_info, XMappingEvent * ev)
{
TRACE ("entering handleMappingNotify");
/* Refreshes the stored modifier and keymap information */
XRefreshKeyboardMapping (ev);
/* Update internal modifiers masks if necessary */
if (ev->request == MappingModifier)
{
TRACE ("handleMappingNotify: modifiers mapping has changed");
initModifiers (display_info->dpy);
}
/* Regrab all keys if the notify is for keyboard (ie not pointer) */
if (ev->request != MappingPointer)
{
TRACE ("handleMappingNotify: Reload settings");
reloadSettings (display_info, UPDATE_BUTTON_GRABS);
#ifdef HAVE_XSYNC
static void
handleXSyncAlarmNotify (DisplayInfo *display_info, XSyncAlarmNotifyEvent * ev)
{
XWindowChanges wc;
Client *c;
TRACE ("entering handleXSyncAlarmNotify");
Olivier Fourdan
committed
if (!display_info->have_xsync)
{
return;
}
c = myDisplayGetClientFromXSyncAlarm (display_info, ev->alarm);
if (c)
{
c->xsync_waiting = FALSE;
c->xsync_value = ev->counter_value;
Olivier Fourdan
committed
if (c->xsync_enabled)
{
wc.x = c->x;
wc.y = c->y;
wc.width = c->width;
wc.height = c->height;
clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, NO_CFG_FLAG);
}
}
}
#endif /* HAVE_XSYNC */
static void
handleEvent (DisplayInfo *display_info, XEvent * ev)
TRACE ("entering handleEvent");
myDisplayUpdateCurrentTime (display_info, ev);
sn_process_event (ev);
case MotionNotify:
handleMotionNotify (display_info, (XMotionEvent *) ev);
break;
case KeyPress:
handleKeyPress (display_info, (XKeyEvent *) ev);
break;
case ButtonPress:
handleButtonPress (display_info, (XButtonEvent *) ev);
break;
case ButtonRelease:
handleButtonRelease (display_info, (XButtonEvent *) ev);
break;
case DestroyNotify:
handleDestroyNotify (display_info, (XDestroyWindowEvent *) ev);
break;
case UnmapNotify:
handleUnmapNotify (display_info, (XUnmapEvent *) ev);
break;
case MapRequest:
handleMapRequest (display_info, (XMapRequestEvent *) ev);
handleMapNotify (display_info, (XMapEvent *) ev);
handleConfigureNotify (display_info, (XConfigureEvent *) ev);
case ConfigureRequest:
handleConfigureRequest (display_info, (XConfigureRequestEvent *) ev);
break;
case EnterNotify:
handleEnterNotify (display_info, (XCrossingEvent *) ev);
break;
case LeaveNotify:
handleLeaveNotify (display_info, (XCrossingEvent *) ev);
break;
case FocusIn:
handleFocusIn (display_info, (XFocusChangeEvent *) ev);
break;
case FocusOut:
handleFocusOut (display_info, (XFocusChangeEvent *) ev);
break;
case PropertyNotify:
handlePropertyNotify (display_info, (XPropertyEvent *) ev);
break;
case ClientMessage:
handleClientMessage (display_info, (XClientMessageEvent *) ev);
break;
case ColormapNotify:
handleColormapNotify (display_info, (XColormapEvent *) ev);
case MappingNotify:
handleMappingNotify (display_info, (XMappingEvent *) ev);
break;
if ((display_info->have_shape) && (ev->type == display_info->shape_event_base))
handleShape (display_info, (XShapeEvent *) ev);
#ifdef HAVE_XSYNC
if ((display_info->have_xsync) && (ev->type == (display_info->xsync_event_base + XSyncAlarmNotify)))
{
handleXSyncAlarmNotify (display_info, (XSyncAlarmNotifyEvent *) ev);
}
#endif /* HAVE_XSYNC */
if (!gdk_events_pending () && !XPending (display_info->dpy))
Olivier Fourdan
committed
if (display_info->reload)
Olivier Fourdan
committed
display_info->reload = FALSE;
Olivier Fourdan
committed
else if (display_info->quit)
{
gtk_main_quit ();
}
xfwm4_event_filter (XEvent * xevent, gpointer data)
DisplayInfo *display_info;
display_info = (DisplayInfo *) data;
TRACE ("entering xfwm4_event_filter");
TRACE ("leaving xfwm4_event_filter");
/* GTK specific stuff */
menu_callback (Menu * menu, MenuOp op, Window xid, gpointer menu_data, gpointer item_data)
Olivier Fourdan
committed
TRACE ("entering menu_callback");
if ((menu_data != NULL) && (xid != None))
ScreenInfo *screen_info = (ScreenInfo *) menu_data;
c = clientGetFromWindow (screen_info, xid, WINDOW);
}
if (c)
{
c->button_pressed[MENU_BUTTON] = FALSE;
switch (op)
case MENU_OP_QUIT:
gtk_main_quit ();
break;
case MENU_OP_MAXIMIZE:
case MENU_OP_UNMAXIMIZE:
if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
{
clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
}
break;
case MENU_OP_MINIMIZE:
if (CLIENT_CAN_HIDE_WINDOW (c))
{
clientHide (c, c->win_workspace, TRUE);
}
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
case MENU_OP_MINIMIZE_ALL:
clientHideAll (c, c->win_workspace);
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
case MENU_OP_UNMINIMIZE:
clientShow (c, TRUE);
Olivier Fourdan
committed
clientClearAllShowDesktop (c->screen_info);
break;
case MENU_OP_SHADE:
case MENU_OP_UNSHADE:
clientToggleShaded (c);
break;
case MENU_OP_STICK:
case MENU_OP_UNSTICK:
clientToggleSticky (c, TRUE);
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
case MENU_OP_WORKSPACES:
clientSetWorkspace (c, GPOINTER_TO_INT (item_data), TRUE);
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
case MENU_OP_DELETE:
Olivier Fourdan
committed
frameDraw (c, FALSE);
clientClose (c);
break;
case MENU_OP_CONTEXT_HELP:
clientEnterContextMenuState (c);
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
case MENU_OP_ABOVE:
case MENU_OP_NORMAL:
clientToggleAbove (c);
/* Fall thru */
default:
Olivier Fourdan
committed
frameDraw (c, FALSE);
break;
else
gdk_beep ();
}
menu_free (menu);
void
initMenuEventWin (void)
{
}
Olivier Fourdan
committed
static void
show_window_menu (Client *c, gint px, gint py, guint button, guint32 time)
ScreenInfo *screen_info;
DisplayInfo *display_info;
Olivier Fourdan
committed
Menu *menu;
MenuOp ops;
MenuOp insensitive;
Olivier Fourdan
committed
gint x, y;
Olivier Fourdan
committed
TRACE ("entering show_window_menu");
Olivier Fourdan
committed
if (!c || ((button != Button1) && (button != Button3)))
Olivier Fourdan
committed
return;
}
Olivier Fourdan
committed
x = px;
y = py;
Olivier Fourdan
committed
c->button_pressed[MENU_BUTTON] = TRUE;
frameDraw (c, FALSE);
y = (gdouble) c->y;
ops = MENU_OP_DELETE | MENU_OP_MINIMIZE_ALL | MENU_OP_WORKSPACES;
insensitive = 0;
Olivier Fourdan
committed
if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_CLOSE))
{
insensitive |= MENU_OP_DELETE;
}
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
{
ops |= MENU_OP_UNMAXIMIZE;
if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
Olivier Fourdan
committed
insensitive |= MENU_OP_UNMAXIMIZE;
Olivier Fourdan
committed
}
else
{
ops |= MENU_OP_MAXIMIZE;
if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
Olivier Fourdan
committed
insensitive |= MENU_OP_MAXIMIZE;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
{
ops |= MENU_OP_UNMINIMIZE;
if (!CLIENT_CAN_HIDE_WINDOW (c))
Olivier Fourdan
committed
insensitive |= MENU_OP_UNMINIMIZE;
Olivier Fourdan
committed
}
else
{
ops |= MENU_OP_MINIMIZE;
if (!CLIENT_CAN_HIDE_WINDOW (c))
Olivier Fourdan
committed
insensitive |= MENU_OP_MINIMIZE;
Olivier Fourdan
committed
}
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
{
ops |= MENU_OP_UNSHADE;
}
else
{
ops |= MENU_OP_SHADE;
}
Olivier Fourdan
committed
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
ops |= MENU_OP_UNSTICK;
if (!CLIENT_CAN_STICK_WINDOW(c))
Olivier Fourdan
committed
insensitive |= MENU_OP_UNSTICK;
Olivier Fourdan
committed
}
else
{
ops |= MENU_OP_STICK;
if (!CLIENT_CAN_STICK_WINDOW(c))
Olivier Fourdan
committed
insensitive |= MENU_OP_STICK;
Olivier Fourdan
committed
}
/* KDE extension */
clientGetWMProtocols(c);
if (FLAG_TEST (c->wm_flags, WM_FLAG_CONTEXT_HELP))
{
ops |= MENU_OP_CONTEXT_HELP;
}
Olivier Fourdan
committed
if (FLAG_TEST(c->flags, CLIENT_FLAG_ABOVE))
{
ops |= MENU_OP_NORMAL;
if (clientIsValidTransientOrModal (c) ||
FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
Olivier Fourdan
committed
insensitive |= MENU_OP_NORMAL;
Olivier Fourdan
committed
}
else
{
Olivier Fourdan
committed
ops |= MENU_OP_ABOVE;
if (clientIsValidTransientOrModal (c) ||
FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
{
insensitive |= MENU_OP_ABOVE;
}
}
if (clientIsValidTransientOrModal (c)
|| !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK)
|| FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
insensitive |= MENU_OP_WORKSPACES;
Olivier Fourdan
committed
}
/* c is not null here */
screen_info = c->screen_info;
display_info = screen_info->display_info;
Olivier Fourdan
committed
{
g_signal_handler_disconnect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), screen_info->button_handler_id);
Olivier Fourdan
committed
}
screen_info->button_handler_id = g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)),
"button_press_event", GTK_SIGNAL_FUNC (show_popup_cb), (gpointer) NULL);
Olivier Fourdan
committed
/*
Since all button press/release events are catched by the windows frames, there is some
side effect with GTK menu. When a menu is opened, any click on the window frame is not
detected as a click outside the menu, and the menu doesn't close.
To avoid this (painless but annoying) behaviour, we just setup a no event window that
"hides" the events to regular windows.
That might look tricky, but it's very efficient and save plenty of lines of complicated
Don't forget to delete that window once the menu is closed, though, or we'll get in
xfwmWindowTemp (screen_info,
&menu_event_window, 0, 0,
screen_info->width,
screen_info->height,
Olivier Fourdan
committed
NoEventMask,
FALSE);
menu = menu_default (screen_info->gscr, c->window, ops, insensitive, menu_callback,
c->win_workspace, screen_info->workspace_count,
screen_info->workspace_names, screen_info->workspace_names_items,
display_info->xfilter, screen_info);
Olivier Fourdan
committed
if (!menu_popup (menu, x, y, button, time))
TRACE ("Cannot open menu");
gdk_beep ();
c->button_pressed[MENU_BUTTON] = FALSE;
Olivier Fourdan
committed
frameDraw (c, FALSE);
menu_free (menu);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
}
static gboolean
show_popup_cb (GtkWidget * widget, GdkEventButton * ev, gpointer data)
{
TRACE ("entering show_popup_cb");
show_window_menu ((Client *) data, (gint) ev->x_root, (gint) ev->y_root, ev->button, ev->time);
Olivier Fourdan
committed
return (TRUE);
static gboolean
set_reload (GObject * obj, GdkEvent * ev, gpointer data)
Olivier Fourdan
committed
DisplayInfo *display_info;
TRACE ("setting reload flag so all prefs will be reread at next event loop");
Olivier Fourdan
committed
display_info = (DisplayInfo *) data;
display_info->reload = TRUE;
static gboolean
dbl_click_time_cb (GObject * obj, GdkEvent * ev, gpointer data)
Olivier Fourdan
committed
g_value_init (&tmp_val, G_TYPE_INT);
if (gdk_setting_get ("gtk-double-click-time", &tmp_val))
display_info->dbl_click_time = abs (g_value_get_int (&tmp_val));
}
return (TRUE);
}
static gboolean
client_event_cb (GtkWidget * widget, GdkEventClient * ev, gpointer data)
TRACE ("entering client_event_cb");
Olivier Fourdan
committed
if (!atom_rcfiles)
Olivier Fourdan
committed
{
atom_rcfiles = gdk_atom_intern ("_GTK_READ_RCFILES", FALSE);
Olivier Fourdan
committed
}
if (ev->message_type == atom_rcfiles)
Olivier Fourdan
committed
{
set_reload (G_OBJECT (widget), (GdkEvent *) ev, data);
Olivier Fourdan
committed
}
return (FALSE);
Olivier Fourdan
committed
screen_info->button_handler_id =
g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)),
"button_press_event", GTK_SIGNAL_FUNC (show_popup_cb), (gpointer) NULL);
g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), "client_event",
Olivier Fourdan
committed
GTK_SIGNAL_FUNC (client_event_cb), (gpointer) (screen_info->display_info));
settings = gtk_settings_get_default ();
if (settings)
{
g_signal_connect (settings, "notify::gtk-theme-name",
Olivier Fourdan
committed
G_CALLBACK (set_reload), (gpointer) (screen_info->display_info));
g_signal_connect (settings, "notify::gtk-font-name",
Olivier Fourdan
committed
G_CALLBACK (set_reload), (gpointer) (screen_info->display_info));
g_signal_connect (settings, "notify::gtk-double-click-time",
G_CALLBACK (dbl_click_time_cb), (gpointer) (screen_info->display_info));