Compare commits
2 Commits
METACITY_2
...
METACITY_2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0ee26a5168 | ||
![]() |
204cf63805 |
25
ChangeLog
25
ChangeLog
@@ -0,0 +1,25 @@
|
||||
2001-08-03 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/keybindings.c: Add Alt + left/right arrow to
|
||||
move between workspaces.
|
||||
|
||||
* src/screen.c (set_wm_check_hint): put property pointing back to
|
||||
itself on the _WIN_SUPPORTING_WM_CHECK window.
|
||||
|
||||
2001-08-03 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/display.c (event_callback): push error trap around configure
|
||||
of withdrawn window, fixes a crash caused by rapidly
|
||||
creating/destroying a window.
|
||||
|
||||
* src/window.c (recalc_window_features): don't allow shading
|
||||
undecorated windows.
|
||||
|
||||
* src/wm-tester/main.c: add a program to torture window managers.
|
||||
|
||||
2001-08-01 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/window.c (recalc_window_features): if a window isn't
|
||||
resizeable, turn off maximize function. If min size is equal to
|
||||
max size, turn off resize function.
|
||||
|
||||
|
35
README
35
README
@@ -42,6 +42,8 @@ METACITY FEATURES
|
||||
Alt-Tab forward cycle window focus
|
||||
Alt-Shift-Tab backward cycle focus
|
||||
Alt-Escape focus previous window
|
||||
Alt-Left Arrow previous workspace
|
||||
Alt-Right Arrow next workspace
|
||||
|
||||
- Window keybindings:
|
||||
Alt-space window menu
|
||||
@@ -177,12 +179,6 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
|
||||
|
||||
- There are probably other ICCCM-compliance issues.
|
||||
|
||||
- I know there's at least one race condition involving rapidly
|
||||
created and destroyed windows that will crash Metacity. I think a
|
||||
small test app that did a lot of rapid show/hide on a GtkWindow,
|
||||
in combination with the METACITY_SYNC environment variable and
|
||||
Metacity in a debugger, would turn this up quickly.
|
||||
|
||||
- Window placement is always cascade for now; I want to implement
|
||||
"first fit, falling back to cascade if no fit."
|
||||
(Configurable placement algorithms are stupid though, don't
|
||||
@@ -201,15 +197,6 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
|
||||
window cycling that I would like to copy. (The little
|
||||
popup window thing.)
|
||||
|
||||
- People seem to like shortcuts using arrow keys for moving
|
||||
between workspaces. My only question here is that I'm not sure
|
||||
what the spatial relationship between workspaces is.
|
||||
(Are they in a grid, or a horizontal row, or what.)
|
||||
I think we may need a window manager spec extension to
|
||||
share this information between the WM and the pager.
|
||||
We could add left/right arrow and pretend they're in
|
||||
a row for the short term though.
|
||||
|
||||
- Should Metacity support flipping in right-to-left locales?
|
||||
I don't know what window managers look like in a right-to-left
|
||||
locale. I assume the window titles should be right-justified;
|
||||
@@ -246,6 +233,24 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
|
||||
xstuff.c:xstuff_is_compliant_wm() in the panel to get started on
|
||||
how the panel deals with this.)
|
||||
|
||||
- If you have "put panel below other windows" turned on
|
||||
in panel Global Preferences, Miscellaneous tab, you need to change
|
||||
this to "Put panel on top of other windows." That's because
|
||||
Metacity uses semantic categories, not the legacy layer system
|
||||
in the GNOME spec. It treats things in the legacy "dock" layer
|
||||
as semantic type dock, but if you have the panel set to be
|
||||
in another layer, Metacity will think it's a normal window.
|
||||
|
||||
You can diagnose this problem because Metacity will put panels in
|
||||
the wrong place, and Alt+rightclick will let you perform operations
|
||||
like minimize/maximize, and Alt+leftclick will let you move the panel.
|
||||
If Metacity has detected that the panel is a panel, then none of
|
||||
this will be enabled.
|
||||
|
||||
I put a patch in the CVS version of the panel to fix this by
|
||||
setting the new non-legacy type hint, but a panel with that
|
||||
patch hasn't been released yet.
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
|
@@ -2,7 +2,7 @@ AC_INIT(src/display.c)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
AM_INIT_AUTOMAKE(metacity, 2.3.1)
|
||||
AM_INIT_AUTOMAKE(metacity, 2.3.2)
|
||||
|
||||
GETTEXT_PACKAGE=metacity
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
@@ -71,6 +71,7 @@ AC_SUBST(HOST_ALIAS)
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/wm-tester/Makefile
|
||||
])
|
||||
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
SUBDIRS=wm-tester
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\"
|
||||
|
||||
metacity_SOURCES= \
|
||||
|
@@ -825,8 +825,10 @@ event_callback (XEvent *event,
|
||||
|
||||
meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n",
|
||||
xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
|
||||
meta_error_trap_push (display);
|
||||
XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
|
||||
xwcm, &xwc);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1285,6 +1287,10 @@ meta_display_get_workspace_by_index (MetaDisplay *display,
|
||||
int index)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
/* should be robust, index is maybe from an app */
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
tmp = g_list_nth (display->workspaces, index);
|
||||
|
||||
@@ -1302,6 +1308,10 @@ meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
/* should be robust, index is maybe from an app */
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
tmp = display->workspaces;
|
||||
while (tmp != NULL)
|
||||
|
@@ -57,6 +57,14 @@ static void handle_focus_previous (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
static void handle_workspace_left (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
static void handle_workspace_right (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
|
||||
@@ -89,6 +97,8 @@ static MetaKeyBinding screen_bindings[] = {
|
||||
{ XK_ISO_Left_Tab, ShiftMask | Mod1Mask, KeyPress, handle_tab_backward, NULL, 0 },
|
||||
{ XK_Tab, ShiftMask | Mod1Mask, KeyPress, handle_tab_backward, NULL, 0 },
|
||||
{ XK_Escape, Mod1Mask, KeyPress, handle_focus_previous, NULL, 0 },
|
||||
{ XK_Left, Mod1Mask, KeyPress, handle_workspace_left, NULL, 0 },
|
||||
{ XK_Right, Mod1Mask, KeyPress, handle_workspace_right, NULL, 0 },
|
||||
{ None, 0, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@@ -499,6 +509,47 @@ meta_display_process_key_event (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
switch_to_workspace (MetaDisplay *display,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
MetaWindow *move_window;
|
||||
|
||||
move_window = NULL;
|
||||
if (display->grab_op == META_GRAB_OP_MOVING)
|
||||
move_window = display->grab_window;
|
||||
|
||||
if (move_window != NULL)
|
||||
{
|
||||
if (move_window->on_all_workspaces)
|
||||
move_window = NULL; /* don't move it after all */
|
||||
|
||||
/* We put the window on the new workspace, flip spaces,
|
||||
* then remove from old workspace, so the window
|
||||
* never gets unmapped and we maintain the button grab
|
||||
* on it.
|
||||
*/
|
||||
if (move_window)
|
||||
{
|
||||
if (!meta_workspace_contains_window (workspace,
|
||||
move_window))
|
||||
meta_workspace_add_window (workspace, move_window);
|
||||
}
|
||||
}
|
||||
|
||||
meta_workspace_activate (workspace);
|
||||
|
||||
if (move_window)
|
||||
{
|
||||
/* Lamely rely on prepend */
|
||||
g_assert (move_window->workspaces->data == workspace);
|
||||
|
||||
while (move_window->workspaces->next) /* while list size > 1 */
|
||||
meta_workspace_remove_window (move_window->workspaces->next->data,
|
||||
move_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_activate_workspace (MetaDisplay *display,
|
||||
MetaWindow *event_window,
|
||||
@@ -514,41 +565,69 @@ handle_activate_workspace (MetaDisplay *display,
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
MetaWindow *move_window;
|
||||
switch_to_workspace (display, workspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could offer to create it I suppose */
|
||||
}
|
||||
}
|
||||
|
||||
move_window = NULL;
|
||||
if (display->grab_op == META_GRAB_OP_MOVING)
|
||||
move_window = display->grab_window;
|
||||
|
||||
if (move_window != NULL)
|
||||
{
|
||||
if (move_window->on_all_workspaces)
|
||||
move_window = NULL; /* don't move it after all */
|
||||
static void
|
||||
handle_workspace_left (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
MetaScreen *screen;
|
||||
int i;
|
||||
|
||||
screen = meta_display_screen_for_root (display,
|
||||
event->xkey.root);
|
||||
|
||||
/* We put the window on the new workspace, flip spaces,
|
||||
* then remove from old workspace, so the window
|
||||
* never gets unmapped and we maintain the button grab
|
||||
* on it.
|
||||
*/
|
||||
if (move_window)
|
||||
{
|
||||
if (!meta_workspace_contains_window (workspace,
|
||||
move_window))
|
||||
meta_workspace_add_window (workspace, move_window);
|
||||
}
|
||||
}
|
||||
|
||||
meta_workspace_activate (workspace);
|
||||
if (screen == NULL)
|
||||
return;
|
||||
|
||||
i = meta_workspace_index (screen->active_workspace);
|
||||
--i;
|
||||
|
||||
if (move_window)
|
||||
{
|
||||
/* Lamely rely on prepend */
|
||||
g_assert (move_window->workspaces->data == workspace);
|
||||
|
||||
while (move_window->workspaces->next) /* while list size > 1 */
|
||||
meta_workspace_remove_window (move_window->workspaces->next->data,
|
||||
move_window);
|
||||
}
|
||||
workspace = meta_display_get_workspace_by_index (display, i);
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
switch_to_workspace (display, workspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could offer to create it I suppose */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_workspace_right (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
MetaScreen *screen;
|
||||
int i;
|
||||
|
||||
screen = meta_display_screen_for_root (display,
|
||||
event->xkey.root);
|
||||
|
||||
if (screen == NULL)
|
||||
return;
|
||||
|
||||
i = meta_workspace_index (screen->active_workspace);
|
||||
++i;
|
||||
|
||||
workspace = meta_display_get_workspace_by_index (display, i);
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
switch_to_workspace (display, workspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -18,10 +18,18 @@ if test -z "$SM_CLIENTS"; then
|
||||
SM_CLIENTS=0
|
||||
fi
|
||||
|
||||
if test -n "$EVIL_TEST"; then
|
||||
TEST_CLIENT='./wm-tester/wm-tester --evil'
|
||||
fi
|
||||
|
||||
if test -z "$ONLY_WM"; then
|
||||
Xnest -ac :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
|
||||
usleep 500000
|
||||
|
||||
if test -n "$TEST_CLIENT"; then
|
||||
DISPLAY=:1 $TEST_CLIENT &
|
||||
fi
|
||||
|
||||
if test $CLIENTS != 0; then
|
||||
for I in `seq 1 $CLIENTS`; do
|
||||
DISPLAY=:1 xterm -geometry 25x15 &
|
||||
@@ -40,5 +48,5 @@ if test -z "$ONLY_WM"; then
|
||||
fi
|
||||
|
||||
if test -z "$ONLY_SETUP"; then
|
||||
METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
|
||||
METACITY_DEBUG_BUTTON_GRABS=1 METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
|
||||
fi
|
||||
|
14
src/screen.c
14
src/screen.c
@@ -50,12 +50,22 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
XA_WINDOW,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
/* Legacy GNOME hint */
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
/* Legacy GNOME hint (uses cardinal, dunno why) */
|
||||
|
||||
/* legacy hint window should have property containing self */
|
||||
XChangeProperty (screen->display->xdisplay, screen->display->leader_window,
|
||||
screen->display->atom_win_supporting_wm_check,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
/* do this after setting up window fully, to avoid races
|
||||
* with clients listening to property notify on root.
|
||||
*/
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_win_supporting_wm_check,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
17
src/window.c
17
src/window.c
@@ -2491,6 +2491,8 @@ update_size_hints (MetaWindow *window)
|
||||
window->size_hints.flags |= PWinGravity;
|
||||
}
|
||||
|
||||
recalc_window_features (window);
|
||||
|
||||
return meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
@@ -2552,7 +2554,7 @@ update_title (MetaWindow *window)
|
||||
&err);
|
||||
if (err != NULL)
|
||||
{
|
||||
meta_warning ("WM_NAME property for %s contained stuff we are too dumb to figure out: %s\n", window->desc, err->message);
|
||||
meta_warning ("WM_NAME property for %s contained stuff window manager is too dumb to figure out: %s\n", window->desc, err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
|
||||
@@ -3441,6 +3443,19 @@ recalc_window_features (MetaWindow *window)
|
||||
window->has_maximize_func = FALSE;
|
||||
}
|
||||
|
||||
/* If min_size == max_size, then don't allow resize */
|
||||
if (window->size_hints.min_width == window->size_hints.max_width &&
|
||||
window->size_hints.min_height == window->size_hints.max_height)
|
||||
window->has_resize_func = FALSE;
|
||||
|
||||
/* don't allow maximize if we can't resize */
|
||||
if (!window->has_resize_func)
|
||||
window->has_maximize_func = FALSE;
|
||||
|
||||
/* no shading if not decorated */
|
||||
if (!window->decorated)
|
||||
window->has_shade_func = FALSE;
|
||||
|
||||
/* FIXME perhaps should ensure if we don't have a shade func,
|
||||
* we aren't shaded, etc.
|
||||
*/
|
||||
|
9
src/wm-tester/Makefile.am
Normal file
9
src/wm-tester/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@
|
||||
|
||||
wm_tester_SOURCES= \
|
||||
main.c
|
||||
|
||||
bin_PROGRAMS=wm-tester
|
||||
|
||||
wm_tester_LDADD= @METACITY_LIBS@
|
158
src/wm-tester/main.c
Normal file
158
src/wm-tester/main.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* WM tester main() */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void set_up_the_evil (void);
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
g_print ("wm-tester [--evil]\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
gboolean do_evil;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
do_evil = FALSE;
|
||||
|
||||
i = 1;
|
||||
while (i < argc)
|
||||
{
|
||||
const char *arg = argv[i];
|
||||
|
||||
if (strcmp (arg, "--help") == 0 ||
|
||||
strcmp (arg, "-h") == 0 ||
|
||||
strcmp (arg, "-?") == 0)
|
||||
usage ();
|
||||
else if (strcmp (arg, "--evil") == 0)
|
||||
do_evil = TRUE;
|
||||
else
|
||||
usage ();
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Be sure some option was provided */
|
||||
if (! (do_evil))
|
||||
return 1;
|
||||
|
||||
if (do_evil)
|
||||
set_up_the_evil ();
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GSList *evil_windows = NULL;
|
||||
|
||||
static gint
|
||||
evil_timeout (gpointer data)
|
||||
{
|
||||
int i;
|
||||
int n_windows;
|
||||
int len;
|
||||
int create_count;
|
||||
int destroy_count;
|
||||
|
||||
len = g_slist_length (evil_windows);
|
||||
|
||||
if (len > 35)
|
||||
{
|
||||
create_count = 2;
|
||||
destroy_count = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_count = 5;
|
||||
destroy_count = 5;
|
||||
}
|
||||
|
||||
/* Create some windows */
|
||||
n_windows = g_random_int_range (0, create_count);
|
||||
|
||||
i = 0;
|
||||
while (i < n_windows)
|
||||
{
|
||||
GtkWidget *w;
|
||||
GtkWidget *c;
|
||||
|
||||
w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
c = gtk_button_new_with_label ("Evil Window!");
|
||||
gtk_container_add (GTK_CONTAINER (w), c);
|
||||
|
||||
gtk_widget_set_uposition (w,
|
||||
g_random_int_range (0,
|
||||
gdk_screen_width ()),
|
||||
g_random_int_range (0,
|
||||
gdk_screen_height ()));
|
||||
|
||||
gtk_widget_show_all (w);
|
||||
|
||||
evil_windows = g_slist_prepend (evil_windows, w);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Destroy some windows */
|
||||
if (len > destroy_count)
|
||||
{
|
||||
n_windows = g_random_int_range (0, destroy_count);
|
||||
i = 0;
|
||||
while (i < n_windows)
|
||||
{
|
||||
GtkWidget *w;
|
||||
|
||||
w = g_slist_nth_data (evil_windows,
|
||||
g_random_int_range (0, len));
|
||||
if (w)
|
||||
{
|
||||
--len;
|
||||
evil_windows = g_slist_remove (evil_windows, w);
|
||||
gtk_widget_destroy (w);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_up_the_evil (void)
|
||||
{
|
||||
g_timeout_add (40, evil_timeout, NULL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user