Newer
Older
clientSetWorkspace (c, screen_info->current_ws, TRUE);
clientShow (c, TRUE);
clientRaise (c);
clientSetFocus (screen_info, c, (Time) ev->data.l[1], NO_FOCUS_FLAG);
}
else
{
clientSetFocus (screen_info, c, CurrentTime, NO_FOCUS_FLAG);
}
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))
Olivier Fourdan
committed
TRACE ("root has received a win_workspace or a net_current_desktop event %i", ev->data.l[0]);
if ((ev->data.l[0] >= 0) && (ev->data.l[0] < screen_info->workspace_count) && (ev->data.l[0] != screen_info->current_ws))
workspaceSwitch (screen_info, ev->data.l[0], NULL);
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);
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);
else if ((ev->message_type == display_info->atoms[NET_SHOWING_DESKTOP]) && (ev->format == 32))
{
TRACE ("root has received a net_showing_desktop event");
clientToggleShowDesktop (screen_info, ev->data.l[0]);
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", c->name, ev->window);
/* 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));
}
TRACE ("unidentified client message for window 0x%lx", ev->window);
handleShape (DisplayInfo *display_info, XShapeEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
TRACE ("entering handleShape");
c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
frameDraw (c, FALSE, TRUE);
handleColormapNotify (DisplayInfo *display_info, XColormapEvent * ev)
Olivier Fourdan
committed
Client *c = NULL;
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
handleEvent (DisplayInfo *display_info, XEvent * ev)
TRACE ("entering handleEvent");
/* Update the display time */
myDisplayUpdateCurentTime (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);
break;
default:
if ((display_info->have_shape) && (ev->type == display_info->shape_event_base))
handleShape (display_info, (XShapeEvent *) ev);
if (!gdk_events_pending () && !XPending (display_info->dpy))
if (xfwm4_reload)
xfwm4_reload = FALSE;
else if (xfwm4_quit)
{
gtk_main_quit ();
}
Olivier Fourdan
committed
XfceFilterStatus
xfwm4_event_filter (XEvent * xevent, gpointer data)
DisplayInfo *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))
{
Olivier Fourdan
committed
clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
}
break;
case MENU_OP_MINIMIZE:
if (CLIENT_CAN_HIDE_WINDOW (c))
{
clientHide (c, c->win_workspace, TRUE);
}
frameDraw (c, FALSE, FALSE);
break;
case MENU_OP_MINIMIZE_ALL:
clientHideAll (c, c->win_workspace);
frameDraw (c, FALSE, FALSE);
break;
case MENU_OP_UNMINIMIZE:
clientShow (c, TRUE);
break;
case MENU_OP_SHADE:
case MENU_OP_UNSHADE:
clientToggleShaded (c);
break;
case MENU_OP_STICK:
case MENU_OP_UNSTICK:
clientToggleSticky (c, TRUE);
frameDraw (c, FALSE, FALSE);
break;
case MENU_OP_WORKSPACES:
clientSetWorkspace (c, GPOINTER_TO_INT (item_data), TRUE);
frameDraw (c, FALSE, FALSE);
break;
case MENU_OP_DELETE:
frameDraw (c, FALSE, FALSE);
clientClose (c);
break;
case MENU_OP_CONTEXT_HELP:
clientEnterContextMenuState (c);
frameDraw (c, FALSE, FALSE);
break;
case MENU_OP_ABOVE:
case MENU_OP_NORMAL:
clientToggleAbove (c);
/* Fall thru */
default:
frameDraw (c, FALSE, FALSE);
break;
else
gdk_beep ();
}
menu_free (menu);
void
initMenuEventWin (void)
{
}
static gboolean
show_popup_cb (GtkWidget * widget, GdkEventButton * ev, gpointer data)
ScreenInfo *screen_info = NULL;
DisplayInfo *display_info = NULL;
Olivier Fourdan
committed
Menu *menu;
MenuOp ops;
MenuOp insensitive;
Olivier Fourdan
committed
gint x = ev->x_root;
gint y = ev->y_root;
TRACE ("entering show_popup_cb");
if ((c) && ((ev->button == 1) || (ev->button == 3)))
c->button_pressed[MENU_BUTTON] = TRUE;
frameDraw (c, FALSE, FALSE);
y = c->y;
ops = MENU_OP_DELETE | MENU_OP_MINIMIZE_ALL | MENU_OP_WORKSPACES;
insensitive = 0;
if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_CLOSE))
{
insensitive |= MENU_OP_DELETE;
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
{
ops |= MENU_OP_UNMAXIMIZE;
if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
{
insensitive |= MENU_OP_UNMAXIMIZE;
}
}
else
{
ops |= MENU_OP_MAXIMIZE;
if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
{
insensitive |= MENU_OP_MAXIMIZE;
}
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
{
ops |= MENU_OP_UNMINIMIZE;
if (!CLIENT_CAN_HIDE_WINDOW (c))
{
insensitive |= MENU_OP_UNMINIMIZE;
}
}
else
{
ops |= MENU_OP_MINIMIZE;
if (!CLIENT_CAN_HIDE_WINDOW (c))
{
insensitive |= MENU_OP_MINIMIZE;
}
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
{
ops |= MENU_OP_UNSHADE;
}
else
{
ops |= MENU_OP_SHADE;
}
if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
{
ops |= MENU_OP_UNSTICK;
if (!CLIENT_CAN_STICK_WINDOW(c))
{
insensitive |= MENU_OP_UNSTICK;
}
}
else
{
ops |= MENU_OP_STICK;
if (!CLIENT_CAN_STICK_WINDOW(c))
{
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;
}
if (FLAG_TEST(c->flags, CLIENT_FLAG_ABOVE))
{
ops |= MENU_OP_NORMAL;
Olivier Fourdan
committed
if (clientIsValidTransientOrModal (c) ||
FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
{
insensitive |= MENU_OP_NORMAL;
}
}
else
{
ops |= MENU_OP_ABOVE;
Olivier Fourdan
committed
if (clientIsValidTransientOrModal (c) ||
FLAG_TEST (c->flags, CLIENT_FLAG_BELOW | CLIENT_FLAG_FULLSCREEN))
{
insensitive |= MENU_OP_ABOVE;
}
}
Olivier Fourdan
committed
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
}
else
{
Olivier Fourdan
committed
}
/* c is not null here */
screen_info = c->screen_info;
display_info = screen_info->display_info;
if (screen_info->button_handler_id)
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
NULL, 0,
screen_info->xroot,
&menu_event_window, 0, 0,
gdk_screen_get_width (screen_info->gscr),
gdk_screen_get_height (screen_info->gscr),
NoEventMask);
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_length,
display_info->xfilter, screen_info);
if (!menu_popup (menu, x, y, ev->button, ev->time))
{
TRACE ("Cannot open menu");
gdk_beep ();
c->button_pressed[MENU_BUTTON] = FALSE;
frameDraw (c, FALSE, FALSE);
menu_free (menu);
Olivier Fourdan
committed
}
Olivier Fourdan
committed
return (TRUE);
static gboolean
set_reload (GObject * obj, GdkEvent * ev, gpointer data)
TRACE ("setting reload flag so all prefs will be reread at next event loop");
xfwm4_reload = TRUE;
static gboolean
dbl_click_time_cb (GObject * obj, GdkEvent * ev, gpointer data)
DisplayInfo *display_info = (DisplayInfo *) data;
Olivier Fourdan
committed
g_return_val_if_fail (display_info, TRUE);
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",
GTK_SIGNAL_FUNC (client_event_cb), NULL);
settings = gtk_settings_get_default ();
if (settings)
{
g_signal_connect (settings, "notify::gtk-theme-name",
g_signal_connect (settings, "notify::gtk-font-name",
g_signal_connect (settings, "notify::gtk-double-click-time",
G_CALLBACK (dbl_click_time_cb), (gpointer) (screen_info->display_info));