diff --git a/configure.in b/configure.in index 6a337a1b2..b4631cc98 100644 --- a/configure.in +++ b/configure.in @@ -40,24 +40,8 @@ changequote([,])dnl ALL_LINGUAS="" AM_GNU_GETTEXT -if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) -fi - -## see if we have Pango built with xft support -if $PKG_CONFIG --exists pangoxft ; then - PANGO_PACKAGES="pangox pangoxft" - have_xft=true - AC_DEFINE(HAVE_XFT) -else - PANGO_PACKAGES="pangox" - have_xft=false -fi -AM_CONDITIONAL(HAVE_XFT, $have_xft) - ## here we get the flags we'll actually use -PKG_CHECK_MODULES(UISLAVE, gtk+-2.0 >= 1.3.5) -PKG_CHECK_MODULES(METACITY, $PANGO_PACKAGES) +PKG_CHECK_MODULES(METACITY, gtk+-2.0 >= 1.3.6) # Check for shaped window extension AC_CHECK_LIB(Xext, XShapeCombineMask, AC_DEFINE(HAVE_SHAPE_EXT),,$METACITY_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index 5f3c9f393..7a3493e24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,46 +1,7 @@ -SUBDIRS=uislave - -INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_COMPILE=1 - -## convenience libraries lead to annoying slow compiles, plus we want -## to be extra-hacky by using #ifdef METACITY_COMPILE, ergo cheesy -## hack that follows. -copied_sources= \ - messagequeue.h \ - messagequeue.c -copied_sources_deps= \ - $(srcdir)/uislave/messagequeue.h \ - $(srcdir)/uislave/messagequeue.c - -BUILT_SOURCES=$(copied_sources) - -$(copied_sources): $(copied_sources_deps) - for I in $(copied_sources); do \ - rm -f $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" > $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - echo "/* DO NOT EDIT THIS FILE */" >> $$I ; \ - cat $(srcdir)/uislave/$$I >> $$I ; \ - done +INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" metacity_SOURCES= \ - api.c \ - api.h \ - colors.c \ - colors.h \ display.c \ display.h \ errors.c \ @@ -49,27 +10,26 @@ metacity_SOURCES= \ eventqueue.h \ frame.c \ frame.h \ + frames.c \ + frames.h \ keybindings.c \ keybindings.h \ main.c \ main.h \ + menu.c \ + menu.h \ screen.c \ screen.h \ session.c \ session.h \ stack.c \ stack.h \ - theme.c \ - theme.h \ - uislave.c \ - uislave.h \ util.c \ util.h \ window.c \ window.h \ workspace.c \ - workspace.h \ - $(copied_sources) + workspace.h bin_PROGRAMS=metacity diff --git a/src/core.c b/src/core.c new file mode 100644 index 000000000..0c935d9ab --- /dev/null +++ b/src/core.c @@ -0,0 +1,23 @@ +/* Metacity interface used by GTK+ UI to talk to core */ + +/* + * 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 "core.h" + diff --git a/src/core.h b/src/core.h new file mode 100644 index 000000000..f49372f9d --- /dev/null +++ b/src/core.h @@ -0,0 +1,31 @@ +/* Metacity interface used by GTK+ UI to talk to core */ + +/* + * 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. + */ + +#ifndef META_CORE_H +#define META_CORE_H + +/* Don't include core headers here */ +#include +#include +#include "frames.h" + + +#endif diff --git a/src/display.c b/src/display.c index 0d73d733d..2399c52c1 100644 --- a/src/display.c +++ b/src/display.c @@ -196,7 +196,9 @@ meta_display_open (const char *name) * created in screen_new */ display->leader_window = None; - + +#if 0 + /* disable multihead pending GTK support */ screens = NULL; i = 0; while (i < ScreenCount (xdisplay)) @@ -209,6 +211,11 @@ meta_display_open (const char *name) screens = g_slist_prepend (screens, screen); ++i; } +#else + screen = meta_screen_new (display, DefaultScreen (xdisplay)); + if (screen) + screens = g_slist_prepend (screens, screen); +#endif if (screens == NULL) { diff --git a/src/frame.c b/src/frame.c index fd23b6708..f8efb9f91 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1009,6 +1009,13 @@ meta_frame_event (MetaFrame *frame, case ConfigureNotify: break; case ConfigureRequest: + { + /* This is a request from the UISlave, or else a client + * that's completely out of line. We call + * meta_window_move_resize() using this information. + */ + + } break; case GravityNotify: break; diff --git a/src/frames.c b/src/frames.c index 4bd609c57..7fb0130ad 100644 --- a/src/frames.c +++ b/src/frames.c @@ -577,7 +577,9 @@ meta_frames_manage_window (MetaFrames *frames, if (frame->window == NULL) { + gdk_flush (); gdk_error_trap_pop (); + g_free (frame); meta_ui_warning ("Frame 0x%lx disappeared as we managed it\n", xwindow); return; } @@ -594,8 +596,25 @@ meta_frames_manage_window (MetaFrames *frames, gdk_drawable_get_size (GDK_DRAWABLE (frame->window), &frame->width, &frame->height); - - gdk_error_trap_pop (); + + /* This shouldn't be required if we don't select for button + * press in frame.c? + */ + XGrabButton (gdk_display, AnyButton, AnyModifier, + xwindow, False, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + False, None); + + gdk_flush (); + if (gdk_error_trap_pop ()) + { + g_object_unref (G_OBJECT (frame->window)); + g_free (frame); + meta_ui_warning ("Errors managing frame 0x%lx\n", xwindow); + return; + } frame->xwindow = xwindow; frame->layout = NULL; diff --git a/src/frames.h b/src/frames.h index 5a263c547..444b8b1f5 100644 --- a/src/frames.h +++ b/src/frames.h @@ -69,7 +69,6 @@ void meta_frames_manage_window (MetaFrames *frames, Window xwindow); void meta_frames_unmanage_window (MetaFrames *frames, Window xwindow); - void meta_frames_set_title (MetaFrames *frames, Window xwindow, const char *title); diff --git a/src/main.c b/src/main.c index e111d6e9b..6142b0e88 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,7 @@ #include "util.h" #include "display.h" #include "errors.h" +#include "ui.h" #include #include @@ -68,6 +69,8 @@ main (int argc, char **argv) putenv (display_name); /* DO NOT FREE display_name, putenv() sucks */ } + + meta_ui_init (&argc, &argv); if (!meta_display_open (NULL)) meta_exit (META_EXIT_ERROR); diff --git a/src/ui.c b/src/ui.c new file mode 100644 index 000000000..41ec45c4a --- /dev/null +++ b/src/ui.c @@ -0,0 +1,28 @@ +/* Metacity interface for talking to GTK+ UI module */ + +/* + * 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 "ui.h" + +void +meta_ui_init (int *argc, char ***argv) +{ + gtk_init (argc, argv); +} diff --git a/src/ui.h b/src/ui.h new file mode 100644 index 000000000..4e2260e37 --- /dev/null +++ b/src/ui.h @@ -0,0 +1,36 @@ +/* Metacity interface for talking to GTK+ UI module */ + +/* + * 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. + */ + +#ifndef META_UI_H +#define META_UI_H + +/* Don't include gtk.h here */ +#include "window.h" + +typedef struct _MetaUI MetaUI; + +void meta_ui_init (int *argc, char ***argv); + +MetaUI* meta_ui_new (Display *xdisplay); +void meta_ui_free (MetaUI *ui); + + +#endif diff --git a/src/uislave.c b/src/uislave.c deleted file mode 100644 index 2f43fc46a..000000000 --- a/src/uislave.c +++ /dev/null @@ -1,353 +0,0 @@ -/* Metacity UI Slave */ - -/* - * 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 "uislave.h" -#include "window.h" -#include -#include -#include -#include -#include -#include - -static void respawn_child (MetaUISlave *uislave); -static void kill_child (MetaUISlave *uislave); -static void reset_vals (MetaUISlave *uislave); -static void message_queue_func (MetaMessageQueue *mq, - MetaMessage* message, - gpointer data); - - -MetaUISlave* -meta_ui_slave_new (const char *display_name, - MetaUISlaveFunc func, - gpointer data) -{ - MetaUISlave *uislave; - - uislave = g_new (MetaUISlave, 1); - - uislave->display_name = g_strdup (display_name); - uislave->func = func; - uislave->data = data; - uislave->no_respawn = FALSE; - uislave->serial = 1; - - reset_vals (uislave); - - /* This may fail; all UISlave functions become no-ops - * if uislave->disabled, and metacity just runs - * with no UI features other than window borders. - */ - respawn_child (uislave); - - return uislave; -} - -void -meta_ui_slave_free (MetaUISlave *uislave) -{ - - meta_verbose ("Deleting UI slave for display '%s'\n", - uislave->display_name); - - kill_child (uislave); - - g_free (uislave->display_name); - - g_free (uislave); -} - -void -meta_ui_slave_disable (MetaUISlave *uislave) -{ - /* Change UI slave into "black hole" mode, - * we found out it's hosed for some reason. - */ - kill_child (uislave); - uislave->no_respawn = TRUE; - meta_warning ("UI slave disabled, no tooltips or window menus will work\n"); -} - -static void -message_queue_func (MetaMessageQueue *mq, - MetaMessage* message, - gpointer data) -{ - MetaUISlave *uislave; - - uislave = data; - - (* uislave->func) (uislave, message, uislave->data); -} - -static void -child_setup (gpointer data) -{ - /* data is leaked, putenv doesn't copy it */ - putenv (data); -} - -static void -respawn_child (MetaUISlave *uislave) -{ - GError *error; - const char *uislavedir; - char *argv[] = { NULL, NULL, NULL, NULL, NULL }; - int child_pid, inpipe, outpipe, errpipe; - char *path; - char *disp; - - if (uislave->no_respawn) - return; - - if (uislave->child_pid != 0) - return; - - uislavedir = g_getenv ("METACITY_UISLAVE_DIR"); - if (uislavedir == NULL) - uislavedir = METACITY_LIBEXECDIR; - - disp = g_strconcat ("DISPLAY=", uislave->display_name, NULL); - - path = g_strconcat (uislavedir, "/", "metacity-uislave", NULL); -#if 0 - argv[0] = "/usr/bin/strace"; - argv[1] = "-o"; - argv[2] = "uislave-strace.log"; -#endif - argv[0] = path; - argv[1] = "--sync"; - - meta_verbose ("Launching UI slave in dir %s display %s\n", - uislavedir, disp); - - error = NULL; - if (g_spawn_async_with_pipes (NULL, - argv, - NULL, - /* flags */ - 0, - child_setup, disp, - &child_pid, - &inpipe, &outpipe, NULL, - &error)) - { - errpipe = -1; - uislave->child_pid = child_pid; - uislave->in_pipe = inpipe; - uislave->out_pipe = outpipe; - - uislave->mq = meta_message_queue_new (outpipe, - message_queue_func, - uislave); - - meta_verbose ("Spawned UI slave with PID %d\n", uislave->child_pid); - } - else - { - meta_warning ("Failed to create user interface process: %s\n", - error->message); - g_error_free (error); - } - - g_free (disp); - g_free (path); -} - -static void -kill_child (MetaUISlave *uislave) -{ - if (uislave->mq) - meta_message_queue_free (uislave->mq); - - if (uislave->out_pipe >= 0) - { - meta_verbose ("Closing UI child output pipe\n"); - close (uislave->out_pipe); - } - - if (uislave->in_pipe >= 0) - { - meta_verbose ("Closing UI child input pipe\n"); - close (uislave->in_pipe); - } - - if (uislave->child_pid > 0) - { - /* don't care if this fails except in verbose mode */ - if (kill (uislave->child_pid, SIGTERM) != 0) - { - meta_verbose ("Kill of UI slave process %d failed: %s\n", - uislave->child_pid, g_strerror (errno)); - } - - uislave->child_pid = 0; - } - - reset_vals (uislave); -} - -static void -reset_vals (MetaUISlave *uislave) -{ - uislave->mq = NULL; - uislave->child_pid = 0; - uislave->in_pipe = -1; - uislave->out_pipe = -1; - /* don't reset no_respawn, it's a permanent thing. */ -} - -/* - * Message delivery - */ - -static int -write_bytes (int fd, void *buf, int bytes) -{ - const char *p; - int left; - - left = bytes; - p = (char*) buf; - while (left > 0) - { - int written; - - written = write (fd, p, left); - - if (written < 0) - return -1; - - left -= written; - p += written; - } - - g_assert (p == ((char*)buf) + bytes); - - return 0; -} - -static void -send_message (MetaUISlave *uislave, MetaMessage *message, - int request_serial) -{ - MetaMessageFooter *footer; - - if (uislave->no_respawn) - return; - - respawn_child (uislave); - - message->header.serial = uislave->serial; - message->header.request_serial = request_serial; - - footer = META_MESSAGE_FOOTER (message); - - footer->checksum = META_MESSAGE_CHECKSUM (message); - uislave->serial += 1; - - if (write_bytes (uislave->in_pipe, - META_MESSAGE_ESCAPE, META_MESSAGE_ESCAPE_LEN) < 0) - { - meta_warning ("Failed to write escape sequence: %s\n", - g_strerror (errno)); - kill_child (uislave); - } - if (write_bytes (uislave->in_pipe, - message, message->header.length) < 0) - { - meta_warning ("Failed to write message: %s\n", - g_strerror (errno)); - kill_child (uislave); - } -} - -void -meta_ui_slave_show_tip (MetaUISlave *uislave, - int root_x, - int root_y, - const char *markup_text) -{ - MetaMessageShowTip showtip; - - memset (&showtip, 0, META_MESSAGE_LENGTH (MetaMessageShowTip)); - showtip.header.message_code = MetaMessageShowTipCode; - showtip.header.length = META_MESSAGE_LENGTH (MetaMessageShowTip); - - showtip.root_x = root_x; - showtip.root_y = root_y; - strncpy (showtip.markup, markup_text, META_MESSAGE_MAX_TIP_LEN); - showtip.markup[META_MESSAGE_MAX_TIP_LEN] = '\0'; - - send_message (uislave, (MetaMessage*)&showtip, 0); -} - -void -meta_ui_slave_hide_tip (MetaUISlave *uislave) -{ - MetaMessageHideTip hidetip; - - memset (&hidetip, 0, META_MESSAGE_LENGTH (MetaMessageHideTip)); - hidetip.header.message_code = MetaMessageHideTipCode; - hidetip.header.length = META_MESSAGE_LENGTH (MetaMessageHideTip); - - send_message (uislave, (MetaMessage*)&hidetip, 0); -} - -void -meta_ui_slave_show_window_menu (MetaUISlave *uislave, - MetaWindow *window, - int root_x, - int root_y, - int button, - MetaMessageWindowMenuOps ops, - MetaMessageWindowMenuOps insensitive, - Time timestamp) -{ - MetaMessageShowWindowMenu showmenu; - - memset (&showmenu, 0, META_MESSAGE_LENGTH (MetaMessageShowWindowMenu)); - showmenu.header.message_code = MetaMessageShowWindowMenuCode; - showmenu.header.length = META_MESSAGE_LENGTH (MetaMessageShowWindowMenu); - - showmenu.window = window->xwindow; - showmenu.root_x = root_x; - showmenu.root_y = root_y; - showmenu.button = button; - showmenu.ops = ops; - showmenu.insensitive = insensitive; - showmenu.timestamp = timestamp; - - send_message (uislave, (MetaMessage*)&showmenu, 0); -} - -void -meta_ui_slave_hide_window_menu (MetaUISlave *uislave) -{ - MetaMessageHideWindowMenu hidemenu; - - memset (&hidemenu, 0, META_MESSAGE_LENGTH (MetaMessageHideWindowMenu)); - hidemenu.header.message_code = MetaMessageHideWindowMenuCode; - hidemenu.header.length = META_MESSAGE_LENGTH (MetaMessageHideWindowMenu); - - send_message (uislave, (MetaMessage*)&hidemenu, 0); -} diff --git a/src/uislave.h b/src/uislave.h deleted file mode 100644 index 3ea15eab7..000000000 --- a/src/uislave.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Metacity UI Slave */ - -/* - * 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. - */ - -#ifndef META_UI_SLAVE_H -#define META_UI_SLAVE_H - -#include "util.h" -#include "uislave/messages.h" -#include "messagequeue.h" -#include "display.h" - -typedef void (* MetaUISlaveFunc) (MetaUISlave *uislave, - MetaMessage *message, - gpointer data); - -struct _MetaUISlave -{ - char *display_name; - int child_pid; - int in_pipe; - int out_pipe; - - MetaMessageQueue *mq; - - MetaUISlaveFunc func; - gpointer data; - - int serial; - - /* if we determine that our available slave is hosed, - * set this bit. - */ - guint no_respawn : 1; -}; - -MetaUISlave* meta_ui_slave_new (const char *display_name, - MetaUISlaveFunc func, - gpointer data); -void meta_ui_slave_free (MetaUISlave *uislave); -void meta_ui_slave_disable (MetaUISlave *uislave); - -void meta_ui_slave_show_tip (MetaUISlave *uislave, - int root_x, - int root_y, - const char *markup_text); -void meta_ui_slave_hide_tip (MetaUISlave *uislave); - -void meta_ui_slave_show_window_menu (MetaUISlave *uislave, - MetaWindow *window, - int root_x, - int root_y, - int button, - MetaMessageWindowMenuOps ops, - MetaMessageWindowMenuOps insensitive, - Time timestamp); -void meta_ui_slave_hide_window_menu (MetaUISlave *uislave); - -#endif - diff --git a/src/uislave/frames.c b/src/uislave/frames.c index 4bd609c57..cb7e9d8b0 100644 --- a/src/uislave/frames.c +++ b/src/uislave/frames.c @@ -577,7 +577,9 @@ meta_frames_manage_window (MetaFrames *frames, if (frame->window == NULL) { + gdk_flush (); gdk_error_trap_pop (); + g_free (frame); meta_ui_warning ("Frame 0x%lx disappeared as we managed it\n", xwindow); return; } @@ -594,8 +596,22 @@ meta_frames_manage_window (MetaFrames *frames, gdk_drawable_get_size (GDK_DRAWABLE (frame->window), &frame->width, &frame->height); - - gdk_error_trap_pop (); + + XGrabButton (gdk_display, AnyButton, AnyModifier, + xwindow, False, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + False, None); + + gdk_flush (); + if (gdk_error_trap_pop ()) + { + g_object_unref (G_OBJECT (frame->window)); + g_free (frame); + meta_ui_warning ("Errors managing frame 0x%lx\n", xwindow); + return; + } frame->xwindow = xwindow; frame->layout = NULL;