2001-05-30 11:36:31 -04:00
|
|
|
/* Metacity X display handler */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2001 Havoc Pennington
|
|
|
|
*
|
|
|
|
* 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 of the
|
|
|
|
* License, 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., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2001-12-09 17:41:12 -05:00
|
|
|
#include <config.h>
|
2001-05-30 11:36:31 -04:00
|
|
|
#include "display.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "screen.h"
|
|
|
|
#include "window.h"
|
2001-06-02 21:33:27 -04:00
|
|
|
#include "frame.h"
|
2001-06-04 00:58:22 -04:00
|
|
|
#include "errors.h"
|
2001-06-06 00:47:37 -04:00
|
|
|
#include "keybindings.h"
|
2001-12-09 19:38:21 -05:00
|
|
|
#include "prefs.h"
|
2002-03-17 12:22:23 -05:00
|
|
|
#include "resizepopup.h"
|
2001-06-06 00:47:37 -04:00
|
|
|
#include "workspace.h"
|
2001-06-09 23:17:15 -04:00
|
|
|
#include <X11/Xatom.h>
|
2001-07-25 23:14:45 -04:00
|
|
|
#include <X11/cursorfont.h>
|
2001-06-09 23:17:15 -04:00
|
|
|
#include <string.h>
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2001-06-19 23:01:26 -04:00
|
|
|
#define USE_GDK_DISPLAY
|
|
|
|
|
2002-05-23 22:23:46 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
MetaDisplay *display;
|
|
|
|
Window xwindow;
|
|
|
|
Time timestamp;
|
|
|
|
MetaWindowPingFunc ping_reply_func;
|
|
|
|
MetaWindowPingFunc ping_timeout_func;
|
|
|
|
void *user_data;
|
|
|
|
guint ping_timeout_id;
|
|
|
|
} MetaPingData;
|
|
|
|
|
2002-05-23 22:23:46 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
MetaDisplay *display;
|
|
|
|
Window xwindow;
|
|
|
|
} MetaAutoRaiseData;
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
static GSList *all_displays = NULL;
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
|
2001-06-02 21:33:27 -04:00
|
|
|
static void meta_spew_event (MetaDisplay *display,
|
|
|
|
XEvent *event);
|
2001-06-19 23:01:26 -04:00
|
|
|
static void event_queue_callback (XEvent *event,
|
|
|
|
gpointer data);
|
|
|
|
static gboolean event_callback (XEvent *event,
|
2001-06-02 21:33:27 -04:00
|
|
|
gpointer data);
|
|
|
|
static Window event_get_modified_window (MetaDisplay *display,
|
|
|
|
XEvent *event);
|
2002-01-03 18:28:19 -05:00
|
|
|
static guint32 event_get_time (MetaDisplay *display,
|
|
|
|
XEvent *event);
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
static void process_pong_message (MetaDisplay *display,
|
|
|
|
XEvent *event);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
|
|
|
|
static gint
|
|
|
|
unsigned_long_equal (gconstpointer v1,
|
|
|
|
gconstpointer v2)
|
|
|
|
{
|
|
|
|
return *((const gulong*) v1) == *((const gulong*) v2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static guint
|
|
|
|
unsigned_long_hash (gconstpointer v)
|
|
|
|
{
|
|
|
|
gulong val = * (const gulong *) v;
|
|
|
|
|
|
|
|
/* I'm not sure this works so well. */
|
|
|
|
#if G_SIZEOF_LONG > 4
|
|
|
|
return (guint) (val ^ (val >> 32));
|
|
|
|
#else
|
|
|
|
return val;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2001-06-09 23:17:15 -04:00
|
|
|
static int
|
2001-08-07 01:52:51 -04:00
|
|
|
set_utf8_string_hint (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom atom,
|
|
|
|
const char *val)
|
2001-06-09 23:17:15 -04:00
|
|
|
{
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
XChangeProperty (display->xdisplay,
|
|
|
|
xwindow, atom,
|
2001-08-07 01:52:51 -04:00
|
|
|
display->atom_utf8_string,
|
2002-05-06 02:11:46 -04:00
|
|
|
8, PropModeReplace, (guchar*) val, strlen (val));
|
2001-06-09 23:17:15 -04:00
|
|
|
return meta_error_trap_pop (display);
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
static void
|
|
|
|
ping_data_free (MetaPingData *ping_data)
|
|
|
|
{
|
|
|
|
/* Remove the timeout */
|
|
|
|
if (ping_data->ping_timeout_id != 0)
|
|
|
|
g_source_remove (ping_data->ping_timeout_id);
|
|
|
|
|
|
|
|
g_free (ping_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remove_pending_pings_for_window (MetaDisplay *display, Window xwindow)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
GSList *dead;
|
|
|
|
|
|
|
|
/* could obviously be more efficient, don't care */
|
|
|
|
|
|
|
|
/* build list to be removed */
|
|
|
|
dead = NULL;
|
|
|
|
for (tmp = display->pending_pings; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
|
|
|
if (ping_data->xwindow == xwindow)
|
|
|
|
dead = g_slist_prepend (dead, ping_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove what we found */
|
|
|
|
for (tmp = dead; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
|
|
|
display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
|
|
|
|
ping_data_free (ping_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (dead);
|
|
|
|
}
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
gboolean
|
|
|
|
meta_display_open (const char *name)
|
|
|
|
{
|
|
|
|
MetaDisplay *display;
|
|
|
|
Display *xdisplay;
|
2001-05-30 23:30:58 -04:00
|
|
|
GSList *screens;
|
2001-05-31 02:42:58 -04:00
|
|
|
GSList *tmp;
|
2002-03-02 10:26:07 -05:00
|
|
|
int i;
|
2001-06-04 02:17:52 -04:00
|
|
|
/* Remember to edit code that assigns each atom to display struct
|
|
|
|
* when adding an atom name here.
|
|
|
|
*/
|
|
|
|
char *atom_names[] = {
|
|
|
|
"_NET_WM_NAME",
|
|
|
|
"WM_PROTOCOLS",
|
|
|
|
"WM_TAKE_FOCUS",
|
2001-06-06 00:47:37 -04:00
|
|
|
"WM_DELETE_WINDOW",
|
2001-06-07 01:18:10 -04:00
|
|
|
"WM_STATE",
|
2001-06-08 02:39:38 -04:00
|
|
|
"_NET_CLOSE_WINDOW",
|
|
|
|
"_NET_WM_STATE",
|
2001-06-21 02:08:35 -04:00
|
|
|
"_MOTIF_WM_HINTS",
|
2001-06-08 02:39:38 -04:00
|
|
|
"_NET_WM_STATE_SHADED",
|
|
|
|
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
2001-06-09 01:14:43 -04:00
|
|
|
"_NET_WM_STATE_MAXIMIZED_VERT",
|
|
|
|
"_NET_WM_DESKTOP",
|
2001-06-09 17:58:30 -04:00
|
|
|
"_NET_NUMBER_OF_DESKTOPS",
|
|
|
|
"WM_CHANGE_STATE",
|
|
|
|
"SM_CLIENT_ID",
|
|
|
|
"WM_CLIENT_LEADER",
|
2001-06-09 23:17:15 -04:00
|
|
|
"WM_WINDOW_ROLE",
|
|
|
|
"_NET_CURRENT_DESKTOP",
|
|
|
|
"_NET_SUPPORTING_WM_CHECK",
|
2001-08-29 00:16:30 -04:00
|
|
|
"_NET_SUPPORTED",
|
2001-06-09 23:17:15 -04:00
|
|
|
"_NET_WM_WINDOW_TYPE",
|
|
|
|
"_NET_WM_WINDOW_TYPE_DESKTOP",
|
|
|
|
"_NET_WM_WINDOW_TYPE_DOCK",
|
|
|
|
"_NET_WM_WINDOW_TYPE_TOOLBAR",
|
|
|
|
"_NET_WM_WINDOW_TYPE_MENU",
|
|
|
|
"_NET_WM_WINDOW_TYPE_DIALOG",
|
|
|
|
"_NET_WM_WINDOW_TYPE_NORMAL",
|
2001-06-10 03:52:35 -04:00
|
|
|
"_NET_WM_STATE_MODAL",
|
|
|
|
"_NET_CLIENT_LIST",
|
2001-06-11 01:16:24 -04:00
|
|
|
"_NET_CLIENT_LIST_STACKING",
|
|
|
|
"_NET_WM_STATE_SKIP_TASKBAR",
|
2001-06-12 20:56:08 -04:00
|
|
|
"_NET_WM_STATE_SKIP_PAGER",
|
2001-06-21 02:08:35 -04:00
|
|
|
"_WIN_WORKSPACE",
|
2001-06-23 01:49:35 -04:00
|
|
|
"_WIN_LAYER",
|
|
|
|
"_WIN_PROTOCOLS",
|
2001-06-23 23:18:10 -04:00
|
|
|
"_WIN_SUPPORTING_WM_CHECK",
|
|
|
|
"_NET_WM_ICON_NAME",
|
2001-08-05 12:04:52 -04:00
|
|
|
"_NET_WM_ICON",
|
2001-08-07 01:52:51 -04:00
|
|
|
"_NET_WM_ICON_GEOMETRY",
|
2001-08-19 21:42:44 -04:00
|
|
|
"UTF8_STRING",
|
2001-08-22 02:01:01 -04:00
|
|
|
"WM_ICON_SIZE",
|
2001-08-29 00:16:30 -04:00
|
|
|
"_KWM_WIN_ICON",
|
2001-10-07 19:06:19 -04:00
|
|
|
"_NET_WM_MOVERESIZE",
|
2001-10-15 00:14:58 -04:00
|
|
|
"_NET_ACTIVE_WINDOW",
|
2002-02-06 22:07:56 -05:00
|
|
|
"_METACITY_RESTART_MESSAGE",
|
2002-01-10 01:31:31 -05:00
|
|
|
"_NET_WM_STRUT",
|
2002-02-06 22:07:56 -05:00
|
|
|
"_WIN_HINTS",
|
2002-02-08 01:01:58 -05:00
|
|
|
"_METACITY_RELOAD_THEME_MESSAGE",
|
2002-02-08 23:50:58 -05:00
|
|
|
"_METACITY_SET_KEYBINDINGS_MESSAGE",
|
2002-02-09 01:54:44 -05:00
|
|
|
"_NET_WM_STATE_HIDDEN",
|
|
|
|
"_NET_WM_WINDOW_TYPE_UTILITY",
|
2002-02-23 17:58:02 -05:00
|
|
|
"_NET_WM_WINDOW_TYPE_SPLASHSCREEN",
|
2002-03-02 19:03:50 -05:00
|
|
|
"_NET_WM_STATE_FULLSCREEN",
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
"_NET_WM_PING",
|
|
|
|
"_NET_WM_PID",
|
2002-04-28 11:47:21 -04:00
|
|
|
"WM_CLIENT_MACHINE",
|
2002-05-06 02:11:46 -04:00
|
|
|
"_NET_WM_WORKAREA",
|
2002-05-16 00:03:36 -04:00
|
|
|
"_NET_SHOW_DESKTOP",
|
|
|
|
"_NET_DESKTOP_LAYOUT"
|
2001-06-04 02:17:52 -04:00
|
|
|
};
|
2001-06-02 00:14:18 -04:00
|
|
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
meta_verbose ("Opening display '%s'\n", XDisplayName (name));
|
|
|
|
|
2001-06-19 23:01:26 -04:00
|
|
|
#ifdef USE_GDK_DISPLAY
|
|
|
|
xdisplay = meta_ui_get_display (name);
|
|
|
|
#else
|
|
|
|
xdisplay = XOpenDisplay (name);
|
|
|
|
#endif
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
if (xdisplay == NULL)
|
|
|
|
{
|
|
|
|
meta_warning (_("Failed to open X Window System display '%s'\n"),
|
|
|
|
XDisplayName (name));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
if (meta_is_syncing ())
|
|
|
|
XSynchronize (xdisplay, True);
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
display = g_new (MetaDisplay, 1);
|
2001-06-02 21:33:27 -04:00
|
|
|
|
|
|
|
/* here we use XDisplayName which is what the user
|
|
|
|
* probably put in, vs. DisplayString(display) which is
|
|
|
|
* canonicalized by XOpenDisplay()
|
|
|
|
*/
|
2001-05-30 11:36:31 -04:00
|
|
|
display->name = g_strdup (XDisplayName (name));
|
|
|
|
display->xdisplay = xdisplay;
|
2002-02-24 14:58:27 -05:00
|
|
|
display->error_traps = 0;
|
|
|
|
display->error_trap_handler = NULL;
|
2001-06-09 01:14:43 -04:00
|
|
|
display->server_grab_count = 0;
|
2001-06-06 00:47:37 -04:00
|
|
|
display->workspaces = NULL;
|
2001-06-23 23:41:44 -04:00
|
|
|
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
display->pending_pings = NULL;
|
2002-05-23 22:23:46 -04:00
|
|
|
display->autoraise_timeout_id = 0;
|
2001-06-23 23:41:44 -04:00
|
|
|
display->focus_window = NULL;
|
2002-03-11 23:34:17 -05:00
|
|
|
display->mru_list = NULL;
|
2001-10-14 23:39:41 -04:00
|
|
|
|
|
|
|
display->showing_desktop = FALSE;
|
2002-01-19 18:59:11 -05:00
|
|
|
|
|
|
|
/* FIXME copy the checks from GDK probably */
|
|
|
|
display->static_gravity_works = g_getenv ("METACITY_USE_STATIC_GRAVITY") != NULL;
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
/* we have to go ahead and do this so error handlers work */
|
2001-05-30 11:36:31 -04:00
|
|
|
all_displays = g_slist_prepend (all_displays, display);
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
meta_display_init_keys (display);
|
2001-06-09 01:14:43 -04:00
|
|
|
|
|
|
|
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
|
|
|
False, atoms);
|
|
|
|
display->atom_net_wm_name = atoms[0];
|
|
|
|
display->atom_wm_protocols = atoms[1];
|
|
|
|
display->atom_wm_take_focus = atoms[2];
|
|
|
|
display->atom_wm_delete_window = atoms[3];
|
|
|
|
display->atom_wm_state = atoms[4];
|
|
|
|
display->atom_net_close_window = atoms[5];
|
|
|
|
display->atom_net_wm_state = atoms[6];
|
|
|
|
display->atom_motif_wm_hints = atoms[7];
|
|
|
|
display->atom_net_wm_state_shaded = atoms[8];
|
|
|
|
display->atom_net_wm_state_maximized_horz = atoms[9];
|
|
|
|
display->atom_net_wm_state_maximized_vert = atoms[10];
|
|
|
|
display->atom_net_wm_desktop = atoms[11];
|
|
|
|
display->atom_net_number_of_desktops = atoms[12];
|
2001-06-09 17:58:30 -04:00
|
|
|
display->atom_wm_change_state = atoms[13];
|
|
|
|
display->atom_sm_client_id = atoms[14];
|
|
|
|
display->atom_wm_client_leader = atoms[15];
|
|
|
|
display->atom_wm_window_role = atoms[16];
|
2001-06-09 23:17:15 -04:00
|
|
|
display->atom_net_current_desktop = atoms[17];
|
|
|
|
display->atom_net_supporting_wm_check = atoms[18];
|
2001-08-29 00:16:30 -04:00
|
|
|
display->atom_net_supported = atoms[19];
|
2001-06-09 23:17:15 -04:00
|
|
|
display->atom_net_wm_window_type = atoms[20];
|
|
|
|
display->atom_net_wm_window_type_desktop = atoms[21];
|
|
|
|
display->atom_net_wm_window_type_dock = atoms[22];
|
|
|
|
display->atom_net_wm_window_type_toolbar = atoms[23];
|
|
|
|
display->atom_net_wm_window_type_menu = atoms[24];
|
|
|
|
display->atom_net_wm_window_type_dialog = atoms[25];
|
|
|
|
display->atom_net_wm_window_type_normal = atoms[26];
|
|
|
|
display->atom_net_wm_state_modal = atoms[27];
|
2001-06-10 03:52:35 -04:00
|
|
|
display->atom_net_client_list = atoms[28];
|
|
|
|
display->atom_net_client_list_stacking = atoms[29];
|
2001-06-11 01:16:24 -04:00
|
|
|
display->atom_net_wm_state_skip_taskbar = atoms[30];
|
|
|
|
display->atom_net_wm_state_skip_pager = atoms[31];
|
2001-06-12 20:56:08 -04:00
|
|
|
display->atom_win_workspace = atoms[32];
|
2001-06-21 02:08:35 -04:00
|
|
|
display->atom_win_layer = atoms[33];
|
2001-06-23 01:49:35 -04:00
|
|
|
display->atom_win_protocols = atoms[34];
|
|
|
|
display->atom_win_supporting_wm_check = atoms[35];
|
2001-06-23 23:18:10 -04:00
|
|
|
display->atom_net_wm_icon_name = atoms[36];
|
|
|
|
display->atom_net_wm_icon = atoms[37];
|
2001-08-05 12:04:52 -04:00
|
|
|
display->atom_net_wm_icon_geometry = atoms[38];
|
2001-08-07 01:52:51 -04:00
|
|
|
display->atom_utf8_string = atoms[39];
|
2001-08-19 21:42:44 -04:00
|
|
|
display->atom_wm_icon_size = atoms[40];
|
2001-08-22 02:01:01 -04:00
|
|
|
display->atom_kwm_win_icon = atoms[41];
|
2001-08-29 00:16:30 -04:00
|
|
|
display->atom_net_wm_moveresize = atoms[42];
|
2001-10-07 19:06:19 -04:00
|
|
|
display->atom_net_active_window = atoms[43];
|
2001-10-15 00:14:58 -04:00
|
|
|
display->atom_metacity_restart_message = atoms[44];
|
2002-01-10 01:31:31 -05:00
|
|
|
display->atom_net_wm_strut = atoms[45];
|
|
|
|
display->atom_win_hints = atoms[46];
|
2002-02-06 22:07:56 -05:00
|
|
|
display->atom_metacity_reload_theme_message = atoms[47];
|
2002-02-08 01:01:58 -05:00
|
|
|
display->atom_metacity_set_keybindings_message = atoms[48];
|
2002-02-08 23:50:58 -05:00
|
|
|
display->atom_net_wm_state_hidden = atoms[49];
|
2002-02-09 01:54:44 -05:00
|
|
|
display->atom_net_wm_window_type_utility = atoms[50];
|
|
|
|
display->atom_net_wm_window_type_splashscreen = atoms[51];
|
2002-02-23 17:58:02 -05:00
|
|
|
display->atom_net_wm_state_fullscreen = atoms[52];
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
display->atom_net_wm_ping = atoms[53];
|
|
|
|
display->atom_net_wm_pid = atoms[54];
|
|
|
|
display->atom_wm_client_machine = atoms[55];
|
2002-04-28 11:47:21 -04:00
|
|
|
display->atom_net_wm_workarea = atoms[56];
|
2002-05-07 10:42:47 -04:00
|
|
|
display->atom_net_show_desktop = atoms[57];
|
2002-05-16 00:03:36 -04:00
|
|
|
display->atom_net_desktop_layout = atoms[58];
|
2002-04-28 11:47:21 -04:00
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
|
|
|
* created in screen_new
|
|
|
|
*/
|
|
|
|
display->leader_window = None;
|
2002-01-05 22:15:49 -05:00
|
|
|
display->no_focus_window = None;
|
|
|
|
|
2001-06-18 02:11:53 -04:00
|
|
|
screens = NULL;
|
2002-05-08 12:24:28 -04:00
|
|
|
|
|
|
|
#ifdef HAVE_GTK_MULTIHEAD
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
i = 0;
|
|
|
|
while (i < ScreenCount (xdisplay))
|
|
|
|
{
|
2001-05-30 23:30:58 -04:00
|
|
|
MetaScreen *screen;
|
|
|
|
|
|
|
|
screen = meta_screen_new (display, i);
|
|
|
|
|
|
|
|
if (screen)
|
|
|
|
screens = g_slist_prepend (screens, screen);
|
2001-05-30 11:36:31 -04:00
|
|
|
++i;
|
|
|
|
}
|
2001-06-17 15:53:45 -04:00
|
|
|
#else
|
2001-06-18 02:11:53 -04:00
|
|
|
{
|
|
|
|
MetaScreen *screen;
|
|
|
|
screen = meta_screen_new (display, DefaultScreen (xdisplay));
|
|
|
|
if (screen)
|
|
|
|
screens = g_slist_prepend (screens, screen);
|
|
|
|
}
|
2001-06-17 15:53:45 -04:00
|
|
|
#endif
|
2001-05-30 23:30:58 -04:00
|
|
|
|
|
|
|
if (screens == NULL)
|
|
|
|
{
|
|
|
|
/* This would typically happen because all the screens already
|
|
|
|
* have window managers
|
|
|
|
*/
|
2001-06-19 23:01:26 -04:00
|
|
|
#ifndef USE_GDK_DISPLAY
|
2001-05-30 23:30:58 -04:00
|
|
|
XCloseDisplay (xdisplay);
|
2001-06-19 23:01:26 -04:00
|
|
|
#endif
|
2001-05-30 23:30:58 -04:00
|
|
|
all_displays = g_slist_remove (all_displays, display);
|
|
|
|
g_free (display->name);
|
|
|
|
g_free (display);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
display->screens = screens;
|
2001-06-19 23:01:26 -04:00
|
|
|
|
|
|
|
#ifdef USE_GDK_DISPLAY
|
|
|
|
display->events = NULL;
|
|
|
|
|
|
|
|
/* Get events */
|
|
|
|
meta_ui_add_event_func (display->xdisplay,
|
|
|
|
event_callback,
|
|
|
|
display);
|
|
|
|
#else
|
2001-05-30 23:30:58 -04:00
|
|
|
display->events = meta_event_queue_new (display->xdisplay,
|
|
|
|
event_queue_callback,
|
|
|
|
display);
|
2001-06-19 23:01:26 -04:00
|
|
|
#endif
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
display->window_ids = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
|
2001-06-08 02:39:38 -04:00
|
|
|
|
2001-06-07 22:17:48 -04:00
|
|
|
display->double_click_time = 250;
|
|
|
|
display->last_button_time = 0;
|
|
|
|
display->last_button_xwindow = None;
|
|
|
|
display->last_button_num = 0;
|
|
|
|
display->is_double_click = FALSE;
|
2001-06-09 17:58:30 -04:00
|
|
|
|
2002-03-02 10:26:07 -05:00
|
|
|
i = 0;
|
|
|
|
while (i < N_IGNORED_SERIALS)
|
|
|
|
{
|
|
|
|
display->ignored_serials[i] = 0;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
display->ungrab_should_not_cause_focus_window = None;
|
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
display->current_time = CurrentTime;
|
2001-08-30 00:01:38 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
display->grab_op = META_GRAB_OP_NONE;
|
|
|
|
display->grab_window = NULL;
|
2002-03-17 12:22:23 -05:00
|
|
|
display->grab_resize_popup = NULL;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-08-07 01:52:51 -04:00
|
|
|
set_utf8_string_hint (display,
|
|
|
|
display->leader_window,
|
|
|
|
display->atom_net_wm_name,
|
|
|
|
"Metacity");
|
2001-06-23 02:54:28 -04:00
|
|
|
|
|
|
|
{
|
|
|
|
/* The legacy GNOME hint is to set a cardinal which is the window
|
|
|
|
* id of the supporting_wm_check window on the supporting_wm_check
|
|
|
|
* window itself
|
|
|
|
*/
|
|
|
|
gulong data[1];
|
|
|
|
|
|
|
|
data[0] = display->leader_window;
|
|
|
|
XChangeProperty (display->xdisplay,
|
|
|
|
display->leader_window,
|
|
|
|
display->atom_win_supporting_wm_check,
|
|
|
|
XA_CARDINAL,
|
|
|
|
32, PropModeReplace, (guchar*) data, 1);
|
|
|
|
}
|
2001-06-02 00:14:18 -04:00
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
/* Now manage all existing windows */
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
meta_screen_manage_all_windows (tmp->data);
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-06-03 14:33:59 -04:00
|
|
|
listify_func (gpointer key, gpointer value, gpointer data)
|
2001-05-30 11:36:31 -04:00
|
|
|
{
|
2001-06-03 14:33:59 -04:00
|
|
|
GSList **listp;
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2001-06-03 14:33:59 -04:00
|
|
|
listp = data;
|
|
|
|
*listp = g_slist_prepend (*listp, value);
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2001-06-03 14:33:59 -04:00
|
|
|
static gint
|
|
|
|
ptrcmp (gconstpointer a, gconstpointer b)
|
|
|
|
{
|
|
|
|
if (a < b)
|
|
|
|
return -1;
|
|
|
|
else if (a > b)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
2001-05-30 11:36:31 -04:00
|
|
|
}
|
|
|
|
|
2001-06-24 04:09:10 -04:00
|
|
|
GSList*
|
|
|
|
meta_display_list_windows (MetaDisplay *display)
|
2001-05-30 11:36:31 -04:00
|
|
|
{
|
2001-06-03 14:33:59 -04:00
|
|
|
GSList *winlist;
|
|
|
|
GSList *tmp;
|
2001-06-24 04:09:10 -04:00
|
|
|
GSList *prev;
|
2001-06-03 14:33:59 -04:00
|
|
|
|
|
|
|
winlist = NULL;
|
2001-05-30 11:36:31 -04:00
|
|
|
g_hash_table_foreach (display->window_ids,
|
2001-06-03 14:33:59 -04:00
|
|
|
listify_func,
|
|
|
|
&winlist);
|
|
|
|
|
2001-06-24 04:09:10 -04:00
|
|
|
/* Uniquify the list, since both frame windows and plain
|
|
|
|
* windows are in the hash
|
|
|
|
*/
|
2001-06-03 14:33:59 -04:00
|
|
|
winlist = g_slist_sort (winlist, ptrcmp);
|
|
|
|
|
2001-06-24 04:09:10 -04:00
|
|
|
prev = NULL;
|
|
|
|
tmp = winlist;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
GSList *next;
|
|
|
|
|
|
|
|
next = tmp->next;
|
|
|
|
|
|
|
|
if (next &&
|
|
|
|
next->data == tmp->data)
|
|
|
|
{
|
|
|
|
/* Delete tmp from list */
|
|
|
|
|
|
|
|
if (prev)
|
|
|
|
prev->next = next;
|
|
|
|
|
|
|
|
if (tmp == winlist)
|
|
|
|
winlist = next;
|
|
|
|
|
|
|
|
g_slist_free_1 (tmp);
|
|
|
|
|
|
|
|
/* leave prev unchanged */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prev = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return winlist;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_close (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *winlist;
|
|
|
|
GSList *tmp;
|
|
|
|
|
2002-02-24 14:58:27 -05:00
|
|
|
if (display->error_traps > 0)
|
2001-06-24 04:09:10 -04:00
|
|
|
meta_bug ("Display closed with error traps pending\n");
|
|
|
|
|
|
|
|
winlist = meta_display_list_windows (display);
|
|
|
|
|
2001-06-04 02:17:52 -04:00
|
|
|
/* Unmanage all windows */
|
|
|
|
meta_display_grab (display);
|
2001-06-03 14:33:59 -04:00
|
|
|
tmp = winlist;
|
|
|
|
while (tmp != NULL)
|
2001-06-04 00:58:22 -04:00
|
|
|
{
|
2001-06-24 04:09:10 -04:00
|
|
|
meta_window_free (tmp->data);
|
2001-06-03 14:33:59 -04:00
|
|
|
|
2001-06-04 00:58:22 -04:00
|
|
|
tmp = tmp->next;
|
2001-06-03 14:33:59 -04:00
|
|
|
}
|
|
|
|
g_slist_free (winlist);
|
2001-06-04 02:17:52 -04:00
|
|
|
meta_display_ungrab (display);
|
2001-06-04 00:58:22 -04:00
|
|
|
|
2002-05-23 22:23:46 -04:00
|
|
|
if (display->autoraise_timeout_id != 0)
|
|
|
|
{
|
|
|
|
g_source_remove (display->autoraise_timeout_id);
|
|
|
|
display->autoraise_timeout_id = 0;
|
|
|
|
}
|
|
|
|
|
2001-06-19 23:01:26 -04:00
|
|
|
#ifdef USE_GDK_DISPLAY
|
|
|
|
/* Stop caring about events */
|
|
|
|
meta_ui_remove_event_func (display->xdisplay,
|
|
|
|
event_callback,
|
|
|
|
display);
|
|
|
|
#endif
|
2002-01-04 17:18:10 -05:00
|
|
|
|
|
|
|
/* Free all screens */
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
meta_screen_free (screen);
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (display->screens);
|
|
|
|
display->screens = NULL;
|
2001-06-19 23:01:26 -04:00
|
|
|
|
2001-06-04 00:58:22 -04:00
|
|
|
/* Must be after all calls to meta_window_free() since they
|
|
|
|
* unregister windows
|
|
|
|
*/
|
|
|
|
g_hash_table_destroy (display->window_ids);
|
2001-06-09 17:58:30 -04:00
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (display->leader_window != None)
|
|
|
|
XDestroyWindow (display->xdisplay, display->leader_window);
|
2001-06-19 23:01:26 -04:00
|
|
|
|
|
|
|
#ifndef USE_GDK_DISPLAY
|
2001-05-30 11:36:31 -04:00
|
|
|
meta_event_queue_free (display->events);
|
|
|
|
XCloseDisplay (display->xdisplay);
|
2001-06-19 23:01:26 -04:00
|
|
|
#endif
|
2001-05-30 11:36:31 -04:00
|
|
|
g_free (display->name);
|
|
|
|
|
|
|
|
all_displays = g_slist_remove (all_displays, display);
|
2001-10-15 00:14:58 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_display_shutdown_keys (display);
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
g_free (display);
|
|
|
|
|
|
|
|
if (all_displays == NULL)
|
|
|
|
{
|
2001-05-30 23:30:58 -04:00
|
|
|
meta_verbose ("Last display closed, exiting\n");
|
2001-05-30 11:36:31 -04:00
|
|
|
meta_quit (META_EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MetaScreen*
|
|
|
|
meta_display_screen_for_root (MetaDisplay *display,
|
|
|
|
Window xroot)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
|
|
|
|
if (xroot == screen->xroot)
|
|
|
|
return screen;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-05-31 23:00:01 -04:00
|
|
|
MetaScreen*
|
|
|
|
meta_display_screen_for_x_screen (MetaDisplay *display,
|
|
|
|
Screen *xscreen)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
|
|
|
|
if (xscreen == screen->xscreen)
|
|
|
|
return screen;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
/* Grab/ungrab routines taken from fvwm */
|
|
|
|
void
|
|
|
|
meta_display_grab (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
if (display->server_grab_count == 0)
|
|
|
|
{
|
|
|
|
XSync (display->xdisplay, False);
|
|
|
|
XGrabServer (display->xdisplay);
|
|
|
|
}
|
|
|
|
XSync (display->xdisplay, False);
|
|
|
|
display->server_grab_count += 1;
|
2001-06-10 23:24:20 -04:00
|
|
|
meta_verbose ("Grabbing display, grab count now %d\n",
|
|
|
|
display->server_grab_count);
|
2001-05-31 02:42:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_ungrab (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
if (display->server_grab_count == 0)
|
|
|
|
meta_bug ("Ungrabbed non-grabbed server\n");
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
display->server_grab_count -= 1;
|
|
|
|
if (display->server_grab_count == 0)
|
|
|
|
{
|
2001-06-06 00:47:37 -04:00
|
|
|
/* FIXME we want to purge all pending "queued" stuff
|
|
|
|
* at this point, such as window hide/show
|
|
|
|
*/
|
2001-06-10 23:24:20 -04:00
|
|
|
XSync (display->xdisplay, False);
|
2001-05-31 02:42:58 -04:00
|
|
|
XUngrabServer (display->xdisplay);
|
|
|
|
}
|
|
|
|
XSync (display->xdisplay, False);
|
2001-06-10 23:24:20 -04:00
|
|
|
|
|
|
|
meta_verbose ("Ungrabbing display, grab count now %d\n",
|
|
|
|
display->server_grab_count);
|
2001-05-31 02:42:58 -04:00
|
|
|
}
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
MetaDisplay*
|
|
|
|
meta_display_for_x_display (Display *xdisplay)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
tmp = all_displays;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = tmp->data;
|
|
|
|
|
|
|
|
if (display->xdisplay == xdisplay)
|
|
|
|
return display;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
2002-03-06 17:27:24 -05:00
|
|
|
meta_warning ("Could not find display for X display %p, probably going to crash\n",
|
|
|
|
xdisplay);
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
GSList*
|
|
|
|
meta_displays_list (void)
|
|
|
|
{
|
|
|
|
return all_displays;
|
|
|
|
}
|
|
|
|
|
2001-06-07 22:17:48 -04:00
|
|
|
gboolean
|
|
|
|
meta_display_is_double_click (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->is_double_click;
|
|
|
|
}
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
static gboolean dump_events = TRUE;
|
|
|
|
|
2001-06-19 23:01:26 -04:00
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
static void
|
2001-06-19 23:01:26 -04:00
|
|
|
event_queue_callback (XEvent *event,
|
2001-05-30 11:36:31 -04:00
|
|
|
gpointer data)
|
2001-06-19 23:01:26 -04:00
|
|
|
{
|
|
|
|
event_callback (event, data);
|
|
|
|
}
|
|
|
|
|
2001-07-25 23:14:45 -04:00
|
|
|
static gboolean
|
|
|
|
grab_op_is_mouse (MetaGrabOp op)
|
|
|
|
{
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_MOVING:
|
|
|
|
case META_GRAB_OP_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_RESIZING_S:
|
|
|
|
case META_GRAB_OP_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_RESIZING_N:
|
|
|
|
case META_GRAB_OP_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_RESIZING_NW:
|
|
|
|
case META_GRAB_OP_RESIZING_W:
|
|
|
|
case META_GRAB_OP_RESIZING_E:
|
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
grab_op_is_keyboard (MetaGrabOp op)
|
|
|
|
{
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_KEYBOARD_MOVING:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
2001-08-19 14:09:10 -04:00
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
2002-04-05 10:52:49 -05:00
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
|
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
|
2001-07-25 23:14:45 -04:00
|
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
/* Get time of current event, or CurrentTime if none. */
|
|
|
|
guint32
|
|
|
|
meta_display_get_current_time (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
return display->current_time;
|
|
|
|
}
|
|
|
|
|
2002-03-02 10:26:07 -05:00
|
|
|
static void
|
|
|
|
add_ignored_serial (MetaDisplay *display,
|
|
|
|
unsigned long serial)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* don't add the same serial more than once */
|
|
|
|
if (display->ignored_serials[N_IGNORED_SERIALS-1] == serial)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* shift serials to the left */
|
|
|
|
i = 0;
|
|
|
|
while (i < (N_IGNORED_SERIALS - 1))
|
|
|
|
{
|
|
|
|
display->ignored_serials[i] = display->ignored_serials[i+1];
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
/* put new one on the end */
|
|
|
|
display->ignored_serials[i] = serial;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
serial_is_ignored (MetaDisplay *display,
|
|
|
|
unsigned long serial)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (i < N_IGNORED_SERIALS)
|
|
|
|
{
|
|
|
|
if (display->ignored_serials[i] == serial)
|
|
|
|
return TRUE;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reset_ignores (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (i < N_IGNORED_SERIALS)
|
|
|
|
{
|
|
|
|
display->ignored_serials[i] = 0;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
display->ungrab_should_not_cause_focus_window = None;
|
|
|
|
}
|
|
|
|
|
2002-05-23 22:23:46 -04:00
|
|
|
static gboolean
|
|
|
|
window_raise_with_delay_callback (void *data)
|
|
|
|
{
|
|
|
|
MetaWindow *window;
|
|
|
|
MetaAutoRaiseData *auto_raise;
|
|
|
|
|
|
|
|
auto_raise = data;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"In autoraise callback for window 0x%lx\n",
|
|
|
|
auto_raise->xwindow);
|
|
|
|
|
|
|
|
auto_raise->display->autoraise_timeout_id = 0;
|
|
|
|
|
|
|
|
window = meta_display_lookup_x_window (auto_raise->display,
|
|
|
|
auto_raise->xwindow);
|
|
|
|
|
|
|
|
if (window == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* If we aren't already on top, check whether the pointer is inside
|
|
|
|
* the window and raise the window if so.
|
|
|
|
*/
|
|
|
|
if (meta_stack_get_top (window->screen->stack) != window)
|
|
|
|
{
|
|
|
|
int x, y, root_x, root_y;
|
|
|
|
Window root, child;
|
|
|
|
unsigned int mask;
|
|
|
|
gboolean same_screen;
|
|
|
|
|
|
|
|
meta_error_trap_push (window->display);
|
|
|
|
same_screen = XQueryPointer (window->display->xdisplay,
|
|
|
|
window->xwindow,
|
|
|
|
&root, &child,
|
|
|
|
&root_x, &root_y, &x, &y, &mask);
|
|
|
|
meta_error_trap_pop (window->display);
|
|
|
|
|
|
|
|
if ((window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) ||
|
|
|
|
(window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect)))
|
|
|
|
meta_window_raise (window);
|
|
|
|
else
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Pointer not inside window, not raising %s\n",
|
|
|
|
window->desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2001-06-19 23:01:26 -04:00
|
|
|
static gboolean
|
|
|
|
event_callback (XEvent *event,
|
|
|
|
gpointer data)
|
2001-05-30 11:36:31 -04:00
|
|
|
{
|
|
|
|
MetaWindow *window;
|
|
|
|
MetaDisplay *display;
|
2001-06-02 21:33:27 -04:00
|
|
|
Window modified;
|
2001-07-11 02:22:00 -04:00
|
|
|
gboolean frame_was_receiver;
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
gboolean filter_out_event;
|
2001-05-31 02:42:58 -04:00
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
display = data;
|
|
|
|
|
|
|
|
if (dump_events)
|
|
|
|
meta_spew_event (display, event);
|
2002-01-03 18:28:19 -05:00
|
|
|
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
filter_out_event = FALSE;
|
2002-01-03 18:28:19 -05:00
|
|
|
display->current_time = event_get_time (display, event);
|
2002-03-02 10:26:07 -05:00
|
|
|
|
|
|
|
modified = event_get_modified_window (display, event);
|
2001-06-19 23:01:26 -04:00
|
|
|
|
2001-06-07 22:17:48 -04:00
|
|
|
if (event->type == ButtonPress)
|
|
|
|
{
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
/* filter out scrollwheel */
|
|
|
|
if (event->xbutton.button == 4 ||
|
|
|
|
event->xbutton.button == 5)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* mark double click events, kind of a hack, oh well. */
|
2002-02-06 22:07:56 -05:00
|
|
|
if (((int)event->xbutton.button) == display->last_button_num &&
|
2001-06-07 22:17:48 -04:00
|
|
|
event->xbutton.window == display->last_button_xwindow &&
|
|
|
|
event->xbutton.time < (display->last_button_time + display->double_click_time))
|
|
|
|
{
|
|
|
|
display->is_double_click = TRUE;
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_EVENTS,
|
|
|
|
"This was the second click of a double click\n");
|
|
|
|
|
2001-06-07 22:17:48 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
display->is_double_click = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
display->last_button_num = event->xbutton.button;
|
|
|
|
display->last_button_xwindow = event->xbutton.window;
|
|
|
|
display->last_button_time = event->xbutton.time;
|
|
|
|
}
|
2001-08-30 00:01:38 -04:00
|
|
|
else if (event->type == UnmapNotify)
|
|
|
|
{
|
|
|
|
if (meta_ui_window_should_not_cause_focus (display->xdisplay,
|
2002-03-02 10:26:07 -05:00
|
|
|
modified))
|
2001-08-30 00:01:38 -04:00
|
|
|
{
|
2002-03-02 10:26:07 -05:00
|
|
|
add_ignored_serial (display, event->xany.serial);
|
2002-02-07 22:34:26 -05:00
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2002-03-02 10:26:07 -05:00
|
|
|
"Adding EnterNotify serial %lu to ignored focus serials\n",
|
|
|
|
event->xany.serial);
|
2001-08-30 00:01:38 -04:00
|
|
|
}
|
|
|
|
}
|
2002-03-02 10:26:07 -05:00
|
|
|
else if (event->type == LeaveNotify &&
|
|
|
|
event->xcrossing.mode == NotifyUngrab &&
|
|
|
|
modified == display->ungrab_should_not_cause_focus_window)
|
|
|
|
{
|
|
|
|
add_ignored_serial (display, event->xany.serial);
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Adding LeaveNotify serial %lu to ignored focus serials\n",
|
|
|
|
event->xany.serial);
|
|
|
|
}
|
2001-06-02 21:33:27 -04:00
|
|
|
|
|
|
|
if (modified != None)
|
|
|
|
window = meta_display_lookup_x_window (display, modified);
|
|
|
|
else
|
|
|
|
window = NULL;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
frame_was_receiver = FALSE;
|
2001-06-02 21:33:27 -04:00
|
|
|
if (window &&
|
|
|
|
window->frame &&
|
|
|
|
modified == window->frame->xwindow)
|
2001-07-11 02:22:00 -04:00
|
|
|
frame_was_receiver = TRUE;
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case KeyPress:
|
|
|
|
case KeyRelease:
|
2001-07-25 23:58:24 -04:00
|
|
|
meta_display_process_key_event (display, window, event);
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case ButtonPress:
|
2001-07-25 23:14:45 -04:00
|
|
|
if ((grab_op_is_mouse (display->grab_op) &&
|
2002-02-06 22:07:56 -05:00
|
|
|
display->grab_button != (int) event->xbutton.button &&
|
2001-07-25 23:14:45 -04:00
|
|
|
display->grab_window == window) ||
|
|
|
|
grab_op_is_keyboard (display->grab_op))
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
|
|
|
meta_verbose ("Ending grab op %d on window %s due to button press\n",
|
|
|
|
display->grab_op,
|
|
|
|
display->grab_window->desc);
|
|
|
|
meta_display_end_grab_op (display,
|
|
|
|
event->xbutton.time);
|
2001-08-19 14:09:10 -04:00
|
|
|
}
|
2001-07-25 23:58:24 -04:00
|
|
|
else if (window && display->grab_op == META_GRAB_OP_NONE)
|
2001-07-25 23:14:45 -04:00
|
|
|
{
|
2001-07-25 23:58:24 -04:00
|
|
|
gboolean begin_move = FALSE;
|
2001-10-14 00:11:42 -04:00
|
|
|
guint grab_mask;
|
2002-02-08 01:50:09 -05:00
|
|
|
gboolean unmodified;
|
2001-10-14 00:11:42 -04:00
|
|
|
|
|
|
|
grab_mask = Mod1Mask;
|
|
|
|
if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS"))
|
|
|
|
grab_mask |= ControlMask;
|
2002-02-08 01:50:09 -05:00
|
|
|
|
|
|
|
/* Two possible sources of an unmodified event; one is a
|
|
|
|
* client that's letting button presses pass through to the
|
|
|
|
* frame, the other is our focus_window_grab on unmodified
|
|
|
|
* button 1. So for all such events we focus the window.
|
|
|
|
*/
|
|
|
|
unmodified = (event->xbutton.state & grab_mask) == 0;
|
2001-07-25 23:58:24 -04:00
|
|
|
|
2002-02-08 01:50:09 -05:00
|
|
|
if (unmodified ||
|
|
|
|
event->xbutton.button == 1)
|
2001-07-25 23:14:45 -04:00
|
|
|
{
|
2002-04-29 16:20:38 -04:00
|
|
|
meta_window_raise (window);
|
2001-12-10 23:03:58 -05:00
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2002-02-08 01:50:09 -05:00
|
|
|
"Focusing %s due to unmodified button %d press (display.c)\n",
|
|
|
|
window->desc, event->xbutton.button);
|
2001-07-25 23:14:45 -04:00
|
|
|
meta_window_focus (window, event->xbutton.time);
|
2001-07-25 23:58:24 -04:00
|
|
|
|
2002-02-08 01:50:09 -05:00
|
|
|
if (!frame_was_receiver && unmodified)
|
2001-12-10 23:03:58 -05:00
|
|
|
{
|
|
|
|
/* This is from our synchronous grab since
|
|
|
|
* it has no modifiers and was on the client window
|
|
|
|
*/
|
|
|
|
int mode;
|
|
|
|
|
2002-01-27 00:50:34 -05:00
|
|
|
/* When clicking a different app in click-to-focus
|
|
|
|
* in application-based mode, and the different
|
|
|
|
* app is not a dock or desktop, eat the focus click.
|
2001-12-10 23:03:58 -05:00
|
|
|
*/
|
|
|
|
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
|
2002-01-27 00:50:34 -05:00
|
|
|
meta_prefs_get_application_based () &&
|
2001-12-10 23:03:58 -05:00
|
|
|
!window->has_focus &&
|
|
|
|
window->type != META_WINDOW_DOCK &&
|
2002-01-27 00:50:34 -05:00
|
|
|
window->type != META_WINDOW_DESKTOP &&
|
|
|
|
(display->focus_window == NULL ||
|
|
|
|
!meta_window_same_application (window,
|
|
|
|
display->focus_window)))
|
2001-12-10 23:03:58 -05:00
|
|
|
mode = AsyncPointer; /* eat focus click */
|
|
|
|
else
|
|
|
|
mode = ReplayPointer; /* give event back */
|
|
|
|
|
|
|
|
XAllowEvents (display->xdisplay,
|
|
|
|
mode, event->xbutton.time);
|
|
|
|
}
|
|
|
|
|
2001-12-10 02:48:21 -05:00
|
|
|
/* you can move on alt-click but not on
|
2001-12-10 23:03:58 -05:00
|
|
|
* the click-to-focus
|
2001-12-10 02:48:21 -05:00
|
|
|
*/
|
2002-02-08 01:50:09 -05:00
|
|
|
if (!unmodified)
|
2001-12-10 02:48:21 -05:00
|
|
|
begin_move = TRUE;
|
2001-07-25 23:14:45 -04:00
|
|
|
}
|
|
|
|
else if (event->xbutton.button == 2)
|
|
|
|
{
|
2002-05-09 17:22:01 -04:00
|
|
|
if (window->has_resize_func)
|
|
|
|
{
|
|
|
|
gboolean north;
|
|
|
|
gboolean west;
|
|
|
|
int root_x, root_y;
|
|
|
|
MetaGrabOp op;
|
|
|
|
|
|
|
|
meta_window_get_position (window, &root_x, &root_y);
|
|
|
|
|
|
|
|
west = event->xbutton.x_root < (root_x + window->rect.width / 2);
|
|
|
|
north = event->xbutton.y_root < (root_y + window->rect.height / 2);
|
|
|
|
|
|
|
|
if (west && north)
|
|
|
|
op = META_GRAB_OP_RESIZING_NW;
|
|
|
|
else if (west)
|
|
|
|
op = META_GRAB_OP_RESIZING_SW;
|
|
|
|
else if (north)
|
|
|
|
op = META_GRAB_OP_RESIZING_NE;
|
|
|
|
else
|
|
|
|
op = META_GRAB_OP_RESIZING_SE;
|
|
|
|
|
|
|
|
meta_display_begin_grab_op (display,
|
|
|
|
window,
|
|
|
|
op,
|
|
|
|
TRUE,
|
|
|
|
event->xbutton.button,
|
|
|
|
0,
|
|
|
|
event->xbutton.time,
|
|
|
|
event->xbutton.x_root,
|
|
|
|
event->xbutton.y_root);
|
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
}
|
|
|
|
else if (event->xbutton.button == 3)
|
|
|
|
{
|
|
|
|
meta_window_show_menu (window,
|
|
|
|
event->xbutton.x_root,
|
|
|
|
event->xbutton.y_root,
|
|
|
|
event->xbutton.button,
|
|
|
|
event->xbutton.time);
|
|
|
|
}
|
2001-07-25 23:58:24 -04:00
|
|
|
|
|
|
|
if (begin_move && window->has_move_func)
|
|
|
|
{
|
|
|
|
meta_display_begin_grab_op (display,
|
|
|
|
window,
|
|
|
|
META_GRAB_OP_MOVING,
|
|
|
|
TRUE,
|
|
|
|
event->xbutton.button,
|
|
|
|
0,
|
|
|
|
event->xbutton.time,
|
|
|
|
event->xbutton.x_root,
|
|
|
|
event->xbutton.y_root);
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case ButtonRelease:
|
2001-07-25 23:14:45 -04:00
|
|
|
if (grab_op_is_mouse (display->grab_op) &&
|
|
|
|
display->grab_window == window)
|
|
|
|
meta_window_handle_mouse_grab_op_event (window, event);
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case MotionNotify:
|
2001-07-25 23:14:45 -04:00
|
|
|
if (grab_op_is_mouse (display->grab_op) &&
|
|
|
|
display->grab_window == window)
|
|
|
|
meta_window_handle_mouse_grab_op_event (window, event);
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case EnterNotify:
|
2001-06-04 00:58:22 -04:00
|
|
|
/* do this even if window->has_focus to avoid races */
|
2002-03-02 10:26:07 -05:00
|
|
|
if (window && !serial_is_ignored (display, event->xany.serial))
|
2001-09-16 17:50:27 -04:00
|
|
|
{
|
2001-12-09 19:38:21 -05:00
|
|
|
switch (meta_prefs_get_focus_mode ())
|
|
|
|
{
|
|
|
|
case META_FOCUS_MODE_SLOPPY:
|
|
|
|
case META_FOCUS_MODE_MOUSE:
|
2001-12-10 23:03:58 -05:00
|
|
|
if (window->type != META_WINDOW_DOCK &&
|
|
|
|
window->type != META_WINDOW_DESKTOP)
|
2002-01-03 18:28:19 -05:00
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
2002-03-02 10:26:07 -05:00
|
|
|
"Focusing %s due to enter notify with serial %lu\n",
|
|
|
|
window->desc, event->xany.serial);
|
|
|
|
|
2002-05-23 22:23:46 -04:00
|
|
|
meta_window_focus (window, event->xcrossing.time);
|
|
|
|
|
|
|
|
/* stop ignoring stuff */
|
|
|
|
reset_ignores (display);
|
|
|
|
|
|
|
|
if (meta_prefs_get_auto_raise ())
|
|
|
|
{
|
|
|
|
MetaAutoRaiseData *auto_raise_data;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Queuing an autoraise timeout for %s with delay %d\n",
|
|
|
|
window->desc,
|
|
|
|
meta_prefs_get_auto_raise_delay ());
|
|
|
|
|
|
|
|
auto_raise_data = g_new (MetaAutoRaiseData, 1);
|
|
|
|
auto_raise_data->display = window->display;
|
|
|
|
auto_raise_data->xwindow = window->xwindow;
|
|
|
|
|
|
|
|
if (display->autoraise_timeout_id != 0)
|
|
|
|
g_source_remove (display->autoraise_timeout_id);
|
|
|
|
|
|
|
|
display->autoraise_timeout_id =
|
|
|
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
|
|
|
meta_prefs_get_auto_raise_delay (),
|
|
|
|
window_raise_with_delay_callback,
|
|
|
|
auto_raise_data,
|
|
|
|
g_free);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Auto raise is disabled\n");
|
|
|
|
}
|
2002-01-03 18:28:19 -05:00
|
|
|
}
|
2001-12-09 19:38:21 -05:00
|
|
|
break;
|
|
|
|
case META_FOCUS_MODE_CLICK:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-09-16 17:50:27 -04:00
|
|
|
if (window->type == META_WINDOW_DOCK)
|
|
|
|
meta_window_raise (window);
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case LeaveNotify:
|
2001-09-16 17:50:27 -04:00
|
|
|
if (window)
|
|
|
|
{
|
2001-12-09 19:38:21 -05:00
|
|
|
switch (meta_prefs_get_focus_mode ())
|
|
|
|
{
|
|
|
|
case META_FOCUS_MODE_MOUSE:
|
|
|
|
/* This is kind of questionable; but we normally
|
|
|
|
* set focus to RevertToPointerRoot, so I guess
|
|
|
|
* leaving it on PointerRoot when nothing is focused
|
|
|
|
* is probably right. Anyway, unfocus the
|
|
|
|
* focused window.
|
|
|
|
*/
|
2002-05-23 22:55:54 -04:00
|
|
|
if (window->has_focus &&
|
|
|
|
event->xcrossing.mode != NotifyGrab &&
|
2002-05-23 23:09:21 -04:00
|
|
|
event->xcrossing.mode != NotifyUngrab &&
|
|
|
|
event->xcrossing.detail != NotifyInferior)
|
2002-01-03 18:28:19 -05:00
|
|
|
{
|
|
|
|
meta_verbose ("Unsetting focus from %s due to LeaveNotify\n",
|
|
|
|
window->desc);
|
|
|
|
XSetInputFocus (display->xdisplay,
|
2002-01-05 22:15:49 -05:00
|
|
|
display->no_focus_window,
|
2002-01-03 18:28:19 -05:00
|
|
|
RevertToPointerRoot,
|
|
|
|
event->xcrossing.time);
|
|
|
|
}
|
2001-12-09 19:38:21 -05:00
|
|
|
break;
|
|
|
|
case META_FOCUS_MODE_SLOPPY:
|
|
|
|
case META_FOCUS_MODE_CLICK:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-01-04 17:46:37 -05:00
|
|
|
if (window->type == META_WINDOW_DOCK &&
|
|
|
|
event->xcrossing.mode != NotifyGrab &&
|
2002-05-11 00:44:34 -04:00
|
|
|
event->xcrossing.mode != NotifyUngrab &&
|
|
|
|
!window->has_focus)
|
2001-09-16 17:50:27 -04:00
|
|
|
meta_window_lower (window);
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case FocusIn:
|
|
|
|
case FocusOut:
|
2001-06-04 00:58:22 -04:00
|
|
|
if (window)
|
2002-01-05 22:15:49 -05:00
|
|
|
{
|
|
|
|
meta_window_notify_focus (window, event);
|
|
|
|
}
|
|
|
|
else if (event->xany.window == display->no_focus_window)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Focus %s event received on no_focus_window 0x%lx "
|
|
|
|
"mode %s detail %s\n",
|
|
|
|
event->type == FocusIn ? "in" :
|
|
|
|
event->type == FocusOut ? "out" :
|
|
|
|
"???",
|
|
|
|
event->xany.window,
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_mode_to_string (event->xfocus.mode),
|
|
|
|
meta_event_detail_to_string (event->xfocus.mode));
|
2002-01-05 22:15:49 -05:00
|
|
|
}
|
|
|
|
else if (meta_display_screen_for_root (display,
|
|
|
|
event->xany.window) != NULL)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Focus %s event received on root window 0x%lx "
|
|
|
|
"mode %s detail %s\n",
|
|
|
|
event->type == FocusIn ? "in" :
|
|
|
|
event->type == FocusOut ? "out" :
|
|
|
|
"???",
|
|
|
|
event->xany.window,
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_mode_to_string (event->xfocus.mode),
|
|
|
|
meta_event_detail_to_string (event->xfocus.mode));
|
2002-01-05 22:15:49 -05:00
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case KeymapNotify:
|
|
|
|
break;
|
|
|
|
case Expose:
|
|
|
|
break;
|
|
|
|
case GraphicsExpose:
|
|
|
|
break;
|
|
|
|
case NoExpose:
|
|
|
|
break;
|
|
|
|
case VisibilityNotify:
|
|
|
|
break;
|
|
|
|
case CreateNotify:
|
|
|
|
break;
|
|
|
|
case DestroyNotify:
|
2001-06-02 21:33:27 -04:00
|
|
|
if (window)
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
2001-07-25 23:14:45 -04:00
|
|
|
if (display->grab_op != META_GRAB_OP_NONE &&
|
|
|
|
display->grab_window == window)
|
|
|
|
meta_display_end_grab_op (display, CurrentTime);
|
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
if (frame_was_receiver)
|
|
|
|
{
|
|
|
|
meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n",
|
|
|
|
window->frame->xwindow);
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
meta_window_destroy_frame (window->frame->window);
|
|
|
|
meta_error_trap_pop (display);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meta_window_free (window); /* Unmanage destroyed window */
|
|
|
|
}
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case UnmapNotify:
|
2001-07-25 23:14:45 -04:00
|
|
|
if (display->grab_op != META_GRAB_OP_NONE &&
|
|
|
|
display->grab_window == window)
|
2002-01-10 22:31:14 -05:00
|
|
|
meta_display_end_grab_op (display, CurrentTime);
|
2001-07-25 23:14:45 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
if (!frame_was_receiver && window)
|
2001-06-04 02:17:52 -04:00
|
|
|
{
|
2001-06-10 23:24:20 -04:00
|
|
|
if (window->unmaps_pending == 0)
|
|
|
|
{
|
2002-02-07 22:34:26 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
|
|
|
"Window %s withdrawn\n",
|
|
|
|
window->desc);
|
2001-06-23 14:30:27 -04:00
|
|
|
window->withdrawn = TRUE;
|
2001-06-10 23:24:20 -04:00
|
|
|
meta_window_free (window); /* Unmanage withdrawn window */
|
2002-01-10 22:31:14 -05:00
|
|
|
window = NULL;
|
2001-06-10 23:24:20 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
window->unmaps_pending -= 1;
|
2002-02-07 22:34:26 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
|
|
|
"Received pending unmap, %d now pending\n",
|
|
|
|
window->unmaps_pending);
|
2001-06-10 23:24:20 -04:00
|
|
|
}
|
2001-06-04 02:17:52 -04:00
|
|
|
}
|
2002-01-10 22:31:14 -05:00
|
|
|
|
|
|
|
/* Unfocus on UnmapNotify, do this after the possible
|
|
|
|
* window_free above so that window_free can see if window->has_focus
|
|
|
|
* and move focus to another window
|
|
|
|
*/
|
|
|
|
if (window)
|
|
|
|
meta_window_notify_focus (window, event);
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case MapNotify:
|
|
|
|
break;
|
|
|
|
case MapRequest:
|
2001-06-02 21:33:27 -04:00
|
|
|
if (window == NULL)
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
|
|
|
window = meta_window_new (display, event->xmaprequest.window,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
/* if frame was receiver it's some malicious send event or something */
|
|
|
|
else if (!frame_was_receiver && window)
|
2001-06-11 02:39:12 -04:00
|
|
|
{
|
|
|
|
if (window->minimized)
|
|
|
|
meta_window_unminimize (window);
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case ReparentNotify:
|
|
|
|
break;
|
|
|
|
case ConfigureNotify:
|
|
|
|
break;
|
|
|
|
case ConfigureRequest:
|
2001-06-02 21:33:27 -04:00
|
|
|
/* This comment and code is found in both twm and fvwm */
|
|
|
|
/*
|
|
|
|
* According to the July 27, 1988 ICCCM draft, we should ignore size and
|
|
|
|
* position fields in the WM_NORMAL_HINTS property when we map a window.
|
|
|
|
* Instead, we'll read the current geometry. Therefore, we should respond
|
|
|
|
* to configuration requests for windows which have never been mapped.
|
|
|
|
*/
|
|
|
|
if (window == NULL)
|
|
|
|
{
|
|
|
|
unsigned int xwcm;
|
|
|
|
XWindowChanges xwc;
|
|
|
|
|
|
|
|
xwcm = event->xconfigurerequest.value_mask &
|
|
|
|
(CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
|
|
|
|
|
|
|
|
xwc.x = event->xconfigurerequest.x;
|
|
|
|
xwc.y = event->xconfigurerequest.y;
|
|
|
|
xwc.width = event->xconfigurerequest.width;
|
|
|
|
xwc.height = event->xconfigurerequest.height;
|
|
|
|
xwc.border_width = event->xconfigurerequest.border_width;
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n",
|
2001-06-08 02:39:38 -04:00
|
|
|
xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
|
2001-08-03 00:20:27 -04:00
|
|
|
meta_error_trap_push (display);
|
2001-06-02 21:33:27 -04:00
|
|
|
XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
|
|
|
|
xwcm, &xwc);
|
2001-08-03 00:20:27 -04:00
|
|
|
meta_error_trap_pop (display);
|
2001-06-02 21:33:27 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-07-11 02:22:00 -04:00
|
|
|
if (!frame_was_receiver)
|
|
|
|
meta_window_configure_request (window, event);
|
2001-06-02 21:33:27 -04:00
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case GravityNotify:
|
|
|
|
break;
|
|
|
|
case ResizeRequest:
|
|
|
|
break;
|
|
|
|
case CirculateNotify:
|
|
|
|
break;
|
|
|
|
case CirculateRequest:
|
|
|
|
break;
|
|
|
|
case PropertyNotify:
|
2001-07-11 02:22:00 -04:00
|
|
|
if (window && !frame_was_receiver)
|
2001-06-02 21:33:27 -04:00
|
|
|
meta_window_property_notify (window, event);
|
2002-05-16 00:03:36 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
MetaScreen *screen;
|
|
|
|
|
|
|
|
screen = meta_display_screen_for_root (display,
|
|
|
|
event->xproperty.window);
|
|
|
|
|
|
|
|
if (screen)
|
|
|
|
{
|
|
|
|
if (event->xproperty.atom ==
|
|
|
|
display->atom_net_desktop_layout)
|
|
|
|
meta_screen_update_workspace_layout (screen);
|
|
|
|
}
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case SelectionClear:
|
|
|
|
break;
|
|
|
|
case SelectionRequest:
|
|
|
|
break;
|
|
|
|
case SelectionNotify:
|
|
|
|
break;
|
|
|
|
case ColormapNotify:
|
2002-05-09 18:34:00 -04:00
|
|
|
if (window && !frame_was_receiver)
|
|
|
|
window->colormap = event->xcolormap.colormap;
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case ClientMessage:
|
2001-06-07 01:18:10 -04:00
|
|
|
if (window)
|
2001-06-09 23:17:15 -04:00
|
|
|
{
|
2001-07-11 02:22:00 -04:00
|
|
|
if (!frame_was_receiver)
|
|
|
|
meta_window_client_message (window, event);
|
2001-06-09 23:17:15 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MetaScreen *screen;
|
|
|
|
|
|
|
|
screen = meta_display_screen_for_root (display,
|
|
|
|
event->xclient.window);
|
|
|
|
|
2001-10-07 19:06:19 -04:00
|
|
|
if (screen)
|
2001-06-09 23:17:15 -04:00
|
|
|
{
|
2001-10-07 19:06:19 -04:00
|
|
|
if (event->xclient.message_type ==
|
|
|
|
display->atom_net_current_desktop)
|
|
|
|
{
|
|
|
|
int space;
|
|
|
|
MetaWorkspace *workspace;
|
2001-06-09 23:17:15 -04:00
|
|
|
|
2001-10-07 19:06:19 -04:00
|
|
|
space = event->xclient.data.l[0];
|
2001-06-09 23:17:15 -04:00
|
|
|
|
2001-10-07 19:06:19 -04:00
|
|
|
meta_verbose ("Request to change current workspace to %d\n",
|
|
|
|
space);
|
2001-06-09 23:17:15 -04:00
|
|
|
|
2001-10-07 19:06:19 -04:00
|
|
|
workspace =
|
|
|
|
meta_display_get_workspace_by_screen_index (display,
|
|
|
|
screen,
|
|
|
|
space);
|
|
|
|
|
|
|
|
if (workspace)
|
|
|
|
meta_workspace_activate (workspace);
|
|
|
|
else
|
|
|
|
meta_verbose ("Don't know about workspace %d\n", space);
|
|
|
|
}
|
2002-03-10 13:36:08 -05:00
|
|
|
else if (event->xclient.message_type ==
|
|
|
|
display->atom_net_number_of_desktops)
|
|
|
|
{
|
|
|
|
int num_spaces;
|
|
|
|
|
|
|
|
num_spaces = event->xclient.data.l[0];
|
|
|
|
|
|
|
|
meta_verbose ("Request to set number of workspaces to %d\n",
|
|
|
|
num_spaces);
|
|
|
|
|
|
|
|
meta_prefs_set_num_workspaces (num_spaces);
|
|
|
|
}
|
2002-05-06 02:11:46 -04:00
|
|
|
else if (event->xclient.message_type ==
|
2002-05-07 10:42:47 -04:00
|
|
|
display->atom_net_show_desktop)
|
2002-05-06 02:11:46 -04:00
|
|
|
{
|
|
|
|
gboolean show_desktop;
|
|
|
|
|
|
|
|
show_desktop = event->xclient.data.l[0] != 0;
|
|
|
|
meta_verbose ("Request to %s desktop\n", show_desktop ? "show" : "hide");
|
|
|
|
|
|
|
|
if (show_desktop)
|
|
|
|
meta_display_show_desktop (display);
|
|
|
|
else
|
|
|
|
meta_display_unshow_desktop (display);
|
|
|
|
}
|
2001-10-15 00:14:58 -04:00
|
|
|
else if (event->xclient.message_type ==
|
|
|
|
display->atom_metacity_restart_message)
|
|
|
|
{
|
|
|
|
meta_verbose ("Received restart request\n");
|
|
|
|
meta_restart ();
|
|
|
|
}
|
2002-02-06 22:07:56 -05:00
|
|
|
else if (event->xclient.message_type ==
|
|
|
|
display->atom_metacity_reload_theme_message)
|
|
|
|
{
|
|
|
|
meta_verbose ("Received reload theme request\n");
|
|
|
|
meta_ui_set_current_theme (meta_prefs_get_theme (),
|
|
|
|
TRUE);
|
2002-02-06 22:25:34 -05:00
|
|
|
meta_display_retheme_all ();
|
2002-02-06 22:07:56 -05:00
|
|
|
}
|
2002-02-08 01:01:58 -05:00
|
|
|
else if (event->xclient.message_type ==
|
|
|
|
display->atom_metacity_set_keybindings_message)
|
|
|
|
{
|
|
|
|
meta_verbose ("Received set keybindings request = %d\n",
|
|
|
|
(int) event->xclient.data.l[0]);
|
|
|
|
meta_set_keybindings_disabled (!event->xclient.data.l[0]);
|
|
|
|
}
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
else if (event->xclient.message_type ==
|
|
|
|
display->atom_wm_protocols)
|
|
|
|
{
|
|
|
|
meta_verbose ("Received WM_PROTOCOLS message\n");
|
|
|
|
|
|
|
|
if ((Atom)event->xclient.data.l[0] == display->atom_net_wm_ping)
|
|
|
|
{
|
|
|
|
process_pong_message (display, event);
|
|
|
|
|
|
|
|
/* We don't want ping reply events going into
|
|
|
|
* the GTK+ event loop because gtk+ will treat
|
|
|
|
* them as ping requests and send more replies.
|
|
|
|
*/
|
|
|
|
filter_out_event = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2001-06-09 23:17:15 -04:00
|
|
|
}
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
case MappingNotify:
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Let XLib know that there is a new keyboard mapping.
|
|
|
|
*/
|
|
|
|
XRefreshKeyboardMapping (&event->xmapping);
|
|
|
|
meta_display_process_mapping_event (display, event);
|
2001-05-30 11:36:31 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2001-06-02 21:33:27 -04:00
|
|
|
}
|
2001-06-19 23:01:26 -04:00
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
display->current_time = CurrentTime;
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
return filter_out_event;
|
2001-05-30 11:36:31 -04:00
|
|
|
}
|
|
|
|
|
2001-06-02 21:33:27 -04:00
|
|
|
/* Return the window this has to do with, if any, rather
|
|
|
|
* than the frame or root window that was selecting
|
|
|
|
* for substructure
|
|
|
|
*/
|
|
|
|
static Window
|
|
|
|
event_get_modified_window (MetaDisplay *display,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case KeyPress:
|
|
|
|
case KeyRelease:
|
|
|
|
case ButtonPress:
|
|
|
|
case ButtonRelease:
|
|
|
|
case MotionNotify:
|
|
|
|
case FocusIn:
|
|
|
|
case FocusOut:
|
|
|
|
case KeymapNotify:
|
|
|
|
case Expose:
|
|
|
|
case GraphicsExpose:
|
|
|
|
case NoExpose:
|
|
|
|
case VisibilityNotify:
|
|
|
|
case ResizeRequest:
|
|
|
|
case PropertyNotify:
|
|
|
|
case SelectionClear:
|
|
|
|
case SelectionRequest:
|
|
|
|
case SelectionNotify:
|
|
|
|
case ColormapNotify:
|
|
|
|
case ClientMessage:
|
2001-06-04 00:58:22 -04:00
|
|
|
case EnterNotify:
|
|
|
|
case LeaveNotify:
|
2001-06-02 21:33:27 -04:00
|
|
|
return event->xany.window;
|
2001-06-04 00:58:22 -04:00
|
|
|
|
2001-06-02 21:33:27 -04:00
|
|
|
case CreateNotify:
|
|
|
|
return event->xcreatewindow.window;
|
|
|
|
|
|
|
|
case DestroyNotify:
|
|
|
|
return event->xdestroywindow.window;
|
|
|
|
|
|
|
|
case UnmapNotify:
|
|
|
|
return event->xunmap.window;
|
|
|
|
|
|
|
|
case MapNotify:
|
|
|
|
return event->xmap.window;
|
|
|
|
|
|
|
|
case MapRequest:
|
|
|
|
return event->xmaprequest.window;
|
|
|
|
|
|
|
|
case ReparentNotify:
|
|
|
|
return event->xreparent.window;
|
|
|
|
|
|
|
|
case ConfigureNotify:
|
|
|
|
return event->xconfigure.window;
|
|
|
|
|
|
|
|
case ConfigureRequest:
|
|
|
|
return event->xconfigurerequest.window;
|
|
|
|
|
|
|
|
case GravityNotify:
|
|
|
|
return event->xgravity.window;
|
|
|
|
|
|
|
|
case CirculateNotify:
|
|
|
|
return event->xcirculate.window;
|
|
|
|
|
|
|
|
case CirculateRequest:
|
|
|
|
return event->xcirculaterequest.window;
|
|
|
|
|
|
|
|
case MappingNotify:
|
|
|
|
return None;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
2001-06-10 15:23:28 -04:00
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
static guint32
|
|
|
|
event_get_time (MetaDisplay *display,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case KeyPress:
|
|
|
|
case KeyRelease:
|
|
|
|
return event->xkey.time;
|
|
|
|
|
|
|
|
case ButtonPress:
|
|
|
|
case ButtonRelease:
|
|
|
|
return event->xbutton.time;
|
|
|
|
|
|
|
|
case MotionNotify:
|
|
|
|
return event->xmotion.time;
|
|
|
|
|
|
|
|
case PropertyNotify:
|
|
|
|
return event->xproperty.time;
|
|
|
|
|
|
|
|
case SelectionClear:
|
|
|
|
case SelectionRequest:
|
|
|
|
case SelectionNotify:
|
|
|
|
return event->xselection.time;
|
|
|
|
|
|
|
|
case EnterNotify:
|
|
|
|
case LeaveNotify:
|
|
|
|
return event->xcrossing.time;
|
|
|
|
|
|
|
|
case FocusIn:
|
|
|
|
case FocusOut:
|
|
|
|
case KeymapNotify:
|
|
|
|
case Expose:
|
|
|
|
case GraphicsExpose:
|
|
|
|
case NoExpose:
|
|
|
|
case MapNotify:
|
|
|
|
case UnmapNotify:
|
|
|
|
case VisibilityNotify:
|
|
|
|
case ResizeRequest:
|
|
|
|
case ColormapNotify:
|
|
|
|
case ClientMessage:
|
|
|
|
case CreateNotify:
|
|
|
|
case DestroyNotify:
|
|
|
|
case MapRequest:
|
|
|
|
case ReparentNotify:
|
|
|
|
case ConfigureNotify:
|
|
|
|
case ConfigureRequest:
|
|
|
|
case GravityNotify:
|
|
|
|
case CirculateNotify:
|
|
|
|
case CirculateRequest:
|
|
|
|
case MappingNotify:
|
|
|
|
default:
|
|
|
|
return CurrentTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-05 22:15:49 -05:00
|
|
|
const char*
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_detail_to_string (int d)
|
2001-06-10 15:23:28 -04:00
|
|
|
{
|
2001-06-18 02:11:53 -04:00
|
|
|
const char *detail = "???";
|
2001-06-10 15:23:28 -04:00
|
|
|
switch (d)
|
|
|
|
{
|
2002-01-05 22:15:49 -05:00
|
|
|
/* We are an ancestor in the A<->B focus change relationship */
|
2001-06-10 15:23:28 -04:00
|
|
|
case NotifyAncestor:
|
|
|
|
detail = "NotifyAncestor";
|
|
|
|
break;
|
|
|
|
case NotifyDetailNone:
|
|
|
|
detail = "NotifyDetailNone";
|
|
|
|
break;
|
2002-01-05 22:15:49 -05:00
|
|
|
/* We are a descendant in the A<->B focus change relationship */
|
2001-06-10 15:23:28 -04:00
|
|
|
case NotifyInferior:
|
|
|
|
detail = "NotifyInferior";
|
2002-01-05 22:15:49 -05:00
|
|
|
break;
|
2001-06-10 15:23:28 -04:00
|
|
|
case NotifyNonlinear:
|
|
|
|
detail = "NotifyNonlinear";
|
|
|
|
break;
|
|
|
|
case NotifyNonlinearVirtual:
|
|
|
|
detail = "NotifyNonlinearVirtual";
|
|
|
|
break;
|
|
|
|
case NotifyPointer:
|
|
|
|
detail = "NotifyPointer";
|
|
|
|
break;
|
|
|
|
case NotifyPointerRoot:
|
|
|
|
detail = "NotifyPointerRoot";
|
|
|
|
break;
|
|
|
|
case NotifyVirtual:
|
|
|
|
detail = "NotifyVirtual";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return detail;
|
|
|
|
}
|
|
|
|
|
2002-01-05 22:15:49 -05:00
|
|
|
const char*
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_mode_to_string (int m)
|
2001-06-10 15:23:28 -04:00
|
|
|
{
|
2001-06-18 02:11:53 -04:00
|
|
|
const char *mode = "???";
|
2001-06-10 15:23:28 -04:00
|
|
|
switch (m)
|
|
|
|
{
|
|
|
|
case NotifyNormal:
|
|
|
|
mode = "NotifyNormal";
|
|
|
|
break;
|
|
|
|
case NotifyGrab:
|
|
|
|
mode = "NotifyGrab";
|
|
|
|
break;
|
|
|
|
case NotifyUngrab:
|
|
|
|
mode = "NotifyUngrab";
|
|
|
|
break;
|
2002-01-05 22:15:49 -05:00
|
|
|
/* not sure any X implementations are missing this, but
|
|
|
|
* it seems to be absent from some docs.
|
|
|
|
*/
|
|
|
|
#ifdef NotifyWhileGrabbed
|
|
|
|
case NotifyWhileGrabbed:
|
|
|
|
mode = "NotifyWhileGrabbed";
|
|
|
|
break;
|
|
|
|
#endif
|
2001-06-10 15:23:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
2002-03-11 23:34:17 -05:00
|
|
|
static const char*
|
2002-03-10 13:36:08 -05:00
|
|
|
stack_mode_to_string (int mode)
|
|
|
|
{
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case Above:
|
|
|
|
return "Above";
|
|
|
|
case Below:
|
|
|
|
return "Below";
|
|
|
|
case TopIf:
|
|
|
|
return "TopIf";
|
|
|
|
case BottomIf:
|
|
|
|
return "BottomIf";
|
|
|
|
case Opposite:
|
|
|
|
return "Opposite";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
2001-07-25 23:58:24 -04:00
|
|
|
static char*
|
|
|
|
key_event_description (Display *xdisplay,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
|
|
|
KeySym keysym;
|
|
|
|
|
|
|
|
keysym = XKeycodeToKeysym (xdisplay, event->xkey.keycode, 0);
|
|
|
|
|
|
|
|
return g_strdup_printf ("Key '%s' state 0x%x",
|
|
|
|
XKeysymToString (keysym), event->xkey.state);
|
|
|
|
}
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
static void
|
|
|
|
meta_spew_event (MetaDisplay *display,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
2002-02-07 22:34:26 -05:00
|
|
|
const char *name = NULL;
|
|
|
|
char *extra = NULL;
|
|
|
|
char *winname;
|
|
|
|
MetaScreen *screen;
|
|
|
|
|
|
|
|
/* filter overnumerous events */
|
|
|
|
if (event->type == Expose || event->type == MotionNotify ||
|
|
|
|
event->type == NoExpose)
|
|
|
|
return;
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case KeyPress:
|
|
|
|
name = "KeyPress";
|
|
|
|
extra = key_event_description (display->xdisplay, event);
|
|
|
|
break;
|
|
|
|
case KeyRelease:
|
|
|
|
name = "KeyRelease";
|
|
|
|
extra = key_event_description (display->xdisplay, event);
|
|
|
|
break;
|
|
|
|
case ButtonPress:
|
|
|
|
name = "ButtonPress";
|
|
|
|
break;
|
|
|
|
case ButtonRelease:
|
|
|
|
name = "ButtonRelease";
|
|
|
|
break;
|
|
|
|
case MotionNotify:
|
|
|
|
name = "MotionNotify";
|
2002-02-24 14:58:27 -05:00
|
|
|
extra = g_strdup_printf ("win: 0x%lx x: %d y: %d",
|
|
|
|
event->xmotion.window,
|
|
|
|
event->xmotion.x,
|
|
|
|
event->xmotion.y);
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case EnterNotify:
|
|
|
|
name = "EnterNotify";
|
2002-03-02 10:26:07 -05:00
|
|
|
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d",
|
2002-02-07 22:34:26 -05:00
|
|
|
event->xcrossing.window,
|
|
|
|
event->xcrossing.root,
|
|
|
|
event->xcrossing.subwindow,
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_mode_to_string (event->xcrossing.mode),
|
|
|
|
meta_event_detail_to_string (event->xcrossing.detail),
|
|
|
|
event->xcrossing.focus);
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case LeaveNotify:
|
|
|
|
name = "LeaveNotify";
|
2002-03-02 10:26:07 -05:00
|
|
|
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d",
|
2002-02-07 22:34:26 -05:00
|
|
|
event->xcrossing.window,
|
|
|
|
event->xcrossing.root,
|
|
|
|
event->xcrossing.subwindow,
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_mode_to_string (event->xcrossing.mode),
|
|
|
|
meta_event_detail_to_string (event->xcrossing.detail),
|
|
|
|
event->xcrossing.focus);
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case FocusIn:
|
|
|
|
name = "FocusIn";
|
|
|
|
extra = g_strdup_printf ("detail: %s mode: %s\n",
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_detail_to_string (event->xfocus.detail),
|
|
|
|
meta_event_mode_to_string (event->xfocus.mode));
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case FocusOut:
|
|
|
|
name = "FocusOut";
|
|
|
|
extra = g_strdup_printf ("detail: %s mode: %s\n",
|
2002-03-02 10:26:07 -05:00
|
|
|
meta_event_detail_to_string (event->xfocus.detail),
|
|
|
|
meta_event_mode_to_string (event->xfocus.mode));
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case KeymapNotify:
|
|
|
|
name = "KeymapNotify";
|
|
|
|
break;
|
|
|
|
case Expose:
|
|
|
|
name = "Expose";
|
|
|
|
break;
|
|
|
|
case GraphicsExpose:
|
|
|
|
name = "GraphicsExpose";
|
|
|
|
break;
|
|
|
|
case NoExpose:
|
|
|
|
name = "NoExpose";
|
|
|
|
break;
|
|
|
|
case VisibilityNotify:
|
|
|
|
name = "VisibilityNotify";
|
|
|
|
break;
|
|
|
|
case CreateNotify:
|
|
|
|
name = "CreateNotify";
|
|
|
|
break;
|
|
|
|
case DestroyNotify:
|
|
|
|
name = "DestroyNotify";
|
|
|
|
break;
|
|
|
|
case UnmapNotify:
|
|
|
|
name = "UnmapNotify";
|
|
|
|
break;
|
|
|
|
case MapNotify:
|
|
|
|
name = "MapNotify";
|
|
|
|
break;
|
|
|
|
case MapRequest:
|
|
|
|
name = "MapRequest";
|
|
|
|
break;
|
|
|
|
case ReparentNotify:
|
|
|
|
name = "ReparentNotify";
|
|
|
|
break;
|
|
|
|
case ConfigureNotify:
|
|
|
|
name = "ConfigureNotify";
|
|
|
|
extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx",
|
|
|
|
event->xconfigure.x,
|
|
|
|
event->xconfigure.y,
|
|
|
|
event->xconfigure.width,
|
|
|
|
event->xconfigure.height,
|
|
|
|
event->xconfigure.above);
|
|
|
|
break;
|
|
|
|
case ConfigureRequest:
|
|
|
|
name = "ConfigureRequest";
|
2002-03-11 23:34:17 -05:00
|
|
|
extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s",
|
2002-02-07 22:34:26 -05:00
|
|
|
event->xconfigurerequest.parent,
|
|
|
|
event->xconfigurerequest.window,
|
|
|
|
event->xconfigurerequest.x,
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWX ? "" : "(unset) ",
|
|
|
|
event->xconfigurerequest.y,
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWY ? "" : "(unset) ",
|
|
|
|
event->xconfigurerequest.width,
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWWidth ? "" : "(unset) ",
|
|
|
|
event->xconfigurerequest.height,
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWHeight ? "" : "(unset) ",
|
|
|
|
event->xconfigurerequest.border_width,
|
|
|
|
event->xconfigurerequest.value_mask &
|
2002-03-10 13:36:08 -05:00
|
|
|
CWBorderWidth ? "" : "(unset)",
|
|
|
|
event->xconfigurerequest.above,
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWSibling ? "" : "(unset)",
|
|
|
|
stack_mode_to_string (event->xconfigurerequest.detail),
|
|
|
|
event->xconfigurerequest.value_mask &
|
|
|
|
CWStackMode ? "" : "(unset)");
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case GravityNotify:
|
|
|
|
name = "GravityNotify";
|
|
|
|
break;
|
|
|
|
case ResizeRequest:
|
|
|
|
name = "ResizeRequest";
|
2002-03-10 10:48:38 -05:00
|
|
|
extra = g_strdup_printf ("width = %d height = %d",
|
|
|
|
event->xresizerequest.width,
|
|
|
|
event->xresizerequest.height);
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
case CirculateNotify:
|
|
|
|
name = "CirculateNotify";
|
|
|
|
break;
|
|
|
|
case CirculateRequest:
|
|
|
|
name = "CirculateRequest";
|
|
|
|
break;
|
|
|
|
case PropertyNotify:
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
const char *state;
|
2001-06-10 23:24:20 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
name = "PropertyNotify";
|
2001-06-10 23:24:20 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
meta_error_trap_push (display);
|
|
|
|
str = XGetAtomName (display->xdisplay,
|
|
|
|
event->xproperty.atom);
|
|
|
|
meta_error_trap_pop (display);
|
|
|
|
|
|
|
|
if (event->xproperty.state == PropertyNewValue)
|
|
|
|
state = "PropertyNewValue";
|
|
|
|
else if (event->xproperty.state == PropertyDelete)
|
|
|
|
state = "PropertyDelete";
|
|
|
|
else
|
|
|
|
state = "???";
|
2001-06-10 23:24:20 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
extra = g_strdup_printf ("atom: %s state: %s",
|
|
|
|
str ? str : "(unknown atom)",
|
|
|
|
state);
|
|
|
|
XFree (str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SelectionClear:
|
|
|
|
name = "SelectionClear";
|
|
|
|
break;
|
|
|
|
case SelectionRequest:
|
|
|
|
name = "SelectionRequest";
|
|
|
|
break;
|
|
|
|
case SelectionNotify:
|
|
|
|
name = "SelectionNotify";
|
|
|
|
break;
|
|
|
|
case ColormapNotify:
|
|
|
|
name = "ColormapNotify";
|
|
|
|
break;
|
|
|
|
case ClientMessage:
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
name = "ClientMessage";
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
str = XGetAtomName (display->xdisplay,
|
|
|
|
event->xclient.message_type);
|
|
|
|
meta_error_trap_pop (display);
|
|
|
|
extra = g_strdup_printf ("type: %s format: %d\n",
|
|
|
|
str ? str : "(unknown atom)",
|
|
|
|
event->xclient.format);
|
|
|
|
XFree (str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MappingNotify:
|
|
|
|
name = "MappingNotify";
|
|
|
|
break;
|
|
|
|
default:
|
2002-03-02 10:26:07 -05:00
|
|
|
name = "(Unknown event)";
|
|
|
|
extra = g_strdup_printf ("type: %d", event->xany.type);
|
2002-02-07 22:34:26 -05:00
|
|
|
break;
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
screen = meta_display_screen_for_root (display, event->xany.window);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
if (screen)
|
|
|
|
winname = g_strdup_printf ("root %d", screen->number);
|
|
|
|
else
|
|
|
|
winname = g_strdup_printf ("0x%lx", event->xany.window);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
meta_topic (META_DEBUG_EVENTS,
|
2002-03-02 10:26:07 -05:00
|
|
|
"%s on %s%s %s %sserial %lu\n", name, winname,
|
2002-02-07 22:34:26 -05:00
|
|
|
extra ? ":" : "", extra ? extra : "",
|
2002-03-02 10:26:07 -05:00
|
|
|
event->xany.send_event ? "SEND " : "",
|
2002-02-07 22:34:26 -05:00
|
|
|
event->xany.serial);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
g_free (winname);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-02-07 22:34:26 -05:00
|
|
|
if (extra)
|
|
|
|
g_free (extra);
|
2001-05-30 11:36:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
MetaWindow*
|
2001-05-31 02:42:58 -04:00
|
|
|
meta_display_lookup_x_window (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2001-05-30 11:36:31 -04:00
|
|
|
{
|
|
|
|
return g_hash_table_lookup (display->window_ids, &xwindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-05-31 02:42:58 -04:00
|
|
|
meta_display_register_x_window (MetaDisplay *display,
|
|
|
|
Window *xwindowp,
|
|
|
|
MetaWindow *window)
|
2001-05-30 11:36:31 -04:00
|
|
|
{
|
2001-05-31 02:42:58 -04:00
|
|
|
g_return_if_fail (g_hash_table_lookup (display->window_ids, xwindowp) == NULL);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
g_hash_table_insert (display->window_ids, xwindowp, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_unregister_x_window (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
|
|
|
{
|
|
|
|
g_return_if_fail (g_hash_table_lookup (display->window_ids, &xwindow) != NULL);
|
|
|
|
|
|
|
|
g_hash_table_remove (display->window_ids, &xwindow);
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
|
|
|
|
/* Remove any pending pings */
|
|
|
|
remove_pending_pings_for_window (display, xwindow);
|
2001-05-30 11:36:31 -04:00
|
|
|
}
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
MetaWorkspace*
|
|
|
|
meta_display_get_workspace_by_index (MetaDisplay *display,
|
2002-02-06 22:07:56 -05:00
|
|
|
int idx)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
GList *tmp;
|
2001-08-03 09:56:39 -04:00
|
|
|
|
|
|
|
/* should be robust, index is maybe from an app */
|
2002-02-06 22:07:56 -05:00
|
|
|
if (idx < 0)
|
2001-08-03 09:56:39 -04:00
|
|
|
return NULL;
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-02-06 22:07:56 -05:00
|
|
|
tmp = g_list_nth (display->workspaces, idx);
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
if (tmp == NULL)
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return tmp->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
MetaWorkspace*
|
|
|
|
meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
2002-02-06 22:07:56 -05:00
|
|
|
int idx)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
int i;
|
|
|
|
|
2002-02-06 22:07:56 -05:00
|
|
|
/* should be robust, idx is maybe from an app */
|
|
|
|
if (idx < 0)
|
2001-08-03 09:56:39 -04:00
|
|
|
return NULL;
|
|
|
|
|
2001-06-06 00:47:37 -04:00
|
|
|
i = 0;
|
|
|
|
tmp = display->workspaces;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWorkspace *w = tmp->data;
|
|
|
|
|
|
|
|
if (w->screen == screen)
|
|
|
|
{
|
2002-02-06 22:07:56 -05:00
|
|
|
if (i == idx)
|
2001-06-06 00:47:37 -04:00
|
|
|
return w;
|
|
|
|
else
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-07-25 23:14:45 -04:00
|
|
|
Cursor
|
|
|
|
meta_display_create_x_cursor (MetaDisplay *display,
|
|
|
|
MetaCursor cursor)
|
|
|
|
{
|
|
|
|
Cursor xcursor;
|
|
|
|
guint glyph;
|
|
|
|
|
|
|
|
switch (cursor)
|
|
|
|
{
|
|
|
|
case META_CURSOR_DEFAULT:
|
|
|
|
glyph = XC_left_ptr;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_NORTH_RESIZE:
|
|
|
|
glyph = XC_top_side;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_SOUTH_RESIZE:
|
|
|
|
glyph = XC_bottom_side;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_WEST_RESIZE:
|
|
|
|
glyph = XC_left_side;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_EAST_RESIZE:
|
|
|
|
glyph = XC_right_side;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_SE_RESIZE:
|
|
|
|
glyph = XC_bottom_right_corner;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_SW_RESIZE:
|
|
|
|
glyph = XC_bottom_left_corner;
|
|
|
|
break;
|
|
|
|
case META_CURSOR_NE_RESIZE:
|
2002-01-19 18:59:11 -05:00
|
|
|
glyph = XC_top_right_corner;
|
2001-07-25 23:14:45 -04:00
|
|
|
break;
|
|
|
|
case META_CURSOR_NW_RESIZE:
|
2002-01-19 18:59:11 -05:00
|
|
|
glyph = XC_top_left_corner;
|
2001-07-25 23:14:45 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
glyph = 0; /* silence compiler */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
|
|
|
|
|
|
|
return xcursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Cursor
|
|
|
|
xcursor_for_op (MetaDisplay *display,
|
|
|
|
MetaGrabOp op)
|
|
|
|
{
|
|
|
|
MetaCursor cursor = META_CURSOR_DEFAULT;
|
|
|
|
|
2002-02-24 14:58:27 -05:00
|
|
|
switch (op)
|
2001-07-25 23:14:45 -04:00
|
|
|
{
|
|
|
|
case META_GRAB_OP_RESIZING_SE:
|
|
|
|
cursor = META_CURSOR_SE_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_S:
|
|
|
|
cursor = META_CURSOR_SOUTH_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_SW:
|
|
|
|
cursor = META_CURSOR_SW_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_N:
|
|
|
|
cursor = META_CURSOR_NORTH_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_NE:
|
|
|
|
cursor = META_CURSOR_NE_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_NW:
|
|
|
|
cursor = META_CURSOR_NW_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_W:
|
|
|
|
cursor = META_CURSOR_WEST_RESIZE;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_RESIZING_E:
|
|
|
|
cursor = META_CURSOR_EAST_RESIZE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return meta_display_create_x_cursor (display, cursor);
|
|
|
|
}
|
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
gboolean
|
|
|
|
meta_display_begin_grab_op (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaGrabOp op,
|
|
|
|
gboolean pointer_already_grabbed,
|
|
|
|
int button,
|
|
|
|
gulong modmask,
|
|
|
|
Time timestamp,
|
|
|
|
int root_x,
|
|
|
|
int root_y)
|
|
|
|
{
|
2002-03-02 10:26:07 -05:00
|
|
|
Window grab_xwindow;
|
2001-07-25 23:14:45 -04:00
|
|
|
Cursor cursor;
|
|
|
|
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
|
|
|
|
op, window->desc, button, pointer_already_grabbed);
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
if (display->grab_op != META_GRAB_OP_NONE)
|
|
|
|
{
|
|
|
|
meta_warning ("Attempt to perform window operation %d on window %s when operation %d on %s already in effect\n",
|
|
|
|
op, window->desc, display->grab_op, display->grab_window->desc);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
|
2002-03-02 10:26:07 -05:00
|
|
|
grab_xwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
if (pointer_already_grabbed)
|
2001-07-25 23:14:45 -04:00
|
|
|
display->grab_have_pointer = TRUE;
|
|
|
|
|
|
|
|
cursor = xcursor_for_op (display, op);
|
2002-02-24 14:58:27 -05:00
|
|
|
|
|
|
|
#define GRAB_MASK (PointerMotionMask | PointerMotionHintMask | \
|
|
|
|
ButtonPressMask | ButtonReleaseMask)
|
|
|
|
|
2001-07-25 23:14:45 -04:00
|
|
|
meta_error_trap_push (display);
|
|
|
|
if (XGrabPointer (display->xdisplay,
|
2002-03-02 10:26:07 -05:00
|
|
|
grab_xwindow,
|
2001-07-25 23:14:45 -04:00
|
|
|
False,
|
2002-02-24 14:58:27 -05:00
|
|
|
GRAB_MASK,
|
2001-07-25 23:14:45 -04:00
|
|
|
GrabModeAsync, GrabModeAsync,
|
|
|
|
None,
|
|
|
|
cursor,
|
|
|
|
timestamp) == GrabSuccess)
|
2001-08-29 00:16:30 -04:00
|
|
|
{
|
|
|
|
display->grab_have_pointer = TRUE;
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"XGrabPointer() returned GrabSuccess\n");
|
|
|
|
}
|
|
|
|
if (meta_error_trap_pop (display) != Success)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"Error trapped from XGrabPointer()\n");
|
|
|
|
if (display->grab_have_pointer)
|
|
|
|
display->grab_have_pointer = FALSE;
|
2001-08-29 00:16:30 -04:00
|
|
|
}
|
2002-02-24 14:58:27 -05:00
|
|
|
#undef GRAB_MASK
|
2001-07-25 23:14:45 -04:00
|
|
|
|
|
|
|
XFreeCursor (display->xdisplay, cursor);
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
if (!display->grab_have_pointer)
|
|
|
|
{
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"XGrabPointer() failed\n");
|
2001-07-11 02:22:00 -04:00
|
|
|
return FALSE;
|
|
|
|
}
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
if (grab_op_is_keyboard (op))
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
|
|
|
if (meta_window_grab_all_keys (window))
|
|
|
|
display->grab_have_keyboard = TRUE;
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
if (!display->grab_have_keyboard)
|
|
|
|
{
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"grabbing all keys failed\n");
|
2001-07-11 02:22:00 -04:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
display->grab_op = op;
|
|
|
|
display->grab_window = window;
|
2002-03-02 10:26:07 -05:00
|
|
|
display->grab_xwindow = grab_xwindow;
|
2001-07-11 02:22:00 -04:00
|
|
|
display->grab_button = button;
|
2002-04-28 00:52:26 -04:00
|
|
|
display->grab_mask = modmask;
|
2001-07-11 02:22:00 -04:00
|
|
|
display->grab_root_x = root_x;
|
|
|
|
display->grab_root_y = root_y;
|
2001-09-10 22:57:05 -04:00
|
|
|
display->grab_initial_window_pos = display->grab_window->rect;
|
2001-07-12 01:53:56 -04:00
|
|
|
meta_window_get_position (display->grab_window,
|
|
|
|
&display->grab_initial_window_pos.x,
|
|
|
|
&display->grab_initial_window_pos.y);
|
|
|
|
|
2002-02-24 14:58:27 -05:00
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"Grab op %d on window %s successful\n",
|
|
|
|
display->grab_op, display->grab_window->desc);
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
g_assert (display->grab_window != NULL);
|
|
|
|
g_assert (display->grab_op != META_GRAB_OP_NONE);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
/* Do this last, after everything is set up. */
|
2002-03-17 12:22:23 -05:00
|
|
|
switch (op)
|
|
|
|
{
|
2002-04-05 10:52:49 -05:00
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
|
|
|
|
meta_screen_ensure_tab_popup (window->screen,
|
|
|
|
META_TAB_LIST_NORMAL);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
|
|
|
|
meta_screen_ensure_tab_popup (window->screen,
|
|
|
|
META_TAB_LIST_DOCKS);
|
2002-03-17 12:22:23 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_window_refresh_resize_popup (display->grab_window);
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_end_grab_op (MetaDisplay *display,
|
|
|
|
Time timestamp)
|
|
|
|
{
|
|
|
|
if (display->grab_op == META_GRAB_OP_NONE)
|
|
|
|
return;
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
if (display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_NORMAL ||
|
|
|
|
display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_DOCK)
|
2001-08-19 14:09:10 -04:00
|
|
|
{
|
|
|
|
meta_ui_tab_popup_free (display->grab_window->screen->tab_popup);
|
|
|
|
display->grab_window->screen->tab_popup = NULL;
|
2002-03-02 10:26:07 -05:00
|
|
|
|
|
|
|
/* If the ungrab here causes an EnterNotify, ignore it for
|
|
|
|
* sloppy focus
|
|
|
|
*/
|
|
|
|
display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
|
2001-08-19 14:09:10 -04:00
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
if (display->grab_have_pointer)
|
2002-03-02 10:26:07 -05:00
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"Ungrabbing pointer with timestamp %lu\n",
|
|
|
|
timestamp);
|
|
|
|
XUngrabPointer (display->xdisplay, timestamp);
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
if (display->grab_have_keyboard)
|
2002-03-02 10:26:07 -05:00
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
|
|
|
"Ungrabbing all keys\n");
|
|
|
|
meta_window_ungrab_all_keys (display->grab_window);
|
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
display->grab_window = NULL;
|
2002-03-02 10:26:07 -05:00
|
|
|
display->grab_xwindow = None;
|
2001-07-25 23:14:45 -04:00
|
|
|
display->grab_op = META_GRAB_OP_NONE;
|
2002-03-17 12:22:23 -05:00
|
|
|
|
|
|
|
if (display->grab_resize_popup)
|
|
|
|
{
|
|
|
|
meta_ui_resize_popup_free (display->grab_resize_popup);
|
|
|
|
display->grab_resize_popup = NULL;
|
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
}
|
|
|
|
|
2001-10-26 00:00:38 -04:00
|
|
|
static void
|
|
|
|
meta_change_button_grab (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
gboolean grab,
|
2001-12-10 23:03:58 -05:00
|
|
|
gboolean sync,
|
2001-10-26 00:00:38 -04:00
|
|
|
int button,
|
|
|
|
int modmask)
|
|
|
|
{
|
|
|
|
int ignored_mask;
|
|
|
|
|
|
|
|
ignored_mask = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
while (ignored_mask < (int) display->ignored_modifier_mask)
|
2001-10-26 00:00:38 -04:00
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
if (ignored_mask & ~(display->ignored_modifier_mask))
|
2001-10-26 00:00:38 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Not a combination of ignored modifiers
|
2001-10-26 00:00:38 -04:00
|
|
|
* (it contains some non-ignored modifiers)
|
|
|
|
*/
|
|
|
|
++ignored_mask;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
if (grab)
|
|
|
|
XGrabButton (display->xdisplay, button, modmask | ignored_mask,
|
|
|
|
xwindow, False,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
PointerMotionMask | PointerMotionHintMask,
|
2001-12-10 23:03:58 -05:00
|
|
|
sync ? GrabModeSync : GrabModeAsync,
|
|
|
|
GrabModeAsync,
|
2001-10-26 00:00:38 -04:00
|
|
|
False, None);
|
|
|
|
else
|
|
|
|
XUngrabButton (display->xdisplay, button, modmask | ignored_mask,
|
|
|
|
xwindow);
|
|
|
|
|
|
|
|
result = meta_error_trap_pop (display);
|
|
|
|
|
|
|
|
if (result != Success)
|
2002-03-06 22:46:12 -05:00
|
|
|
meta_verbose ("Failed to grab button %d with mask 0x%x for window 0x%lx error code %d\n",
|
2001-10-26 00:00:38 -04:00
|
|
|
button, modmask | ignored_mask, xwindow, result);
|
|
|
|
|
|
|
|
++ignored_mask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-25 23:14:45 -04:00
|
|
|
void
|
|
|
|
meta_display_grab_window_buttons (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
|
|
|
{
|
|
|
|
/* Grab Alt + button1 and Alt + button2 for moving window,
|
|
|
|
* and Alt + button3 for popping up window menu.
|
|
|
|
*/
|
2001-07-25 23:58:24 -04:00
|
|
|
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
/* FIXME If we ignored errors here instead of spewing, we could
|
|
|
|
* put one big error trap around the loop and avoid a bunch of
|
|
|
|
* XSync()
|
|
|
|
*/
|
2001-07-25 23:58:24 -04:00
|
|
|
|
2001-07-25 23:14:45 -04:00
|
|
|
{
|
2001-10-26 00:00:38 -04:00
|
|
|
gboolean debug = g_getenv ("METACITY_DEBUG_BUTTON_GRABS") != NULL;
|
2001-07-25 23:14:45 -04:00
|
|
|
int i = 1;
|
|
|
|
while (i < 4)
|
|
|
|
{
|
2001-10-26 00:00:38 -04:00
|
|
|
meta_change_button_grab (display,
|
|
|
|
xwindow,
|
|
|
|
TRUE,
|
2001-12-10 23:03:58 -05:00
|
|
|
FALSE,
|
2001-10-26 00:00:38 -04:00
|
|
|
i, Mod1Mask);
|
|
|
|
|
|
|
|
|
|
|
|
/* This is for debugging, since I end up moving the Xnest
|
|
|
|
* otherwise ;-)
|
2001-10-14 00:11:42 -04:00
|
|
|
*/
|
2001-10-26 00:00:38 -04:00
|
|
|
if (debug)
|
|
|
|
meta_change_button_grab (display, xwindow,
|
|
|
|
TRUE,
|
2001-12-10 23:03:58 -05:00
|
|
|
FALSE,
|
2001-10-26 00:00:38 -04:00
|
|
|
i, ControlMask);
|
2001-07-25 23:14:45 -04:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_ungrab_window_buttons (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
|
|
|
{
|
2001-10-26 00:00:38 -04:00
|
|
|
gboolean debug = g_getenv ("METACITY_DEBUG_BUTTON_GRABS") != NULL;
|
2001-08-19 14:09:10 -04:00
|
|
|
int i = 1;
|
|
|
|
while (i < 4)
|
|
|
|
{
|
2001-10-26 00:00:38 -04:00
|
|
|
meta_change_button_grab (display, xwindow,
|
2001-12-10 23:03:58 -05:00
|
|
|
FALSE, FALSE, i, Mod1Mask);
|
2001-10-26 00:00:38 -04:00
|
|
|
if (debug)
|
|
|
|
meta_change_button_grab (display, xwindow,
|
2001-12-10 23:03:58 -05:00
|
|
|
FALSE, FALSE, i, ControlMask);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
2001-07-25 23:14:45 -04:00
|
|
|
}
|
|
|
|
|
2001-12-10 02:48:21 -05:00
|
|
|
/* Grab buttons we only grab while unfocused in click-to-focus mode */
|
2002-02-08 01:50:09 -05:00
|
|
|
#define MAX_FOCUS_BUTTON 4
|
2001-12-10 02:48:21 -05:00
|
|
|
void
|
2001-12-10 23:03:58 -05:00
|
|
|
meta_display_grab_focus_window_button (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2001-12-10 02:48:21 -05:00
|
|
|
{
|
|
|
|
/* Grab button 1 for activating unfocused windows */
|
|
|
|
meta_verbose ("Grabbing unfocused window buttons for 0x%lx\n", xwindow);
|
|
|
|
|
|
|
|
/* FIXME If we ignored errors here instead of spewing, we could
|
|
|
|
* put one big error trap around the loop and avoid a bunch of
|
|
|
|
* XSync()
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
int i = 1;
|
2002-02-08 01:50:09 -05:00
|
|
|
while (i < MAX_FOCUS_BUTTON)
|
2001-12-10 02:48:21 -05:00
|
|
|
{
|
|
|
|
meta_change_button_grab (display,
|
|
|
|
xwindow,
|
2001-12-10 23:03:58 -05:00
|
|
|
TRUE, TRUE, i, 0);
|
2001-12-10 02:48:21 -05:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-10 23:03:58 -05:00
|
|
|
meta_display_ungrab_focus_window_button (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2001-12-10 02:48:21 -05:00
|
|
|
{
|
|
|
|
meta_verbose ("Ungrabbing unfocused window buttons for 0x%lx\n", xwindow);
|
|
|
|
|
|
|
|
{
|
|
|
|
int i = 1;
|
2002-02-08 01:50:09 -05:00
|
|
|
while (i < MAX_FOCUS_BUTTON)
|
2001-12-10 02:48:21 -05:00
|
|
|
{
|
|
|
|
meta_change_button_grab (display, xwindow,
|
2001-12-10 23:03:58 -05:00
|
|
|
FALSE, TRUE, i, 0);
|
2001-12-10 02:48:21 -05:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-30 00:01:38 -04:00
|
|
|
void
|
|
|
|
meta_display_increment_event_serial (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
/* We just make some random X request */
|
|
|
|
XDeleteProperty (display->xdisplay, display->leader_window,
|
|
|
|
display->atom_motif_wm_hints);
|
|
|
|
}
|
2001-10-07 19:06:19 -04:00
|
|
|
|
2002-05-06 02:11:46 -04:00
|
|
|
static void
|
|
|
|
meta_display_update_show_desktop_hint (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
unsigned long data[1];
|
|
|
|
|
|
|
|
data[0] = display->showing_desktop ? 1 : 0;
|
|
|
|
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
XChangeProperty (display->xdisplay, screen->xroot,
|
2002-05-07 10:42:47 -04:00
|
|
|
display->atom_net_show_desktop,
|
2002-05-06 02:11:46 -04:00
|
|
|
XA_CARDINAL,
|
|
|
|
32, PropModeReplace, (guchar*) data, 1);
|
|
|
|
meta_error_trap_pop (display);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-07 19:06:19 -04:00
|
|
|
void
|
|
|
|
meta_display_update_active_window_hint (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
unsigned long data[2];
|
|
|
|
|
|
|
|
if (display->focus_window)
|
|
|
|
data[0] = display->focus_window->xwindow;
|
|
|
|
else
|
|
|
|
data[0] = None;
|
|
|
|
data[1] = None;
|
|
|
|
|
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
XChangeProperty (display->xdisplay, screen->xroot,
|
|
|
|
display->atom_net_active_window,
|
|
|
|
XA_WINDOW,
|
|
|
|
32, PropModeReplace, (guchar*) data, 2);
|
|
|
|
meta_error_trap_pop (display);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
}
|
2001-10-14 23:39:41 -04:00
|
|
|
|
|
|
|
static void
|
|
|
|
queue_windows_showing (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *windows;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display);
|
|
|
|
|
|
|
|
tmp = windows;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
meta_window_queue_calc_showing (tmp->data);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_show_desktop (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (display->showing_desktop)
|
|
|
|
return;
|
|
|
|
|
|
|
|
display->showing_desktop = TRUE;
|
|
|
|
|
|
|
|
queue_windows_showing (display);
|
2002-05-06 02:11:46 -04:00
|
|
|
|
|
|
|
meta_display_update_show_desktop_hint (display);
|
2001-10-14 23:39:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_unshow_desktop (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
if (!display->showing_desktop)
|
|
|
|
return;
|
|
|
|
|
|
|
|
display->showing_desktop = FALSE;
|
|
|
|
|
|
|
|
queue_windows_showing (display);
|
2002-05-06 02:11:46 -04:00
|
|
|
|
|
|
|
meta_display_update_show_desktop_hint (display);
|
2001-10-14 23:39:41 -04:00
|
|
|
}
|
2002-01-27 21:09:12 -05:00
|
|
|
|
2002-02-06 22:25:34 -05:00
|
|
|
void
|
|
|
|
meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList* windows;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display);
|
|
|
|
tmp = windows;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
|
|
|
meta_window_queue_move_resize (window);
|
|
|
|
if (window->frame)
|
2002-05-30 20:02:54 -04:00
|
|
|
{
|
|
|
|
meta_frame_queue_draw (window->frame);
|
|
|
|
|
|
|
|
/* FIXME this sucks and is slooooooooow. Do it in the idle with the
|
|
|
|
* redraw or the window resize.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* in case the theme doesn't affect the frame size */
|
|
|
|
meta_ui_apply_frame_shape (window->screen->ui,
|
|
|
|
window->frame->xwindow,
|
|
|
|
window->frame->rect.width,
|
|
|
|
window->frame->rect.height);
|
|
|
|
#endif
|
|
|
|
}
|
2002-02-06 22:25:34 -05:00
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_retheme_all (void)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
tmp = meta_displays_list ();
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = tmp->data;
|
|
|
|
meta_display_queue_retheme_all_windows (display);
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-27 21:09:12 -05:00
|
|
|
static gboolean is_syncing = FALSE;
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_is_syncing (void)
|
|
|
|
{
|
|
|
|
return is_syncing;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_syncing (gboolean setting)
|
|
|
|
{
|
|
|
|
if (setting != is_syncing)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
is_syncing = setting;
|
|
|
|
|
|
|
|
tmp = meta_displays_list ();
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = tmp->data;
|
|
|
|
XSynchronize (display->xdisplay, is_syncing);
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
|
2002-04-13 00:58:45 -04:00
|
|
|
#define PING_TIMEOUT_DELAY 2250
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
|
|
|
|
static gboolean
|
|
|
|
meta_display_ping_timeout (gpointer data)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data;
|
|
|
|
|
|
|
|
ping_data = data;
|
|
|
|
|
|
|
|
ping_data->ping_timeout_id = 0;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_PING,
|
|
|
|
"Ping %lu on window %lx timed out\n",
|
|
|
|
ping_data->timestamp, ping_data->xwindow);
|
|
|
|
|
|
|
|
(* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
|
|
|
|
ping_data->user_data);
|
|
|
|
|
|
|
|
ping_data->display->pending_pings =
|
|
|
|
g_slist_remove (ping_data->display->pending_pings,
|
|
|
|
ping_data);
|
|
|
|
ping_data_free (ping_data);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_ping_window (MetaDisplay *display,
|
|
|
|
MetaWindow *window,
|
|
|
|
Time timestamp,
|
|
|
|
MetaWindowPingFunc ping_reply_func,
|
|
|
|
MetaWindowPingFunc ping_timeout_func,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data;
|
|
|
|
|
|
|
|
if (timestamp == CurrentTime)
|
|
|
|
{
|
|
|
|
meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
|
|
|
|
return;
|
|
|
|
}
|
2002-04-15 18:14:06 -04:00
|
|
|
|
|
|
|
if (!window->net_wm_ping)
|
|
|
|
{
|
|
|
|
if (ping_reply_func)
|
|
|
|
(* ping_reply_func) (display, window->xwindow, user_data);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
Screw around with Anders's ping patch so he'll get plenty of CVS
2002-02-26 Havoc Pennington <hp@pobox.com>
Screw around with Anders's ping patch so he'll get plenty of CVS
conflicts. ;-)
* src/display.c (meta_display_ping_window): spew warnings
if we try to call this with CurrentTime
(meta_display_ping_timeout): remove ping from the pending pings
after it times out.
* src/util.h: added PING debug category
* src/display.c (remove_pending_pings_for_window): don't remove
"tmp" just before "tmp->next", don't break out of loop after
finding the first match
(meta_display_open): no trailing comma in array init
(event_callback): move the processing of ping replies into a
separate function
* src/screen.c (set_supported_hint): add _NET_WM_PING to supported
list
* src/display.h: change gpointer to void*
2002-02-26 Anders Carlsson <andersca@gnu.org>
* src/display.c: (ping_data_free),
(remove_pending_pings_for_window), (meta_display_open),
(event_callback), (meta_display_unregister_x_window),
(meta_display_ping_timeout), (meta_display_ping_window),
(meta_display_window_has_pending_pings):
Implement meta_display_ping_window, and filter out scroll wheel
events.
* src/display.h:
Add MetaWindowPingFunc, meta_display_ping_window and
meta_display_window_has_pending_pings.
2002-02-26 21:05:39 -05:00
|
|
|
|
|
|
|
ping_data = g_new (MetaPingData, 1);
|
|
|
|
ping_data->display = display;
|
|
|
|
ping_data->xwindow = window->xwindow;
|
|
|
|
ping_data->timestamp = timestamp;
|
|
|
|
ping_data->ping_reply_func = ping_reply_func;
|
|
|
|
ping_data->ping_timeout_func = ping_timeout_func;
|
|
|
|
ping_data->user_data = user_data;
|
|
|
|
ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
|
|
|
|
meta_display_ping_timeout,
|
|
|
|
ping_data);
|
|
|
|
|
|
|
|
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_PING,
|
|
|
|
"Sending ping with timestamp %lu to window %s\n",
|
|
|
|
timestamp, window->desc);
|
|
|
|
meta_window_send_icccm_message (window,
|
|
|
|
display->atom_net_wm_ping,
|
|
|
|
timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* process the pong from our ping */
|
|
|
|
static void
|
|
|
|
process_pong_message (MetaDisplay *display,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_PING, "Received a pong with timestamp %lu\n",
|
|
|
|
(Time) event->xclient.data.l[1]);
|
|
|
|
|
|
|
|
for (tmp = display->pending_pings; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
|
|
|
if ((Time)event->xclient.data.l[1] == ping_data->timestamp)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_PING,
|
|
|
|
"Matching ping found for pong %lu\n",
|
|
|
|
ping_data->timestamp);
|
|
|
|
|
|
|
|
/* Remove the ping data from the list */
|
|
|
|
display->pending_pings = g_slist_remove (display->pending_pings,
|
|
|
|
ping_data);
|
|
|
|
|
|
|
|
/* Remove the timeout */
|
|
|
|
if (ping_data->ping_timeout_id != 0)
|
|
|
|
{
|
|
|
|
g_source_remove (ping_data->ping_timeout_id);
|
|
|
|
ping_data->ping_timeout_id = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call callback */
|
|
|
|
(* ping_data->ping_reply_func) (display, ping_data->xwindow,
|
|
|
|
ping_data->user_data);
|
|
|
|
|
|
|
|
ping_data_free (ping_data);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_display_window_has_pending_pings (MetaDisplay *display,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
for (tmp = display->pending_pings; tmp; tmp = tmp->next)
|
|
|
|
{
|
|
|
|
MetaPingData *ping_data = tmp->data;
|
|
|
|
|
|
|
|
if (ping_data->xwindow == window->xwindow)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
#define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)))
|
|
|
|
|
2002-03-11 23:34:17 -05:00
|
|
|
static MetaWindow*
|
|
|
|
find_tab_forward (MetaDisplay *display,
|
2002-04-05 10:52:49 -05:00
|
|
|
MetaTabList type,
|
2002-05-11 02:59:54 -04:00
|
|
|
MetaScreen *screen,
|
2002-03-11 23:34:17 -05:00
|
|
|
MetaWorkspace *workspace,
|
|
|
|
GList *start)
|
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail (start != NULL, NULL);
|
2002-05-11 02:59:54 -04:00
|
|
|
|
2002-03-11 23:34:17 -05:00
|
|
|
tmp = start->next;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2002-05-11 02:59:54 -04:00
|
|
|
if (window->screen == screen &&
|
|
|
|
IN_TAB_CHAIN (window, type) &&
|
2002-03-11 23:34:17 -05:00
|
|
|
(workspace == NULL ||
|
|
|
|
meta_window_visible_on_workspace (window, workspace)))
|
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = display->mru_list;
|
|
|
|
while (tmp != start)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
if (IN_TAB_CHAIN (window, type) &&
|
2002-03-11 23:34:17 -05:00
|
|
|
(workspace == NULL ||
|
|
|
|
meta_window_visible_on_workspace (window, workspace)))
|
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MetaWindow*
|
|
|
|
find_tab_backward (MetaDisplay *display,
|
2002-04-05 10:52:49 -05:00
|
|
|
MetaTabList type,
|
2002-05-11 02:59:54 -04:00
|
|
|
MetaScreen *screen,
|
2002-03-11 23:34:17 -05:00
|
|
|
MetaWorkspace *workspace,
|
|
|
|
GList *start)
|
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail (start != NULL, NULL);
|
|
|
|
|
|
|
|
tmp = start->prev;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2002-05-11 02:59:54 -04:00
|
|
|
if (window->screen == screen &&
|
|
|
|
IN_TAB_CHAIN (window, type) &&
|
2002-03-11 23:34:17 -05:00
|
|
|
(workspace == NULL ||
|
|
|
|
meta_window_visible_on_workspace (window, workspace)))
|
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = g_list_last (display->mru_list);
|
|
|
|
while (tmp != start)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
if (IN_TAB_CHAIN (window, type) &&
|
2002-03-11 23:34:17 -05:00
|
|
|
(workspace == NULL ||
|
|
|
|
meta_window_visible_on_workspace (window, workspace)))
|
|
|
|
return window;
|
|
|
|
|
|
|
|
tmp = tmp->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
GSList*
|
|
|
|
meta_display_get_tab_list (MetaDisplay *display,
|
2002-04-05 10:52:49 -05:00
|
|
|
MetaTabList type,
|
2002-03-11 23:34:17 -05:00
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWorkspace *workspace)
|
|
|
|
{
|
|
|
|
GSList *tab_list;
|
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
/* workspace can be NULL for all workspaces */
|
|
|
|
|
2002-03-11 23:34:17 -05:00
|
|
|
/* Windows sellout mode - MRU order */
|
|
|
|
{
|
|
|
|
GList *tmp;
|
|
|
|
|
|
|
|
tab_list = NULL;
|
|
|
|
tmp = screen->display->mru_list;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *window = tmp->data;
|
|
|
|
|
|
|
|
if (window->screen == screen &&
|
2002-04-05 10:52:49 -05:00
|
|
|
IN_TAB_CHAIN (window, type) &&
|
2002-03-11 23:34:17 -05:00
|
|
|
(workspace == NULL ||
|
|
|
|
meta_window_visible_on_workspace (window, workspace)))
|
|
|
|
tab_list = g_slist_prepend (tab_list, window);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
tab_list = g_slist_reverse (tab_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tab_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
MetaWindow*
|
|
|
|
meta_display_get_tab_next (MetaDisplay *display,
|
2002-04-05 10:52:49 -05:00
|
|
|
MetaTabList type,
|
2002-05-11 02:59:54 -04:00
|
|
|
MetaScreen *screen,
|
2002-03-11 23:34:17 -05:00
|
|
|
MetaWorkspace *workspace,
|
|
|
|
MetaWindow *window,
|
|
|
|
gboolean backward)
|
|
|
|
{
|
|
|
|
if (display->mru_list == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (window != NULL)
|
|
|
|
{
|
|
|
|
g_assert (window->display == display);
|
|
|
|
|
|
|
|
if (backward)
|
2002-05-11 02:59:54 -04:00
|
|
|
return find_tab_backward (display, type, screen, workspace,
|
2002-03-11 23:34:17 -05:00
|
|
|
g_list_find (display->mru_list,
|
|
|
|
window));
|
|
|
|
else
|
2002-05-11 02:59:54 -04:00
|
|
|
return find_tab_forward (display, type, screen, workspace,
|
2002-03-11 23:34:17 -05:00
|
|
|
g_list_find (display->mru_list,
|
|
|
|
window));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (backward)
|
2002-05-11 02:59:54 -04:00
|
|
|
return find_tab_backward (display, type, screen, workspace,
|
2002-03-11 23:34:17 -05:00
|
|
|
g_list_last (display->mru_list));
|
|
|
|
else
|
2002-05-11 02:59:54 -04:00
|
|
|
return find_tab_forward (display, type, screen, workspace,
|
2002-03-11 23:34:17 -05:00
|
|
|
display->mru_list);
|
|
|
|
}
|
2002-03-17 12:22:23 -05:00
|
|
|
|
|
|
|
int
|
|
|
|
meta_resize_gravity_from_grab_op (MetaGrabOp op)
|
|
|
|
{
|
|
|
|
int gravity;
|
|
|
|
|
|
|
|
gravity = -1;
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
|
|
|
gravity = NorthWestGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
|
|
|
case META_GRAB_OP_RESIZING_S:
|
|
|
|
gravity = NorthGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_RESIZING_SW:
|
|
|
|
gravity = NorthEastGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
|
|
|
case META_GRAB_OP_RESIZING_N:
|
|
|
|
gravity = SouthGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_RESIZING_NE:
|
|
|
|
gravity = SouthWestGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
|
|
|
case META_GRAB_OP_RESIZING_NW:
|
|
|
|
gravity = SouthEastGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
|
|
|
case META_GRAB_OP_RESIZING_E:
|
|
|
|
gravity = WestGravity;
|
|
|
|
break;
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
|
|
|
case META_GRAB_OP_RESIZING_W:
|
|
|
|
gravity = EastGravity;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gravity;
|
|
|
|
}
|
2002-05-23 22:23:46 -04:00
|
|
|
|
2002-05-28 23:11:24 -04:00
|
|
|
gboolean
|
|
|
|
meta_rectangle_intersect (MetaRectangle *src1,
|
|
|
|
MetaRectangle *src2,
|
|
|
|
MetaRectangle *dest)
|
|
|
|
{
|
|
|
|
int dest_x, dest_y;
|
|
|
|
int dest_w, dest_h;
|
|
|
|
int return_val;
|
|
|
|
|
|
|
|
g_return_val_if_fail (src1 != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (src2 != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (dest != NULL, FALSE);
|
|
|
|
|
|
|
|
return_val = FALSE;
|
|
|
|
|
|
|
|
dest_x = MAX (src1->x, src2->x);
|
|
|
|
dest_y = MAX (src1->y, src2->y);
|
|
|
|
dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
|
|
|
|
dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
|
|
|
|
|
|
|
|
if (dest_w > 0 && dest_h > 0)
|
|
|
|
{
|
|
|
|
dest->x = dest_x;
|
|
|
|
dest->y = dest_y;
|
|
|
|
dest->width = dest_w;
|
|
|
|
dest->height = dest_h;
|
|
|
|
return_val = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dest->width = 0;
|
|
|
|
dest->height = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return return_val;
|
|
|
|
}
|
|
|
|
|