Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
200cd629df | ||
![]() |
e8a29c1e82 | ||
![]() |
8589e4f3d3 | ||
![]() |
948e54772d | ||
![]() |
2d4b05a71b | ||
![]() |
a6433e84f5 | ||
![]() |
083854e2de | ||
![]() |
3508c4aa87 | ||
![]() |
d04b15ee25 | ||
![]() |
d6143e4c73 | ||
![]() |
d8ffc3c187 | ||
![]() |
2af788956e | ||
![]() |
d399141d13 |
@@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.50)
|
||||
|
||||
m4_define([mutter_major_version], [2])
|
||||
m4_define([mutter_minor_version], [27])
|
||||
m4_define([mutter_micro_version], [5])
|
||||
m4_define([mutter_minor_version], [28])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
|
@@ -16,10 +16,6 @@ mutter_built_sources = \
|
||||
mutter_SOURCES= \
|
||||
core/async-getprop.c \
|
||||
core/async-getprop.h \
|
||||
core/alttabhandler.c \
|
||||
include/alttabhandler.h \
|
||||
core/alttabhandlerdefault.c \
|
||||
include/alttabhandlerdefault.h \
|
||||
core/bell.c \
|
||||
core/bell.h \
|
||||
core/boxes.c \
|
||||
@@ -153,7 +149,6 @@ libmutterincludedir = $(includedir)/mutter/mutter-private
|
||||
# Headers installed for plugins; introspected information will
|
||||
# be extracted into Mutter-<version>.gir
|
||||
libmutterinclude_base_headers = \
|
||||
include/alttabhandler.h \
|
||||
include/boxes.h \
|
||||
ui/gradient.h \
|
||||
include/main.h \
|
||||
|
@@ -390,10 +390,10 @@ mutter_begin_modal_for_plugin (MetaScreen *screen,
|
||||
|
||||
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
XGrabKeyboard (xdpy, grab_window,
|
||||
False, /* owner_events */
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
timestamp);
|
||||
result = XGrabKeyboard (xdpy, grab_window,
|
||||
False, /* owner_events */
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
timestamp);
|
||||
|
||||
if (result != Success)
|
||||
goto fail;
|
||||
|
@@ -459,6 +459,18 @@ mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
mutter_set_stage_input_region (screen, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_plugin_get_windows:
|
||||
* @plugin: A #MutterPlugin
|
||||
*
|
||||
* This function returns all of the #MutterWindow objects referenced by Mutter, including
|
||||
* override-redirect windows. The returned list is a snapshot of Mutter's current
|
||||
* stacking order, with the topmost window last.
|
||||
*
|
||||
* The 'restacked' signal of #MetaScreen signals when this value has changed.
|
||||
*
|
||||
* Returns: (transfer none) (element-type MutterWindow): Windows in stacking order, topmost last
|
||||
*/
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
|
@@ -1,138 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include "alttabhandlerdefault.h"
|
||||
#include "screen-private.h"
|
||||
|
||||
static GType handler_type = G_TYPE_INVALID;
|
||||
|
||||
GType meta_alt_tab_handler_default_get_type (void);
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_register (GType type)
|
||||
{
|
||||
handler_type = type;
|
||||
}
|
||||
|
||||
MetaAltTabHandler *
|
||||
meta_alt_tab_handler_new (MetaScreen *screen,
|
||||
gboolean immediate)
|
||||
{
|
||||
if (handler_type == G_TYPE_INVALID)
|
||||
handler_type = meta_alt_tab_handler_default_get_type ();
|
||||
|
||||
return g_object_new (handler_type,
|
||||
"screen", screen,
|
||||
"immediate", immediate,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void meta_alt_tab_handler_class_init (GObjectClass *object_class);
|
||||
|
||||
GType
|
||||
meta_alt_tab_handler_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
const GTypeInfo type_info =
|
||||
{
|
||||
sizeof (MetaAltTabHandlerInterface), /* class_size */
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc)meta_alt_tab_handler_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
0,
|
||||
0, /* n_preallocs */
|
||||
NULL
|
||||
};
|
||||
GType g_define_type_id =
|
||||
g_type_register_static (G_TYPE_INTERFACE, "MetaAltTabHandler",
|
||||
&type_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
|
||||
|
||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
||||
}
|
||||
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_class_init (GObjectClass *object_class)
|
||||
{
|
||||
g_object_interface_install_property (object_class,
|
||||
g_param_spec_object ("screen",
|
||||
"Screen",
|
||||
"MetaScreen this is the switcher for",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_interface_install_property (object_class,
|
||||
g_param_spec_boolean ("immediate",
|
||||
"Immediate mode",
|
||||
"Whether or not to select windows immediately",
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->add_window (handler, window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->show (handler,
|
||||
initial_selection);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_destroy (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->destroy (handler);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_forward (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->forward (handler);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_backward (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->backward (handler);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler)
|
||||
{
|
||||
return META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->get_selected (handler);
|
||||
}
|
@@ -1,223 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction: default implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include "alttabhandlerdefault.h"
|
||||
#include "frame-private.h"
|
||||
#include "window-private.h"
|
||||
|
||||
static void meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaAltTabHandlerDefault, meta_alt_tab_handler_default, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_ALT_TAB_HANDLER,
|
||||
meta_alt_tab_handler_default_interface_init))
|
||||
|
||||
enum {
|
||||
PROP_SCREEN = 1,
|
||||
PROP_IMMEDIATE
|
||||
};
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_init (MetaAltTabHandlerDefault *hd)
|
||||
{
|
||||
hd->entries = g_array_new (FALSE, FALSE, sizeof (MetaTabEntry));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
hd->screen = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_IMMEDIATE:
|
||||
hd->immediate_mode = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_finalize (GObject *object)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
|
||||
|
||||
g_array_free (hd->entries, TRUE);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_free (hd->tab_popup);
|
||||
|
||||
G_OBJECT_CLASS (meta_alt_tab_handler_default_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
MetaTabEntry entry;
|
||||
MetaRectangle r;
|
||||
|
||||
entry.key = (MetaTabEntryKey) window;
|
||||
entry.title = window->title;
|
||||
entry.icon = window->icon;
|
||||
entry.blank = FALSE;
|
||||
entry.hidden = !meta_window_showing_on_its_workspace (window);
|
||||
entry.demands_attention = window->wm_state_demands_attention;
|
||||
|
||||
if (hd->immediate_mode || !entry.hidden ||
|
||||
!meta_window_get_icon_geometry (window, &r))
|
||||
meta_window_get_outer_rect (window, &r);
|
||||
entry.rect = r;
|
||||
|
||||
/* Find inside of highlight rectangle to be used when window is
|
||||
* outlined for tabbing. This should be the size of the
|
||||
* east/west frame, and the size of the south frame, on those
|
||||
* sides. On the top it should be the size of the south frame
|
||||
* edge.
|
||||
*/
|
||||
#define OUTLINE_WIDTH 5
|
||||
/* Top side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->bottom_height > 0 &&
|
||||
window->frame->child_y >= window->frame->bottom_height)
|
||||
entry.inner_rect.y = window->frame->bottom_height;
|
||||
else
|
||||
entry.inner_rect.y = OUTLINE_WIDTH;
|
||||
|
||||
/* Bottom side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->bottom_height != 0)
|
||||
entry.inner_rect.height = r.height
|
||||
- entry.inner_rect.y - window->frame->bottom_height;
|
||||
else
|
||||
entry.inner_rect.height = r.height
|
||||
- entry.inner_rect.y - OUTLINE_WIDTH;
|
||||
|
||||
/* Left side */
|
||||
if (!entry.hidden && window->frame && window->frame->child_x != 0)
|
||||
entry.inner_rect.x = window->frame->child_x;
|
||||
else
|
||||
entry.inner_rect.x = OUTLINE_WIDTH;
|
||||
|
||||
/* Right side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->right_width != 0)
|
||||
entry.inner_rect.width = r.width
|
||||
- entry.inner_rect.x - window->frame->right_width;
|
||||
else
|
||||
entry.inner_rect.width = r.width
|
||||
- entry.inner_rect.x - OUTLINE_WIDTH;
|
||||
|
||||
g_array_append_val (hd->entries, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
return;
|
||||
|
||||
hd->tab_popup = meta_ui_tab_popup_new ((MetaTabEntry *)hd->entries->data,
|
||||
hd->screen->number,
|
||||
hd->entries->len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
meta_ui_tab_popup_select (hd->tab_popup, (MetaTabEntryKey) initial_selection);
|
||||
meta_ui_tab_popup_set_showing (hd->tab_popup, !hd->immediate_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_destroy (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
{
|
||||
meta_ui_tab_popup_free (hd->tab_popup);
|
||||
hd->tab_popup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_forward (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_forward (hd->tab_popup);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_backward (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_backward (hd->tab_popup);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
meta_alt_tab_handler_default_get_selected (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
return (MetaWindow *)meta_ui_tab_popup_get_selected (hd->tab_popup);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_class_init (MetaAltTabHandlerDefaultClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = meta_alt_tab_handler_default_set_property;
|
||||
object_class->finalize = meta_alt_tab_handler_default_finalize;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_SCREEN, "screen");
|
||||
g_object_class_override_property (object_class, PROP_IMMEDIATE, "immediate");
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface)
|
||||
{
|
||||
handler_iface->add_window = meta_alt_tab_handler_default_add_window;
|
||||
handler_iface->show = meta_alt_tab_handler_default_show;
|
||||
handler_iface->destroy = meta_alt_tab_handler_default_destroy;
|
||||
handler_iface->forward = meta_alt_tab_handler_default_forward;
|
||||
handler_iface->backward = meta_alt_tab_handler_default_backward;
|
||||
handler_iface->get_selected = meta_alt_tab_handler_default_get_selected;
|
||||
}
|
@@ -150,6 +150,15 @@ struct _MetaDisplay
|
||||
|
||||
guint32 current_time;
|
||||
|
||||
/* We maintain a sequence counter, incremented for each #MetaWindow
|
||||
* created. This is exposed by meta_window_get_stable_sequence()
|
||||
* but is otherwise not used inside mutter.
|
||||
*
|
||||
* It can be useful to plugins which want to sort windows in a
|
||||
* stable fashion.
|
||||
*/
|
||||
guint32 window_sequence_counter;
|
||||
|
||||
/* Pings which we're waiting for a reply from */
|
||||
GSList *pending_pings;
|
||||
|
||||
|
@@ -2047,15 +2047,11 @@ process_tab_grab (MetaDisplay *display,
|
||||
action = META_KEYBINDING_ACTION_NONE;
|
||||
|
||||
/*
|
||||
* There are currently two different ways of customizing Alt-Tab, you can either
|
||||
* provide a replacement AltTabHandler object, or you can hook into the keybindings
|
||||
* meta_keybindings_set_custom_handler() and call meta_display_begin_grab_op()
|
||||
* yourself with one of the "tabbing" grab ops META_GRAB_OP_KEYBOARD_TABBING_NORMAL,
|
||||
* etc. See meta_display_process_key_event() for the complete list. If screen->tab_handler
|
||||
* is NULL, the latter mechanism is being used. We skip most of our normal
|
||||
* processing and just make sure that the right custom handlers get called.
|
||||
* If there is no tab_pop up object, i.e., there is some custom handler
|
||||
* implementing Alt+Tab & Co., we call this custom handler; we do not
|
||||
* mess about with the grab, as that is up to the handler to deal with.
|
||||
*/
|
||||
if (!screen->tab_handler)
|
||||
if (!screen->tab_popup)
|
||||
{
|
||||
if (event->type == KeyRelease)
|
||||
{
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include "screen.h"
|
||||
#include <X11/Xutil.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "alttabhandler.h"
|
||||
#include "ui.h"
|
||||
|
||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
@@ -82,9 +81,8 @@ struct _MetaScreen
|
||||
Visual *default_xvisual;
|
||||
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
|
||||
MetaUI *ui;
|
||||
MetaAltTabHandler *tab_handler;
|
||||
MetaTabPopup *ws_popup;
|
||||
|
||||
MetaTabPopup *tab_popup, *ws_popup;
|
||||
|
||||
MetaWorkspace *active_workspace;
|
||||
|
||||
/* This window holds the focus when we don't want to focus
|
||||
@@ -119,7 +117,7 @@ struct _MetaScreen
|
||||
|
||||
Window wm_cm_selection_window;
|
||||
|
||||
guint work_area_idle;
|
||||
guint work_area_later;
|
||||
|
||||
int rows_of_workspaces;
|
||||
int columns_of_workspaces;
|
||||
@@ -147,7 +145,8 @@ struct _MetaScreenClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*restacked) (MetaScreen *);
|
||||
void (*restacked) (MetaScreen *);
|
||||
void (*workareas_changed) (MetaScreen *);
|
||||
};
|
||||
|
||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||
|
@@ -38,7 +38,6 @@
|
||||
#include "stack.h"
|
||||
#include "xprops.h"
|
||||
#include "compositor.h"
|
||||
#include "alttabhandlerdefault.h"
|
||||
#include "mutter-marshal.h"
|
||||
#include "mutter-enum-types.h"
|
||||
|
||||
@@ -86,6 +85,7 @@ enum
|
||||
WORKSPACE_REMOVED,
|
||||
WORKSPACE_SWITCHED,
|
||||
STARTUP_SEQUENCE_CHANGED,
|
||||
WORKAREAS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -218,6 +218,15 @@ meta_screen_class_init (MetaScreenClass *klass)
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
screen_signals[WORKAREAS_CHANGED] =
|
||||
g_signal_new ("workareas-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MetaScreenClass, workareas_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WORKSPACES,
|
||||
pspec);
|
||||
@@ -687,7 +696,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
NoEventMask);
|
||||
screen->work_area_idle = 0;
|
||||
screen->work_area_later = 0;
|
||||
|
||||
screen->active_workspace = NULL;
|
||||
screen->workspaces = NULL;
|
||||
@@ -781,9 +790,9 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->ui = meta_ui_new (screen->display->xdisplay,
|
||||
screen->xscreen);
|
||||
|
||||
screen->tab_handler = NULL;
|
||||
screen->tab_popup = NULL;
|
||||
screen->ws_popup = NULL;
|
||||
|
||||
|
||||
screen->stack = meta_stack_new (screen);
|
||||
screen->stack_tracker = meta_stack_tracker_new (screen);
|
||||
|
||||
@@ -874,8 +883,8 @@ meta_screen_free (MetaScreen *screen,
|
||||
XDestroyWindow (screen->display->xdisplay,
|
||||
screen->wm_sn_selection_window);
|
||||
|
||||
if (screen->work_area_idle != 0)
|
||||
g_source_remove (screen->work_area_idle);
|
||||
if (screen->work_area_later != 0)
|
||||
g_source_remove (screen->work_area_later);
|
||||
|
||||
|
||||
if (XGetGCValues (screen->display->xdisplay,
|
||||
@@ -1516,58 +1525,146 @@ meta_screen_tab_popup_create (MetaScreen *screen,
|
||||
MetaTabShowType show_type,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
MetaTabEntry *entries;
|
||||
GList *tab_list;
|
||||
GList *tmp;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (screen->tab_handler == NULL);
|
||||
|
||||
screen->tab_handler = meta_alt_tab_handler_new (screen,
|
||||
show_type == META_TAB_SHOW_INSTANTLY);
|
||||
if (screen->tab_popup)
|
||||
return;
|
||||
|
||||
tab_list = meta_display_get_tab_list (screen->display,
|
||||
list_type,
|
||||
screen,
|
||||
screen->active_workspace);
|
||||
|
||||
for (tmp = tab_list; tmp; tmp = tmp->next)
|
||||
meta_alt_tab_handler_add_window (screen->tab_handler, tmp->data);
|
||||
|
||||
meta_alt_tab_handler_show (screen->tab_handler, initial_selection);
|
||||
|
||||
len = g_list_length (tab_list);
|
||||
|
||||
entries = g_new (MetaTabEntry, len + 1);
|
||||
entries[len].key = NULL;
|
||||
entries[len].title = NULL;
|
||||
entries[len].icon = NULL;
|
||||
|
||||
i = 0;
|
||||
tmp = tab_list;
|
||||
while (i < len)
|
||||
{
|
||||
MetaWindow *window;
|
||||
MetaRectangle r;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
entries[i].key = (MetaTabEntryKey) window;
|
||||
entries[i].title = window->title;
|
||||
entries[i].icon = g_object_ref (window->icon);
|
||||
entries[i].blank = FALSE;
|
||||
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
|
||||
entries[i].demands_attention = window->wm_state_demands_attention;
|
||||
|
||||
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
||||
!entries[i].hidden ||
|
||||
!meta_window_get_icon_geometry (window, &r))
|
||||
meta_window_get_outer_rect (window, &r);
|
||||
|
||||
entries[i].rect = r;
|
||||
|
||||
/* Find inside of highlight rectangle to be used when window is
|
||||
* outlined for tabbing. This should be the size of the
|
||||
* east/west frame, and the size of the south frame, on those
|
||||
* sides. On the top it should be the size of the south frame
|
||||
* edge.
|
||||
*/
|
||||
#define OUTLINE_WIDTH 5
|
||||
/* Top side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->bottom_height > 0 &&
|
||||
window->frame->child_y >= window->frame->bottom_height)
|
||||
entries[i].inner_rect.y = window->frame->bottom_height;
|
||||
else
|
||||
entries[i].inner_rect.y = OUTLINE_WIDTH;
|
||||
|
||||
/* Bottom side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->bottom_height != 0)
|
||||
entries[i].inner_rect.height = r.height
|
||||
- entries[i].inner_rect.y - window->frame->bottom_height;
|
||||
else
|
||||
entries[i].inner_rect.height = r.height
|
||||
- entries[i].inner_rect.y - OUTLINE_WIDTH;
|
||||
|
||||
/* Left side */
|
||||
if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
|
||||
entries[i].inner_rect.x = window->frame->child_x;
|
||||
else
|
||||
entries[i].inner_rect.x = OUTLINE_WIDTH;
|
||||
|
||||
/* Right side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->right_width != 0)
|
||||
entries[i].inner_rect.width = r.width
|
||||
- entries[i].inner_rect.x - window->frame->right_width;
|
||||
else
|
||||
entries[i].inner_rect.width = r.width
|
||||
- entries[i].inner_rect.x - OUTLINE_WIDTH;
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (!meta_prefs_get_no_tab_popup ())
|
||||
screen->tab_popup = meta_ui_tab_popup_new (entries,
|
||||
screen->number,
|
||||
len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_object_unref (entries[i].icon);
|
||||
|
||||
g_free (entries);
|
||||
|
||||
g_list_free (tab_list);
|
||||
|
||||
meta_ui_tab_popup_select (screen->tab_popup,
|
||||
(MetaTabEntryKey) initial_selection);
|
||||
|
||||
if (show_type != META_TAB_SHOW_INSTANTLY)
|
||||
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_forward (MetaScreen *screen)
|
||||
{
|
||||
g_return_if_fail (screen->tab_handler != NULL);
|
||||
g_return_if_fail (screen->tab_popup != NULL);
|
||||
|
||||
meta_alt_tab_handler_forward (screen->tab_handler);
|
||||
meta_ui_tab_popup_forward (screen->tab_popup);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_backward (MetaScreen *screen)
|
||||
{
|
||||
g_return_if_fail (screen->tab_handler != NULL);
|
||||
g_return_if_fail (screen->tab_popup != NULL);
|
||||
|
||||
meta_alt_tab_handler_backward (screen->tab_handler);
|
||||
meta_ui_tab_popup_backward (screen->tab_popup);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_screen_tab_popup_get_selected (MetaScreen *screen)
|
||||
{
|
||||
g_return_val_if_fail (screen->tab_handler != NULL, NULL);
|
||||
g_return_val_if_fail (screen->tab_popup != NULL, NULL);
|
||||
|
||||
return meta_alt_tab_handler_get_selected (screen->tab_handler);
|
||||
return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_destroy (MetaScreen *screen)
|
||||
{
|
||||
if (!screen->tab_handler)
|
||||
return;
|
||||
|
||||
meta_alt_tab_handler_destroy (screen->tab_handler);
|
||||
g_object_unref (screen->tab_handler);
|
||||
screen->tab_handler = NULL;
|
||||
if (screen->tab_popup)
|
||||
{
|
||||
meta_ui_tab_popup_free (screen->tab_popup);
|
||||
screen->tab_popup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1580,8 +1677,9 @@ meta_screen_workspace_popup_create (MetaScreen *screen,
|
||||
MetaWorkspaceLayout layout;
|
||||
int n_workspaces;
|
||||
int current_workspace;
|
||||
|
||||
g_return_if_fail (screen->ws_popup == NULL);
|
||||
|
||||
if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
|
||||
return;
|
||||
|
||||
current_workspace = meta_workspace_index (screen->active_workspace);
|
||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
@@ -2200,15 +2298,17 @@ set_work_area_hint (MetaScreen *screen)
|
||||
(guchar*) data, num_workspaces*4);
|
||||
g_free (data);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
|
||||
g_signal_emit (screen, screen_signals[WORKAREAS_CHANGED], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_work_area_idle_func (MetaScreen *screen)
|
||||
set_work_area_later_func (MetaScreen *screen)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Running work area idle function\n");
|
||||
"Running work area hint computation function\n");
|
||||
|
||||
screen->work_area_idle = 0;
|
||||
screen->work_area_later = 0;
|
||||
|
||||
set_work_area_hint (screen);
|
||||
|
||||
@@ -2218,16 +2318,16 @@ set_work_area_idle_func (MetaScreen *screen)
|
||||
void
|
||||
meta_screen_queue_workarea_recalc (MetaScreen *screen)
|
||||
{
|
||||
/* Recompute work area in an idle */
|
||||
if (screen->work_area_idle == 0)
|
||||
/* Recompute work area later before redrawing */
|
||||
if (screen->work_area_later == 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Adding work area hint idle function\n");
|
||||
screen->work_area_idle =
|
||||
g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
|
||||
(GSourceFunc) set_work_area_idle_func,
|
||||
screen,
|
||||
NULL);
|
||||
"Adding work area hint computation function\n");
|
||||
screen->work_area_later =
|
||||
meta_later_add (META_LATER_BEFORE_REDRAW,
|
||||
(GSourceFunc) set_work_area_later_func,
|
||||
screen,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -134,7 +134,7 @@ struct _MetaStackTracker
|
||||
/* Idle function used to sync the compositor's view of the window
|
||||
* stack up with our best guess before a frame is drawn.
|
||||
*/
|
||||
guint sync_stack_idle;
|
||||
guint sync_stack_later;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -383,8 +383,8 @@ meta_stack_tracker_new (MetaScreen *screen)
|
||||
void
|
||||
meta_stack_tracker_free (MetaStackTracker *tracker)
|
||||
{
|
||||
if (tracker->sync_stack_idle)
|
||||
g_source_remove (tracker->sync_stack_idle);
|
||||
if (tracker->sync_stack_later)
|
||||
meta_later_remove (tracker->sync_stack_later);
|
||||
|
||||
g_array_free (tracker->server_stack, TRUE);
|
||||
if (tracker->predicted_stack)
|
||||
@@ -667,10 +667,10 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
int n_windows;
|
||||
int i;
|
||||
|
||||
if (tracker->sync_stack_idle)
|
||||
if (tracker->sync_stack_later)
|
||||
{
|
||||
g_source_remove (tracker->sync_stack_idle);
|
||||
tracker->sync_stack_idle = 0;
|
||||
meta_later_remove (tracker->sync_stack_later);
|
||||
tracker->sync_stack_later = 0;
|
||||
}
|
||||
|
||||
meta_stack_tracker_get_stack (tracker, &windows, &n_windows);
|
||||
@@ -696,7 +696,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stack_tracker_sync_stack_idle (gpointer data)
|
||||
stack_tracker_sync_stack_later (gpointer data)
|
||||
{
|
||||
meta_stack_tracker_sync_stack (data);
|
||||
|
||||
@@ -719,10 +719,10 @@ stack_tracker_sync_stack_idle (gpointer data)
|
||||
void
|
||||
meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker)
|
||||
{
|
||||
if (tracker->sync_stack_idle == 0)
|
||||
if (tracker->sync_stack_later == 0)
|
||||
{
|
||||
tracker->sync_stack_idle = g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
|
||||
stack_tracker_sync_stack_idle,
|
||||
tracker->sync_stack_later = meta_later_add (META_LATER_BEFORE_REDRAW,
|
||||
stack_tracker_sync_stack_later,
|
||||
tracker, NULL);
|
||||
}
|
||||
}
|
||||
|
199
src/core/util.c
199
src/core/util.c
@@ -26,9 +26,12 @@
|
||||
#define _POSIX_C_SOURCE 200112L /* for fdopen() */
|
||||
|
||||
#include <config.h>
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <clutter/clutter.h> /* For clutter_threads_add_repaint_func() */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -663,5 +666,201 @@ meta_nexus_get_type (void)
|
||||
return nexus_type;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Later functions: like idles but integrated with the Clutter repaint loop
|
||||
***************************************************************************/
|
||||
|
||||
static guint last_later_id = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint id;
|
||||
MetaLaterType when;
|
||||
GSourceFunc func;
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
int source;
|
||||
gboolean run_once;
|
||||
} MetaLater;
|
||||
|
||||
static GSList *laters = NULL;
|
||||
/* This is a dummy timeline used to get the Clutter master clock running */
|
||||
static ClutterTimeline *later_timeline;
|
||||
static guint later_repaint_func = 0;
|
||||
|
||||
static void ensure_later_repaint_func (void);
|
||||
|
||||
static void
|
||||
destroy_later (MetaLater *later)
|
||||
{
|
||||
if (later->source)
|
||||
g_source_remove (later->source);
|
||||
if (later->notify)
|
||||
later->notify (later->data);
|
||||
g_slice_free (MetaLater, later);
|
||||
}
|
||||
|
||||
/* Used to sort the list of laters with the highest priority
|
||||
* functions first.
|
||||
*/
|
||||
static int
|
||||
compare_laters (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
run_repaint_laters (gpointer data)
|
||||
{
|
||||
GSList *old_laters = laters;
|
||||
GSList *l;
|
||||
gboolean keep_timeline_running = FALSE;
|
||||
laters = NULL;
|
||||
|
||||
for (l = old_laters; l; l = l->next)
|
||||
{
|
||||
MetaLater *later = l->data;
|
||||
if (later->source == 0 ||
|
||||
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
|
||||
{
|
||||
if (later->func (later->data))
|
||||
{
|
||||
if (later->source == 0)
|
||||
keep_timeline_running = TRUE;
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
}
|
||||
else
|
||||
destroy_later (later);
|
||||
}
|
||||
else
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
}
|
||||
|
||||
if (!keep_timeline_running)
|
||||
clutter_timeline_stop (later_timeline);
|
||||
|
||||
g_slist_free (old_laters);
|
||||
|
||||
/* Just keep the repaint func around - it's cheap if the list is empty */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_later_repaint_func (void)
|
||||
{
|
||||
if (!later_timeline)
|
||||
later_timeline = clutter_timeline_new (G_MAXUINT);
|
||||
|
||||
if (later_repaint_func == 0)
|
||||
later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters,
|
||||
NULL, NULL);
|
||||
|
||||
/* Make sure the repaint function gets run */
|
||||
clutter_timeline_start (later_timeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
call_idle_later (gpointer data)
|
||||
{
|
||||
MetaLater *later = data;
|
||||
|
||||
if (!later->func (later->data))
|
||||
{
|
||||
laters = g_slist_remove (laters, later);
|
||||
later->source = 0;
|
||||
destroy_later (later);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
later->run_once = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_later_add:
|
||||
* @when: enumeration value determining the phase at which to run the callback
|
||||
* @func: callback to run later
|
||||
* @data: data to pass to the callback
|
||||
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
|
||||
*
|
||||
* Sets up a callback to be called at some later time. @when determines the
|
||||
* particular later occasion at which it is called. This is much like g_idle_add(),
|
||||
* except that the functions interact properly with clutter event handling.
|
||||
* If a "later" function is added from a clutter event handler, and is supposed
|
||||
* to be run before the stage is redrawn, it will be run before that redraw
|
||||
* of the stage, not the next one.
|
||||
*
|
||||
* Return value: an integer ID (guaranteed to be non-zero) that can be used
|
||||
* to cancel the callback and prevent it from being run.
|
||||
*/
|
||||
guint
|
||||
meta_later_add (MetaLaterType when,
|
||||
GSourceFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
MetaLater *later = g_slice_new0 (MetaLater);
|
||||
|
||||
later->id = ++last_later_id;
|
||||
later->when = when;
|
||||
later->func = func;
|
||||
later->data = data;
|
||||
later->notify = notify;
|
||||
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
|
||||
switch (when)
|
||||
{
|
||||
case META_LATER_RESIZE:
|
||||
/* We add this one two ways - as a high-priority idle and as a
|
||||
* repaint func. If we are in a clutter event callback, the repaint
|
||||
* handler will get hit first, and we'll take care of this function
|
||||
* there so it gets called before the stage is redrawn, even if
|
||||
* we haven't gotten back to the main loop. Otherwise, the idle
|
||||
* handler will get hit first and we want to call this function
|
||||
* there so it will happen before GTK+ repaints.
|
||||
*/
|
||||
later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL);
|
||||
ensure_later_repaint_func ();
|
||||
break;
|
||||
case META_LATER_BEFORE_REDRAW:
|
||||
ensure_later_repaint_func ();
|
||||
break;
|
||||
case META_LATER_IDLE:
|
||||
later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return later->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_later_remove:
|
||||
* @later_id: the integer ID returned from meta_later_add()
|
||||
*
|
||||
* Removes a callback added with meta_later_add()
|
||||
*/
|
||||
void
|
||||
meta_later_remove (guint later_id)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = laters; l; l = l->next)
|
||||
{
|
||||
MetaLater *later = l->data;
|
||||
if (later->id == later_id)
|
||||
{
|
||||
laters = g_slist_remove_link (laters, l);
|
||||
/* If this was a "repaint func" later, we just let the
|
||||
* repaint func run and get removed
|
||||
*/
|
||||
destroy_later (later);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* eof util.c */
|
||||
|
||||
|
@@ -316,6 +316,9 @@ struct _MetaWindow
|
||||
*/
|
||||
int unmaps_pending;
|
||||
|
||||
/* See docs for meta_window_get_stable_sequence() */
|
||||
guint32 stable_sequence;
|
||||
|
||||
/* set to the most recent user-interaction event timestamp that we
|
||||
know about for this window */
|
||||
guint32 net_wm_user_time;
|
||||
|
@@ -116,8 +116,9 @@ static void meta_window_apply_session_info (MetaWindow *window,
|
||||
static void unmaximize_window_before_freeing (MetaWindow *window);
|
||||
static void unminimize_window_and_all_transient_parents (MetaWindow *window);
|
||||
|
||||
/* Idle handlers for the three queues. The "data" parameter in each case
|
||||
* will be a GINT_TO_POINTER of the index into the queue arrays to use.
|
||||
/* Idle handlers for the three queues (run with meta_later_add()). The
|
||||
* "data" parameter in each case will be a GINT_TO_POINTER of the
|
||||
* index into the queue arrays to use.
|
||||
*
|
||||
* TODO: Possibly there is still some code duplication among these, which we
|
||||
* need to sort out at some point.
|
||||
@@ -802,6 +803,10 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
|
||||
meta_display_register_x_window (display, &window->xwindow, window);
|
||||
|
||||
/* Assign this #MetaWindow a sequence number which can be used
|
||||
* for sorting.
|
||||
*/
|
||||
window->stable_sequence = ++display->window_sequence_counter;
|
||||
|
||||
/* assign the window to its group, or create a new group if needed
|
||||
*/
|
||||
@@ -1701,7 +1706,7 @@ meta_window_calc_showing (MetaWindow *window)
|
||||
implement_showing (window, meta_window_should_be_showing (window));
|
||||
}
|
||||
|
||||
static guint queue_idle[NUMBER_OF_QUEUES] = {0, 0, 0};
|
||||
static guint queue_later[NUMBER_OF_QUEUES] = {0, 0, 0};
|
||||
static GSList *queue_pending[NUMBER_OF_QUEUES] = {NULL, NULL, NULL};
|
||||
|
||||
static int
|
||||
@@ -1739,7 +1744,7 @@ idle_calc_showing (gpointer data)
|
||||
copy = g_slist_copy (queue_pending[queue_index]);
|
||||
g_slist_free (queue_pending[queue_index]);
|
||||
queue_pending[queue_index] = NULL;
|
||||
queue_idle[queue_index] = 0;
|
||||
queue_later[queue_index] = 0;
|
||||
|
||||
destroying_windows_disallowed += 1;
|
||||
|
||||
@@ -1897,10 +1902,10 @@ meta_window_unqueue (MetaWindow *window, guint queuebits)
|
||||
* In that case, we should kill the function that deals with
|
||||
* the queue, because there's nothing left for it to do.
|
||||
*/
|
||||
if (queue_pending[queuenum] == NULL && queue_idle[queuenum] != 0)
|
||||
if (queue_pending[queuenum] == NULL && queue_later[queuenum] != 0)
|
||||
{
|
||||
g_source_remove (queue_idle[queuenum]);
|
||||
queue_idle[queuenum] = 0;
|
||||
meta_later_remove (queue_later[queuenum]);
|
||||
queue_later[queuenum] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1933,14 +1938,14 @@ meta_window_queue (MetaWindow *window, guint queuebits)
|
||||
* I seem to be turning into a Perl programmer.
|
||||
*/
|
||||
|
||||
const gint window_queue_idle_priority[NUMBER_OF_QUEUES] =
|
||||
const MetaLaterType window_queue_later_when[NUMBER_OF_QUEUES] =
|
||||
{
|
||||
META_PRIORITY_BEFORE_REDRAW, /* CALC_SHOWING */
|
||||
META_PRIORITY_RESIZE, /* MOVE_RESIZE */
|
||||
META_PRIORITY_BEFORE_REDRAW /* UPDATE_ICON */
|
||||
META_LATER_BEFORE_REDRAW, /* CALC_SHOWING */
|
||||
META_LATER_RESIZE, /* MOVE_RESIZE */
|
||||
META_LATER_BEFORE_REDRAW /* UPDATE_ICON */
|
||||
};
|
||||
|
||||
const GSourceFunc window_queue_idle_handler[NUMBER_OF_QUEUES] =
|
||||
const GSourceFunc window_queue_later_handler[NUMBER_OF_QUEUES] =
|
||||
{
|
||||
idle_calc_showing,
|
||||
idle_move_resize,
|
||||
@@ -1973,11 +1978,11 @@ meta_window_queue (MetaWindow *window, guint queuebits)
|
||||
* that. If not, we'll create one.
|
||||
*/
|
||||
|
||||
if (queue_idle[queuenum] == 0)
|
||||
queue_idle[queuenum] = g_idle_add_full
|
||||
if (queue_later[queuenum] == 0)
|
||||
queue_later[queuenum] = meta_later_add
|
||||
(
|
||||
window_queue_idle_priority[queuenum],
|
||||
window_queue_idle_handler[queuenum],
|
||||
window_queue_later_when[queuenum],
|
||||
window_queue_later_handler[queuenum],
|
||||
GUINT_TO_POINTER(queuenum),
|
||||
NULL
|
||||
);
|
||||
@@ -2726,7 +2731,14 @@ meta_window_hide (MetaWindow *window)
|
||||
invalidate_work_areas (window);
|
||||
}
|
||||
|
||||
if (window->has_focus)
|
||||
/* The check on expected_focus_window is a temporary workaround for
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=597352
|
||||
* We may have already switched away from this window but not yet
|
||||
* gotten FocusIn/FocusOut events. A more complete comprehensive
|
||||
* fix for these type of issues is described in the bug.
|
||||
*/
|
||||
if (window->has_focus &&
|
||||
window == window->display->expected_focus_window)
|
||||
{
|
||||
MetaWindow *not_this_one = NULL;
|
||||
MetaWorkspace *my_workspace = meta_window_get_workspace (window);
|
||||
@@ -4196,7 +4208,7 @@ idle_move_resize (gpointer data)
|
||||
copy = g_slist_copy (queue_pending[queue_index]);
|
||||
g_slist_free (queue_pending[queue_index]);
|
||||
queue_pending[queue_index] = NULL;
|
||||
queue_idle[queue_index] = 0;
|
||||
queue_later[queue_index] = 0;
|
||||
|
||||
destroying_windows_disallowed += 1;
|
||||
|
||||
@@ -6258,7 +6270,7 @@ idle_update_icon (gpointer data)
|
||||
copy = g_slist_copy (queue_pending[queue_index]);
|
||||
g_slist_free (queue_pending[queue_index]);
|
||||
queue_pending[queue_index] = NULL;
|
||||
queue_idle[queue_index] = 0;
|
||||
queue_later[queue_index] = 0;
|
||||
|
||||
destroying_windows_disallowed += 1;
|
||||
|
||||
@@ -8532,6 +8544,26 @@ meta_window_set_user_time (MetaWindow *window,
|
||||
g_object_notify (G_OBJECT (window), "user-time");
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_stable_sequence:
|
||||
* @window: A #MetaWindow
|
||||
*
|
||||
* The stable sequence number is a monotonicially increasing
|
||||
* unique integer assigned to each #MetaWindow upon creation.
|
||||
*
|
||||
* This number can be useful for sorting windows in a stable
|
||||
* fashion.
|
||||
*
|
||||
* Returns: Internal sequence number for this window
|
||||
*/
|
||||
guint32
|
||||
meta_window_get_stable_sequence (MetaWindow *window)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_WINDOW (window), 0);
|
||||
|
||||
return window->stable_sequence;
|
||||
}
|
||||
|
||||
/* Sets the demands_attention hint on a window, but only
|
||||
* if it's at least partially obscured (see #305882).
|
||||
*/
|
||||
@@ -8835,6 +8867,25 @@ meta_window_get_transient_for (MetaWindow *window)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_transient_for_as_xid:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Returns the XID of the window that is pointed to by the
|
||||
* WM_TRANSIENT_FOR hint on this window (see XGetTransientForHint()
|
||||
* or XSetTransientForHint()). Metacity keeps transient windows above their
|
||||
* parents. A typical usage of this hint is for a dialog that wants to stay
|
||||
* above its associated window.
|
||||
*
|
||||
* Return value: (transfer none): the window this window is transient for, or
|
||||
* None if the WM_TRANSIENT_FOR hint is unset.
|
||||
*/
|
||||
Window
|
||||
meta_window_get_transient_for_as_xid (MetaWindow *window)
|
||||
{
|
||||
return window->xtransient_for;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_pid:
|
||||
* @window: a #MetaWindow
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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_ALT_TAB_HANDLER_H
|
||||
#define META_ALT_TAB_HANDLER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define META_TYPE_ALT_TAB_HANDLER (meta_alt_tab_handler_get_type ())
|
||||
#define META_ALT_TAB_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandler))
|
||||
#define META_ALT_TAB_HANDLER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandlerInterface))
|
||||
|
||||
typedef struct _MetaAltTabHandler MetaAltTabHandler;
|
||||
typedef struct _MetaAltTabHandlerInterface MetaAltTabHandlerInterface;
|
||||
|
||||
struct _MetaAltTabHandlerInterface {
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (*add_window) (MetaAltTabHandler *handler,
|
||||
MetaWindow *window);
|
||||
|
||||
void (*show) (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection);
|
||||
void (*destroy) (MetaAltTabHandler *handler);
|
||||
|
||||
void (*forward) (MetaAltTabHandler *handler);
|
||||
void (*backward) (MetaAltTabHandler *handler);
|
||||
|
||||
MetaWindow * (*get_selected) (MetaAltTabHandler *handler);
|
||||
};
|
||||
|
||||
GType meta_alt_tab_handler_get_type (void);
|
||||
|
||||
void meta_alt_tab_handler_register (GType type);
|
||||
MetaAltTabHandler *meta_alt_tab_handler_new (MetaScreen *screen,
|
||||
gboolean immediate);
|
||||
|
||||
void meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_alt_tab_handler_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection);
|
||||
void meta_alt_tab_handler_destroy (MetaAltTabHandler *handler);
|
||||
|
||||
void meta_alt_tab_handler_forward (MetaAltTabHandler *handler);
|
||||
void meta_alt_tab_handler_backward (MetaAltTabHandler *handler);
|
||||
|
||||
MetaWindow *meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler);
|
||||
|
||||
#endif
|
||||
|
@@ -1,55 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction: default implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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_ALT_TAB_HANDLER_DEFAULT_H
|
||||
#define META_ALT_TAB_HANDLER_DEFAULT_H
|
||||
|
||||
#include "alttabhandler.h"
|
||||
#include "tabpopup.h"
|
||||
|
||||
#define META_TYPE_ALT_TAB_HANDLER_DEFAULT (meta_alt_tab_handler_default_get_type ())
|
||||
#define META_ALT_TAB_HANDLER_DEFAULT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER_DEFAULT, MetaAltTabHandlerDefault))
|
||||
|
||||
typedef struct _MetaAltTabHandlerDefault MetaAltTabHandlerDefault;
|
||||
typedef struct _MetaAltTabHandlerDefaultClass MetaAltTabHandlerDefaultClass;
|
||||
|
||||
struct _MetaAltTabHandlerDefault {
|
||||
GObject parent_instance;
|
||||
|
||||
MetaScreen *screen;
|
||||
|
||||
GArray *entries;
|
||||
gboolean immediate_mode;
|
||||
|
||||
MetaTabPopup *tab_popup;
|
||||
};
|
||||
|
||||
struct _MetaAltTabHandlerDefaultClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
GType meta_alt_tab_handler_default_get_type (void);
|
||||
|
||||
#endif
|
||||
|
@@ -317,8 +317,10 @@ struct _MetaButtonLayout
|
||||
* coelesce multiple things together, the appropriate place to
|
||||
* do it is usually META_PRIORITY_BEFORE_REDRAW.
|
||||
*
|
||||
* (FIXME: Use a Clutter paint() function instead, to prevent
|
||||
* starving the repaints)
|
||||
* Note that its usually better to use meta_later_add() rather
|
||||
* than calling g_idle_add() directly; this will make sure things
|
||||
* get run when added from a clutter event handler without
|
||||
* waiting for another repaint cycle.
|
||||
*
|
||||
* If something has a priority lower than the redraw priority
|
||||
* (such as a default priority idle), then it may be arbitrarily
|
||||
|
@@ -161,6 +161,26 @@ MetaNexus *meta_nexus_new ();
|
||||
*/
|
||||
extern MetaNexus *sigchld_nexus;
|
||||
|
||||
/**
|
||||
* MetaLaterType:
|
||||
* @META_LATER_RESIZE: call in a resize processing phase that is done
|
||||
* before GTK+ repainting (including window borders) is done.
|
||||
* @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
|
||||
* @META_LATER_IDLE: call at a very low priority (can be blocked
|
||||
* by running animations or redrawing applications)
|
||||
**/
|
||||
typedef enum {
|
||||
META_LATER_RESIZE,
|
||||
META_LATER_BEFORE_REDRAW,
|
||||
META_LATER_IDLE
|
||||
} MetaLaterType;
|
||||
|
||||
guint meta_later_add (MetaLaterType when,
|
||||
GSourceFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
void meta_later_remove (guint later_id);
|
||||
|
||||
#endif /* META_UTIL_H */
|
||||
|
||||
|
||||
|
@@ -116,8 +116,10 @@ void meta_window_minimize (MetaWindow *window);
|
||||
void meta_window_unminimize (MetaWindow *window);
|
||||
const char *meta_window_get_title (MetaWindow *window);
|
||||
MetaWindow *meta_window_get_transient_for (MetaWindow *window);
|
||||
Window meta_window_get_transient_for_as_xid (MetaWindow *window);
|
||||
void meta_window_delete (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
guint meta_window_get_stable_sequence (MetaWindow *window);
|
||||
guint32 meta_window_get_user_time (MetaWindow *window);
|
||||
int meta_window_get_pid (MetaWindow *window);
|
||||
const char *meta_window_get_client_machine (MetaWindow *window);
|
||||
|
Reference in New Issue
Block a user