mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
...
This commit is contained in:
parent
146361b6f5
commit
b5e506ce9d
@ -28,6 +28,8 @@
|
|||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "keybindings.h"
|
#include "keybindings.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static GSList *all_displays = NULL;
|
static GSList *all_displays = NULL;
|
||||||
static void meta_spew_event (MetaDisplay *display,
|
static void meta_spew_event (MetaDisplay *display,
|
||||||
@ -61,6 +63,19 @@ unsigned_long_hash (gconstpointer v)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_string_hint (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
Atom atom,
|
||||||
|
const char *val)
|
||||||
|
{
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XChangeProperty (display->xdisplay,
|
||||||
|
xwindow, atom,
|
||||||
|
XA_STRING,
|
||||||
|
8, PropModeReplace, (guchar*) val, strlen (val) + 1);
|
||||||
|
return meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_display_open (const char *name)
|
meta_display_open (const char *name)
|
||||||
@ -90,7 +105,18 @@ meta_display_open (const char *name)
|
|||||||
"WM_CHANGE_STATE",
|
"WM_CHANGE_STATE",
|
||||||
"SM_CLIENT_ID",
|
"SM_CLIENT_ID",
|
||||||
"WM_CLIENT_LEADER",
|
"WM_CLIENT_LEADER",
|
||||||
"WM_WINDOW_ROLE"
|
"WM_WINDOW_ROLE",
|
||||||
|
"_NET_CURRENT_DESKTOP",
|
||||||
|
"_NET_SUPPORTING_WM_CHECK",
|
||||||
|
"_NET_WM_SUPPORTED",
|
||||||
|
"_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",
|
||||||
|
"_NET_WM_STATE_MODAL"
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -144,6 +170,17 @@ meta_display_open (const char *name)
|
|||||||
display->atom_sm_client_id = atoms[14];
|
display->atom_sm_client_id = atoms[14];
|
||||||
display->atom_wm_client_leader = atoms[15];
|
display->atom_wm_client_leader = atoms[15];
|
||||||
display->atom_wm_window_role = atoms[16];
|
display->atom_wm_window_role = atoms[16];
|
||||||
|
display->atom_net_current_desktop = atoms[17];
|
||||||
|
display->atom_net_supporting_wm_check = atoms[18];
|
||||||
|
display->atom_net_wm_supported = atoms[19];
|
||||||
|
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];
|
||||||
|
|
||||||
screens = NULL;
|
screens = NULL;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -191,6 +228,11 @@ meta_display_open (const char *name)
|
|||||||
((MetaScreen*)display->screens->data)->xroot,
|
((MetaScreen*)display->screens->data)->xroot,
|
||||||
-100, -100, 1, 1, 0, 0, 0);
|
-100, -100, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
set_string_hint (display,
|
||||||
|
display->leader_window,
|
||||||
|
display->atom_net_supporting_wm_check,
|
||||||
|
"Metacity");
|
||||||
|
|
||||||
/* Now manage all existing windows */
|
/* Now manage all existing windows */
|
||||||
tmp = display->screens;
|
tmp = display->screens;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
@ -560,7 +602,39 @@ event_queue_callback (MetaEventQueue *queue,
|
|||||||
break;
|
break;
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
if (window)
|
if (window)
|
||||||
|
{
|
||||||
meta_window_client_message (window, event);
|
meta_window_client_message (window, event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
screen = meta_display_screen_for_root (display,
|
||||||
|
event->xclient.window);
|
||||||
|
|
||||||
|
if (screen &&
|
||||||
|
event->xclient.message_type ==
|
||||||
|
display->atom_net_current_desktop)
|
||||||
|
{
|
||||||
|
int space;
|
||||||
|
MetaWorkspace *workspace;
|
||||||
|
|
||||||
|
space = event->xclient.data.l[0];
|
||||||
|
|
||||||
|
meta_verbose ("Request to change current workspace to %d\n",
|
||||||
|
space);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MappingNotify:
|
case MappingNotify:
|
||||||
break;
|
break;
|
||||||
|
@ -62,6 +62,17 @@ struct _MetaDisplay
|
|||||||
Atom atom_sm_client_id;
|
Atom atom_sm_client_id;
|
||||||
Atom atom_wm_client_leader;
|
Atom atom_wm_client_leader;
|
||||||
Atom atom_wm_window_role;
|
Atom atom_wm_window_role;
|
||||||
|
Atom atom_net_current_desktop;
|
||||||
|
Atom atom_net_supporting_wm_check;
|
||||||
|
Atom atom_net_wm_supported;
|
||||||
|
Atom atom_net_wm_window_type;
|
||||||
|
Atom atom_net_wm_window_type_desktop;
|
||||||
|
Atom atom_net_wm_window_type_dock;
|
||||||
|
Atom atom_net_wm_window_type_toolbar;
|
||||||
|
Atom atom_net_wm_window_type_menu;
|
||||||
|
Atom atom_net_wm_window_type_dialog;
|
||||||
|
Atom atom_net_wm_window_type_normal;
|
||||||
|
Atom atom_net_wm_state_modal;
|
||||||
|
|
||||||
/* This is the actual window from focus events,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
|
34
src/frame.c
34
src/frame.c
@ -52,15 +52,20 @@ meta_frame_init_info (MetaFrame *frame,
|
|||||||
{
|
{
|
||||||
info->flags =
|
info->flags =
|
||||||
META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_DELETE |
|
META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_DELETE |
|
||||||
META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE |
|
|
||||||
META_FRAME_ALLOWS_RESIZE;
|
META_FRAME_ALLOWS_RESIZE;
|
||||||
|
|
||||||
|
if (frame->window->type == META_WINDOW_NORMAL)
|
||||||
|
info->flags |= (META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE);
|
||||||
|
|
||||||
if (frame->window->has_focus)
|
if (frame->window->has_focus)
|
||||||
info->flags |= META_FRAME_HAS_FOCUS;
|
info->flags |= META_FRAME_HAS_FOCUS;
|
||||||
|
|
||||||
if (frame->window->shaded)
|
if (frame->window->shaded)
|
||||||
info->flags |= META_FRAME_SHADED;
|
info->flags |= META_FRAME_SHADED;
|
||||||
|
|
||||||
|
if (frame->window->on_all_workspaces)
|
||||||
|
info->flags |= META_FRAME_STUCK;
|
||||||
|
|
||||||
info->drawable = None;
|
info->drawable = None;
|
||||||
info->xoffset = 0;
|
info->xoffset = 0;
|
||||||
info->yoffset = 0;
|
info->yoffset = 0;
|
||||||
@ -257,6 +262,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
frame->right_width = 0;
|
frame->right_width = 0;
|
||||||
frame->bg_pixel = 0;
|
frame->bg_pixel = 0;
|
||||||
|
|
||||||
|
frame->mapped = FALSE;
|
||||||
|
|
||||||
attrs.event_mask = EVENT_MASK;
|
attrs.event_mask = EVENT_MASK;
|
||||||
|
|
||||||
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||||
@ -355,19 +362,37 @@ meta_window_destroy_frame (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_frame_sync_to_window (MetaFrame *frame)
|
meta_frame_sync_to_window (MetaFrame *frame,
|
||||||
|
gboolean need_move,
|
||||||
|
gboolean need_resize)
|
||||||
{
|
{
|
||||||
meta_verbose ("Syncing frame geometry %d,%d %dx%d pixel %ld\n",
|
meta_verbose ("Syncing frame geometry %d,%d %dx%d pixel %ld\n",
|
||||||
frame->rect.x, frame->rect.y,
|
frame->rect.x, frame->rect.y,
|
||||||
frame->rect.width, frame->rect.height,
|
frame->rect.width, frame->rect.height,
|
||||||
frame->bg_pixel);
|
frame->bg_pixel);
|
||||||
|
|
||||||
|
/* set bg to none to avoid flicker */
|
||||||
set_background_none (frame);
|
set_background_none (frame);
|
||||||
|
|
||||||
|
if (need_move && need_resize)
|
||||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
frame->rect.x,
|
frame->rect.x,
|
||||||
frame->rect.y,
|
frame->rect.y,
|
||||||
frame->rect.width,
|
frame->rect.width,
|
||||||
frame->rect.height);
|
frame->rect.height);
|
||||||
|
else if (need_move)
|
||||||
|
XMoveWindow (frame->window->display->xdisplay,
|
||||||
|
frame->xwindow,
|
||||||
|
frame->rect.x,
|
||||||
|
frame->rect.y);
|
||||||
|
else if (need_resize)
|
||||||
|
XResizeWindow (frame->window->display->xdisplay,
|
||||||
|
frame->xwindow,
|
||||||
|
frame->rect.width,
|
||||||
|
frame->rect.height);
|
||||||
|
|
||||||
|
/* also syncs bg_pixel */
|
||||||
set_background_color (frame);
|
set_background_color (frame);
|
||||||
meta_frame_queue_draw (frame);
|
meta_frame_queue_draw (frame);
|
||||||
}
|
}
|
||||||
@ -703,6 +728,11 @@ get_menu_items (MetaFrame *frame,
|
|||||||
else
|
else
|
||||||
*ops |= META_MESSAGE_MENU_SHADE;
|
*ops |= META_MESSAGE_MENU_SHADE;
|
||||||
|
|
||||||
|
if (frame->window->on_all_workspaces)
|
||||||
|
*ops |= META_MESSAGE_MENU_UNSTICK;
|
||||||
|
else
|
||||||
|
*ops |= META_MESSAGE_MENU_STICK;
|
||||||
|
|
||||||
*ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
|
*ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
|
||||||
|
|
||||||
if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
|
if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
|
||||||
|
@ -62,6 +62,7 @@ struct _MetaFrame
|
|||||||
guint tooltip_timeout;
|
guint tooltip_timeout;
|
||||||
|
|
||||||
guint theme_acquired : 1;
|
guint theme_acquired : 1;
|
||||||
|
guint mapped : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_window_ensure_frame (MetaWindow *window);
|
void meta_window_ensure_frame (MetaWindow *window);
|
||||||
@ -84,7 +85,9 @@ void meta_frame_adjust_for_gravity (int win_gravity,
|
|||||||
int y,
|
int y,
|
||||||
int *win_root_x,
|
int *win_root_x,
|
||||||
int *win_root_y);
|
int *win_root_y);
|
||||||
void meta_frame_sync_to_window (MetaFrame *frame);
|
void meta_frame_sync_to_window (MetaFrame *frame,
|
||||||
|
gboolean need_move,
|
||||||
|
gboolean need_resize);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
60
src/menu.c
60
src/menu.c
@ -54,7 +54,10 @@ static MenuItem menuitems[] = {
|
|||||||
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
|
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
|
||||||
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||||
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
|
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
|
||||||
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") }
|
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") },
|
||||||
|
{ 0, NULL, NULL }, /* separator */
|
||||||
|
{ META_MESSAGE_MENU_STICK, NULL, N_("Put on _All Workspaces") },
|
||||||
|
{ META_MESSAGE_MENU_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -105,6 +108,32 @@ get_num_desktops (void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
get_active_desktop (void)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
gint format;
|
||||||
|
gulong nitems;
|
||||||
|
gulong bytes_after;
|
||||||
|
gulong *num;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
XGetWindowProperty (gdk_display, gdk_root_window,
|
||||||
|
gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, XA_CARDINAL, &type, &format, &nitems,
|
||||||
|
&bytes_after, (guchar **)&num);
|
||||||
|
|
||||||
|
if (type != XA_CARDINAL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result = *num;
|
||||||
|
|
||||||
|
XFree (num);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static gulong
|
static gulong
|
||||||
get_current_desktop (GdkWindow *window)
|
get_current_desktop (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@ -130,7 +159,7 @@ get_current_desktop (GdkWindow *window)
|
|||||||
if (type != XA_CARDINAL)
|
if (type != XA_CARDINAL)
|
||||||
{
|
{
|
||||||
meta_ui_warning ("_NET_WM_DESKTOP has wrong type %s\n", gdk_atom_name (type));
|
meta_ui_warning ("_NET_WM_DESKTOP has wrong type %s\n", gdk_atom_name (type));
|
||||||
return -1;
|
return 0xFFFFFFFF; /* sticky */
|
||||||
}
|
}
|
||||||
|
|
||||||
result = *num;
|
result = *num;
|
||||||
@ -172,11 +201,17 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (i < G_N_ELEMENTS (menuitems))
|
while (i < G_N_ELEMENTS (menuitems))
|
||||||
{
|
{
|
||||||
if (ops & menuitems[i].op)
|
if (ops & menuitems[i].op || menuitems[i].op == 0)
|
||||||
{
|
{
|
||||||
GtkWidget *mi;
|
GtkWidget *mi;
|
||||||
MenuData *md;
|
MenuData *md;
|
||||||
|
|
||||||
|
if (menuitems[i].op == 0)
|
||||||
|
{
|
||||||
|
mi = gtk_separator_menu_item_new ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (menuitems[i].stock_id)
|
if (menuitems[i].stock_id)
|
||||||
{
|
{
|
||||||
GtkWidget *image;
|
GtkWidget *image;
|
||||||
@ -205,6 +240,7 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
"activate",
|
"activate",
|
||||||
GTK_SIGNAL_FUNC (activate_cb),
|
GTK_SIGNAL_FUNC (activate_cb),
|
||||||
md);
|
md);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
||||||
mi);
|
mi);
|
||||||
@ -222,20 +258,20 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
meta_ui_warning ("Creating %d workspace menu current %d\n",
|
meta_ui_warning ("Creating %d workspace menu current %d\n",
|
||||||
n_workspaces, current_workspace);
|
n_workspaces, current_workspace);
|
||||||
|
|
||||||
if (n_workspaces > 0 && current_workspace >= 0)
|
if (n_workspaces > 0)
|
||||||
{
|
{
|
||||||
GtkWidget *mi;
|
GtkWidget *mi;
|
||||||
|
|
||||||
mi = gtk_separator_menu_item_new ();
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
||||||
gtk_widget_show (mi);
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < n_workspaces)
|
while (i < n_workspaces)
|
||||||
{
|
{
|
||||||
char *label;
|
char *label;
|
||||||
MenuData *md;
|
MenuData *md;
|
||||||
|
|
||||||
|
if (current_workspace == 0xFFFFFFFF)
|
||||||
|
label = g_strdup_printf (_("Only on workspace _%d\n"),
|
||||||
|
i + 1);
|
||||||
|
else
|
||||||
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
||||||
i + 1);
|
i + 1);
|
||||||
|
|
||||||
@ -430,6 +466,14 @@ activate_cb (GtkWidget *menuitem, gpointer data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case META_MESSAGE_MENU_STICK:
|
||||||
|
wmspec_change_desktop (md->window, 0xFFFFFFFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_MESSAGE_MENU_UNSTICK:
|
||||||
|
wmspec_change_desktop (md->window, get_active_desktop ());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
meta_ui_warning (G_STRLOC": Unknown window op\n");
|
meta_ui_warning (G_STRLOC": Unknown window op\n");
|
||||||
break;
|
break;
|
||||||
|
52
src/screen.c
52
src/screen.c
@ -30,6 +30,7 @@
|
|||||||
#include "keybindings.h"
|
#include "keybindings.h"
|
||||||
|
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -40,6 +41,53 @@ static char* get_screen_name (MetaDisplay *display,
|
|||||||
int number);
|
int number);
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_wm_check_hint (MetaScreen *screen)
|
||||||
|
{
|
||||||
|
unsigned long data[1];
|
||||||
|
|
||||||
|
data[0] = screen->display->leader_window;
|
||||||
|
|
||||||
|
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||||
|
screen->display->atom_net_supporting_wm_check,
|
||||||
|
XA_WINDOW,
|
||||||
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_supported_hint (MetaScreen *screen)
|
||||||
|
{
|
||||||
|
#define N_SUPPORTED 17
|
||||||
|
Atom atoms[N_SUPPORTED];
|
||||||
|
|
||||||
|
atoms[0] = screen->display->atom_net_wm_name;
|
||||||
|
atoms[1] = screen->display->atom_net_close_window;
|
||||||
|
atoms[2] = screen->display->atom_net_wm_state;
|
||||||
|
atoms[3] = screen->display->atom_net_wm_state_shaded;
|
||||||
|
atoms[4] = screen->display->atom_net_wm_state_maximized_vert;
|
||||||
|
atoms[5] = screen->display->atom_net_wm_state_maximized_horz;
|
||||||
|
atoms[6] = screen->display->atom_net_wm_desktop;
|
||||||
|
atoms[7] = screen->display->atom_net_number_of_desktops;
|
||||||
|
atoms[8] = screen->display->atom_net_current_desktop;
|
||||||
|
atoms[9] = screen->display->atom_net_wm_window_type;
|
||||||
|
atoms[10] = screen->display->atom_net_wm_window_type_desktop;
|
||||||
|
atoms[11] = screen->display->atom_net_wm_window_type_dock;
|
||||||
|
atoms[12] = screen->display->atom_net_wm_window_type_toolbar;
|
||||||
|
atoms[13] = screen->display->atom_net_wm_window_type_menu;
|
||||||
|
atoms[14] = screen->display->atom_net_wm_window_type_dialog;
|
||||||
|
atoms[15] = screen->display->atom_net_wm_window_type_normal;
|
||||||
|
atoms[16] = screen->display->atom_net_wm_state_modal;
|
||||||
|
|
||||||
|
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||||
|
screen->display->atom_net_wm_supported,
|
||||||
|
XA_ATOM,
|
||||||
|
32, PropModeReplace, (guchar*) atoms, N_SUPPORTED);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
#undef N_SUPPORTED
|
||||||
|
}
|
||||||
|
|
||||||
MetaScreen*
|
MetaScreen*
|
||||||
meta_screen_new (MetaDisplay *display,
|
meta_screen_new (MetaDisplay *display,
|
||||||
int number)
|
int number)
|
||||||
@ -104,6 +152,10 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
|
|
||||||
screen->showing_tooltip = FALSE;
|
screen->showing_tooltip = FALSE;
|
||||||
|
|
||||||
|
set_supported_hint (screen);
|
||||||
|
|
||||||
|
set_wm_check_hint (screen);
|
||||||
|
|
||||||
/* Screens must have at least one workspace at all times,
|
/* Screens must have at least one workspace at all times,
|
||||||
* so create that required workspace.
|
* so create that required workspace.
|
||||||
*/
|
*/
|
||||||
|
@ -51,8 +51,6 @@ struct _MetaScreen
|
|||||||
|
|
||||||
guint showing_tooltip : 1;
|
guint showing_tooltip : 1;
|
||||||
|
|
||||||
/*< private >*/
|
|
||||||
|
|
||||||
/* we only need one since we only draw to a single visual (that of
|
/* we only need one since we only draw to a single visual (that of
|
||||||
* root window)
|
* root window)
|
||||||
*/
|
*/
|
||||||
|
@ -179,10 +179,10 @@ default_release_frame (MetaFrameInfo *info,
|
|||||||
#define SPACER_SPACING 3
|
#define SPACER_SPACING 3
|
||||||
#define SPACER_WIDTH 2
|
#define SPACER_WIDTH 2
|
||||||
#define SPACER_HEIGHT 10
|
#define SPACER_HEIGHT 10
|
||||||
#define BUTTON_WIDTH 12
|
#define BUTTON_WIDTH 14
|
||||||
#define BUTTON_HEIGHT 12
|
#define BUTTON_HEIGHT 14
|
||||||
#define BUTTON_PAD 2
|
#define BUTTON_PAD 1
|
||||||
#define INNER_BUTTON_PAD 1
|
#define INNER_BUTTON_PAD 3
|
||||||
static void
|
static void
|
||||||
calc_geometry (MetaFrameInfo *info,
|
calc_geometry (MetaFrameInfo *info,
|
||||||
DefaultFrameData *d,
|
DefaultFrameData *d,
|
||||||
|
@ -42,7 +42,8 @@ typedef enum
|
|||||||
META_FRAME_ALLOWS_RESIZE = 1 << 4,
|
META_FRAME_ALLOWS_RESIZE = 1 << 4,
|
||||||
META_FRAME_TRANSIENT = 1 << 5,
|
META_FRAME_TRANSIENT = 1 << 5,
|
||||||
META_FRAME_HAS_FOCUS = 1 << 6,
|
META_FRAME_HAS_FOCUS = 1 << 6,
|
||||||
META_FRAME_SHADED = 1 << 7
|
META_FRAME_SHADED = 1 << 7,
|
||||||
|
META_FRAME_STUCK = 1 << 8
|
||||||
} MetaFrameFlags;
|
} MetaFrameFlags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -54,7 +54,10 @@ static MenuItem menuitems[] = {
|
|||||||
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
|
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
|
||||||
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||||
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
|
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
|
||||||
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") }
|
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") },
|
||||||
|
{ 0, NULL, NULL }, /* separator */
|
||||||
|
{ META_MESSAGE_MENU_STICK, NULL, N_("Put on _All Workspaces") },
|
||||||
|
{ META_MESSAGE_MENU_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -105,6 +108,32 @@ get_num_desktops (void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
get_active_desktop (void)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
gint format;
|
||||||
|
gulong nitems;
|
||||||
|
gulong bytes_after;
|
||||||
|
gulong *num;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
XGetWindowProperty (gdk_display, gdk_root_window,
|
||||||
|
gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, XA_CARDINAL, &type, &format, &nitems,
|
||||||
|
&bytes_after, (guchar **)&num);
|
||||||
|
|
||||||
|
if (type != XA_CARDINAL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result = *num;
|
||||||
|
|
||||||
|
XFree (num);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static gulong
|
static gulong
|
||||||
get_current_desktop (GdkWindow *window)
|
get_current_desktop (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@ -130,7 +159,7 @@ get_current_desktop (GdkWindow *window)
|
|||||||
if (type != XA_CARDINAL)
|
if (type != XA_CARDINAL)
|
||||||
{
|
{
|
||||||
meta_ui_warning ("_NET_WM_DESKTOP has wrong type %s\n", gdk_atom_name (type));
|
meta_ui_warning ("_NET_WM_DESKTOP has wrong type %s\n", gdk_atom_name (type));
|
||||||
return -1;
|
return 0xFFFFFFFF; /* sticky */
|
||||||
}
|
}
|
||||||
|
|
||||||
result = *num;
|
result = *num;
|
||||||
@ -172,11 +201,17 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (i < G_N_ELEMENTS (menuitems))
|
while (i < G_N_ELEMENTS (menuitems))
|
||||||
{
|
{
|
||||||
if (ops & menuitems[i].op)
|
if (ops & menuitems[i].op || menuitems[i].op == 0)
|
||||||
{
|
{
|
||||||
GtkWidget *mi;
|
GtkWidget *mi;
|
||||||
MenuData *md;
|
MenuData *md;
|
||||||
|
|
||||||
|
if (menuitems[i].op == 0)
|
||||||
|
{
|
||||||
|
mi = gtk_separator_menu_item_new ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (menuitems[i].stock_id)
|
if (menuitems[i].stock_id)
|
||||||
{
|
{
|
||||||
GtkWidget *image;
|
GtkWidget *image;
|
||||||
@ -205,6 +240,7 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
"activate",
|
"activate",
|
||||||
GTK_SIGNAL_FUNC (activate_cb),
|
GTK_SIGNAL_FUNC (activate_cb),
|
||||||
md);
|
md);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
||||||
mi);
|
mi);
|
||||||
@ -222,20 +258,20 @@ meta_window_menu_show (gulong xwindow,
|
|||||||
meta_ui_warning ("Creating %d workspace menu current %d\n",
|
meta_ui_warning ("Creating %d workspace menu current %d\n",
|
||||||
n_workspaces, current_workspace);
|
n_workspaces, current_workspace);
|
||||||
|
|
||||||
if (n_workspaces > 0 && current_workspace >= 0)
|
if (n_workspaces > 0)
|
||||||
{
|
{
|
||||||
GtkWidget *mi;
|
GtkWidget *mi;
|
||||||
|
|
||||||
mi = gtk_separator_menu_item_new ();
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
||||||
gtk_widget_show (mi);
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < n_workspaces)
|
while (i < n_workspaces)
|
||||||
{
|
{
|
||||||
char *label;
|
char *label;
|
||||||
MenuData *md;
|
MenuData *md;
|
||||||
|
|
||||||
|
if (current_workspace == 0xFFFFFFFF)
|
||||||
|
label = g_strdup_printf (_("Only on workspace _%d\n"),
|
||||||
|
i + 1);
|
||||||
|
else
|
||||||
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
||||||
i + 1);
|
i + 1);
|
||||||
|
|
||||||
@ -430,6 +466,14 @@ activate_cb (GtkWidget *menuitem, gpointer data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case META_MESSAGE_MENU_STICK:
|
||||||
|
wmspec_change_desktop (md->window, 0xFFFFFFFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_MESSAGE_MENU_UNSTICK:
|
||||||
|
wmspec_change_desktop (md->window, get_active_desktop ());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
meta_ui_warning (G_STRLOC": Unknown window op\n");
|
meta_ui_warning (G_STRLOC": Unknown window op\n");
|
||||||
break;
|
break;
|
||||||
|
@ -136,7 +136,9 @@ typedef enum
|
|||||||
META_MESSAGE_MENU_MAXIMIZE = 1 << 3,
|
META_MESSAGE_MENU_MAXIMIZE = 1 << 3,
|
||||||
META_MESSAGE_MENU_UNSHADE = 1 << 4,
|
META_MESSAGE_MENU_UNSHADE = 1 << 4,
|
||||||
META_MESSAGE_MENU_SHADE = 1 << 5,
|
META_MESSAGE_MENU_SHADE = 1 << 5,
|
||||||
META_MESSAGE_MENU_WORKSPACES = 1 << 6
|
META_MESSAGE_MENU_UNSTICK = 1 << 6,
|
||||||
|
META_MESSAGE_MENU_STICK = 1 << 7,
|
||||||
|
META_MESSAGE_MENU_WORKSPACES = 1 << 8
|
||||||
} MetaMessageWindowMenuOps;
|
} MetaMessageWindowMenuOps;
|
||||||
|
|
||||||
struct _MetaMessageShowWindowMenu
|
struct _MetaMessageShowWindowMenu
|
||||||
|
351
src/window.c
351
src/window.c
@ -49,6 +49,8 @@ static int update_wm_class (MetaWindow *window);
|
|||||||
static int update_transient_for (MetaWindow *window);
|
static int update_transient_for (MetaWindow *window);
|
||||||
static void update_sm_hints (MetaWindow *window);
|
static void update_sm_hints (MetaWindow *window);
|
||||||
static int update_role (MetaWindow *window);
|
static int update_role (MetaWindow *window);
|
||||||
|
static int update_net_wm_type (MetaWindow *window);
|
||||||
|
static void recalc_window_type (MetaWindow *window);
|
||||||
static int set_wm_state (MetaWindow *window,
|
static int set_wm_state (MetaWindow *window,
|
||||||
int state);
|
int state);
|
||||||
static void send_configure_notify (MetaWindow *window);
|
static void send_configure_notify (MetaWindow *window);
|
||||||
@ -64,8 +66,6 @@ static void meta_window_show (MetaWindow *window);
|
|||||||
static void meta_window_hide (MetaWindow *window);
|
static void meta_window_hide (MetaWindow *window);
|
||||||
|
|
||||||
static void meta_window_move_resize_internal (MetaWindow *window,
|
static void meta_window_move_resize_internal (MetaWindow *window,
|
||||||
gboolean move,
|
|
||||||
gboolean resize,
|
|
||||||
gboolean is_configure_request,
|
gboolean is_configure_request,
|
||||||
int root_x_nw,
|
int root_x_nw,
|
||||||
int root_y_nw,
|
int root_y_nw,
|
||||||
@ -164,6 +164,7 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->has_focus = FALSE;
|
window->has_focus = FALSE;
|
||||||
|
|
||||||
window->maximized = FALSE;
|
window->maximized = FALSE;
|
||||||
|
window->on_all_workspaces = FALSE;
|
||||||
window->shaded = FALSE;
|
window->shaded = FALSE;
|
||||||
window->initially_iconic = FALSE;
|
window->initially_iconic = FALSE;
|
||||||
window->minimized = FALSE;
|
window->minimized = FALSE;
|
||||||
@ -175,6 +176,8 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->has_minimize_func = TRUE;
|
window->has_minimize_func = TRUE;
|
||||||
window->has_maximize_func = TRUE;
|
window->has_maximize_func = TRUE;
|
||||||
|
|
||||||
|
window->wm_state_modal = FALSE;
|
||||||
|
|
||||||
window->res_class = NULL;
|
window->res_class = NULL;
|
||||||
window->res_name = NULL;
|
window->res_name = NULL;
|
||||||
window->role = NULL;
|
window->role = NULL;
|
||||||
@ -184,6 +187,9 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->xgroup_leader = None;
|
window->xgroup_leader = None;
|
||||||
window->xclient_leader = None;
|
window->xclient_leader = None;
|
||||||
|
|
||||||
|
window->type = META_WINDOW_NORMAL;
|
||||||
|
window->type_atom = None;
|
||||||
|
|
||||||
meta_display_register_x_window (display, &window->xwindow, window);
|
meta_display_register_x_window (display, &window->xwindow, window);
|
||||||
|
|
||||||
update_size_hints (window);
|
update_size_hints (window);
|
||||||
@ -196,6 +202,7 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
update_transient_for (window);
|
update_transient_for (window);
|
||||||
update_sm_hints (window); /* must come after transient_for */
|
update_sm_hints (window); /* must come after transient_for */
|
||||||
update_role (window);
|
update_role (window);
|
||||||
|
update_net_wm_type (window);
|
||||||
|
|
||||||
if (window->initially_iconic)
|
if (window->initially_iconic)
|
||||||
{
|
{
|
||||||
@ -218,7 +225,7 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
* passing TRUE for is_configure_request, ICCCM says
|
* passing TRUE for is_configure_request, ICCCM says
|
||||||
* initial map is handled same as configure request
|
* initial map is handled same as configure request
|
||||||
*/
|
*/
|
||||||
meta_window_move_resize_internal (window, TRUE, TRUE, TRUE,
|
meta_window_move_resize_internal (window, TRUE,
|
||||||
window->size_hints.x,
|
window->size_hints.x,
|
||||||
window->size_hints.y,
|
window->size_hints.y,
|
||||||
window->size_hints.width,
|
window->size_hints.width,
|
||||||
@ -309,6 +316,12 @@ meta_window_calc_showing (MetaWindow *window)
|
|||||||
window->desc,
|
window->desc,
|
||||||
meta_workspace_index (window->screen->active_workspace));
|
meta_workspace_index (window->screen->active_workspace));
|
||||||
|
|
||||||
|
if (window->on_all_workspaces)
|
||||||
|
{
|
||||||
|
on_workspace = TRUE;
|
||||||
|
meta_verbose ("Window %s is on all workspaces\n", window->desc);
|
||||||
|
}
|
||||||
|
|
||||||
if (window->minimized || !on_workspace)
|
if (window->minimized || !on_workspace)
|
||||||
{
|
{
|
||||||
meta_window_hide (window);
|
meta_window_hide (window);
|
||||||
@ -334,15 +347,23 @@ meta_window_show (MetaWindow *window)
|
|||||||
|
|
||||||
/* Shaded means the frame is mapped but the window is not */
|
/* Shaded means the frame is mapped but the window is not */
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame && !window->frame->mapped)
|
||||||
|
{
|
||||||
|
meta_verbose ("Frame actually needs map\n");
|
||||||
|
window->frame->mapped = TRUE;
|
||||||
XMapWindow (window->display->xdisplay, window->frame->xwindow);
|
XMapWindow (window->display->xdisplay, window->frame->xwindow);
|
||||||
|
}
|
||||||
|
|
||||||
if (window->shaded)
|
if (window->shaded)
|
||||||
{
|
{
|
||||||
|
if (window->mapped)
|
||||||
|
{
|
||||||
|
meta_verbose ("%s actually needs unmap\n", window->desc);
|
||||||
window->mapped = FALSE;
|
window->mapped = FALSE;
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
if (!window->iconic)
|
if (!window->iconic)
|
||||||
{
|
{
|
||||||
@ -352,10 +373,14 @@ meta_window_show (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!window->mapped)
|
||||||
|
{
|
||||||
|
meta_verbose ("%s actually needs map\n", window->desc);
|
||||||
window->mapped = TRUE;
|
window->mapped = TRUE;
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
if (window->iconic)
|
if (window->iconic)
|
||||||
{
|
{
|
||||||
@ -370,11 +395,19 @@ meta_window_hide (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
meta_verbose ("Hiding window %s\n", window->desc);
|
meta_verbose ("Hiding window %s\n", window->desc);
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame && window->frame->mapped)
|
||||||
|
{
|
||||||
|
meta_verbose ("Frame actually needs unmap\n");
|
||||||
|
window->frame->mapped = FALSE;
|
||||||
XUnmapWindow (window->display->xdisplay, window->frame->xwindow);
|
XUnmapWindow (window->display->xdisplay, window->frame->xwindow);
|
||||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
}
|
||||||
|
|
||||||
|
if (window->mapped)
|
||||||
|
{
|
||||||
|
meta_verbose ("%s actually needs unmap\n", window->desc);
|
||||||
window->mapped = FALSE;
|
window->mapped = FALSE;
|
||||||
|
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||||
|
}
|
||||||
|
|
||||||
if (!window->iconic)
|
if (!window->iconic)
|
||||||
{
|
{
|
||||||
@ -466,8 +499,6 @@ meta_window_unshade (MetaWindow *window)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_resize_internal (MetaWindow *window,
|
meta_window_move_resize_internal (MetaWindow *window,
|
||||||
gboolean move,
|
|
||||||
gboolean resize,
|
|
||||||
gboolean is_configure_request,
|
gboolean is_configure_request,
|
||||||
int root_x_nw,
|
int root_x_nw,
|
||||||
int root_y_nw,
|
int root_y_nw,
|
||||||
@ -478,30 +509,23 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
gboolean need_configure_notify;
|
gboolean need_configure_notify;
|
||||||
MetaFrameGeometry fgeom;
|
MetaFrameGeometry fgeom;
|
||||||
|
gboolean need_move_client = FALSE;
|
||||||
|
gboolean need_move_frame = FALSE;
|
||||||
|
gboolean need_resize_client = FALSE;
|
||||||
|
gboolean need_resize_frame = FALSE;
|
||||||
|
|
||||||
if (resize)
|
meta_verbose ("Move/resize %s to %d,%d %dx%d\n",
|
||||||
meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h);
|
window->desc, root_x_nw, root_y_nw, w, h);
|
||||||
if (move)
|
|
||||||
meta_verbose ("Moving %s to %d,%d\n", window->desc,
|
|
||||||
root_x_nw, root_y_nw);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* remember that root_x_nw, root_y_nw are bogus if not moving,
|
|
||||||
* and w, h are bogus if not resizing
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (resize)
|
|
||||||
{
|
|
||||||
constrain_size (window, w, h, &w, &h);
|
constrain_size (window, w, h, &w, &h);
|
||||||
meta_verbose ("Constrained resize of %s to %d x %d\n", window->desc, w, h);
|
meta_verbose ("Constrained resize of %s to %d x %d\n", window->desc, w, h);
|
||||||
if (w == window->rect.width &&
|
|
||||||
h == window->rect.height)
|
if (w != window->rect.width ||
|
||||||
resize = FALSE;
|
h != window->rect.height)
|
||||||
|
need_resize_client = TRUE;
|
||||||
|
|
||||||
window->rect.width = w;
|
window->rect.width = w;
|
||||||
window->rect.height = h;
|
window->rect.height = h;
|
||||||
}
|
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
@ -519,7 +543,9 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
else
|
else
|
||||||
new_h = window->rect.height + fgeom.top_height + fgeom.bottom_height;
|
new_h = window->rect.height + fgeom.top_height + fgeom.bottom_height;
|
||||||
|
|
||||||
/* FIXME could check to avoid XResizeWindow on frame */
|
if (new_w != window->frame->rect.width ||
|
||||||
|
new_h != window->frame->rect.height)
|
||||||
|
need_resize_frame = TRUE;
|
||||||
|
|
||||||
window->frame->rect.width = new_w;
|
window->frame->rect.width = new_w;
|
||||||
window->frame->rect.height = new_h;
|
window->frame->rect.height = new_h;
|
||||||
@ -527,11 +553,8 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
meta_verbose ("Calculated frame size %dx%d\n",
|
meta_verbose ("Calculated frame size %dx%d\n",
|
||||||
window->frame->rect.width,
|
window->frame->rect.width,
|
||||||
window->frame->rect.height);
|
window->frame->rect.height);
|
||||||
}
|
|
||||||
|
|
||||||
if (move)
|
if (is_configure_request)
|
||||||
{
|
|
||||||
if (is_configure_request && window->frame)
|
|
||||||
{
|
{
|
||||||
meta_frame_adjust_for_gravity (window->size_hints.win_gravity,
|
meta_frame_adjust_for_gravity (window->size_hints.win_gravity,
|
||||||
window->frame->rect.width,
|
window->frame->rect.width,
|
||||||
@ -545,6 +568,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
meta_verbose ("Compensated position for gravity, new pos %d,%d\n",
|
meta_verbose ("Compensated position for gravity, new pos %d,%d\n",
|
||||||
root_x_nw, root_y_nw);
|
root_x_nw, root_y_nw);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constrain_position (window,
|
constrain_position (window,
|
||||||
window->frame ? &fgeom : NULL,
|
window->frame ? &fgeom : NULL,
|
||||||
@ -561,11 +585,13 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
new_x = root_x_nw - fgeom.left_width;
|
new_x = root_x_nw - fgeom.left_width;
|
||||||
new_y = root_y_nw - fgeom.top_height;
|
new_y = root_y_nw - fgeom.top_height;
|
||||||
|
|
||||||
if (new_x == window->frame->rect.x &&
|
if (new_x != window->frame->rect.x ||
|
||||||
new_y == window->frame->rect.y &&
|
new_y != window->frame->rect.y)
|
||||||
window->rect.x == fgeom.left_width &&
|
need_move_frame = TRUE;
|
||||||
window->rect.y == fgeom.top_height)
|
|
||||||
move = FALSE;
|
if (window->rect.x != fgeom.left_width ||
|
||||||
|
window->rect.y != fgeom.top_height)
|
||||||
|
need_move_client = TRUE;
|
||||||
|
|
||||||
window->frame->rect.x = new_x;
|
window->frame->rect.x = new_x;
|
||||||
window->frame->rect.y = new_y;
|
window->frame->rect.y = new_y;
|
||||||
@ -578,14 +604,13 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (root_x_nw == window->rect.x &&
|
if (root_x_nw != window->rect.x ||
|
||||||
root_y_nw == window->rect.y)
|
root_y_nw != window->rect.y)
|
||||||
move = FALSE;
|
need_move_client = TRUE;
|
||||||
|
|
||||||
window->rect.x = root_x_nw;
|
window->rect.x = root_x_nw;
|
||||||
window->rect.y = root_y_nw;
|
window->rect.y = root_y_nw;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in other frame member variables */
|
/* Fill in other frame member variables */
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
@ -602,8 +627,11 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
* notify if we don't resize. ICCCM 4.1.5
|
* notify if we don't resize. ICCCM 4.1.5
|
||||||
*/
|
*/
|
||||||
need_configure_notify =
|
need_configure_notify =
|
||||||
(!resize) ||
|
(!need_resize_client) ||
|
||||||
(is_configure_request && !(move || resize || window->border_width != 0));
|
(is_configure_request &&
|
||||||
|
!(need_move_client || need_move_frame ||
|
||||||
|
need_resize_client || need_resize_frame ||
|
||||||
|
window->border_width != 0));
|
||||||
|
|
||||||
/* Sync our new size/pos with X as efficiently as possible */
|
/* Sync our new size/pos with X as efficiently as possible */
|
||||||
|
|
||||||
@ -616,17 +644,17 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
mask = 0;
|
mask = 0;
|
||||||
if (is_configure_request && window->border_width != 0)
|
if (is_configure_request && window->border_width != 0)
|
||||||
mask |= CWBorderWidth; /* must force to 0 */
|
mask |= CWBorderWidth; /* must force to 0 */
|
||||||
if (move)
|
if (need_move_client)
|
||||||
mask |= (CWX | CWY);
|
mask |= (CWX | CWY);
|
||||||
if (resize)
|
if (need_resize_client)
|
||||||
mask |= (CWWidth | CWHeight);
|
mask |= (CWWidth | CWHeight);
|
||||||
|
|
||||||
if (mask != 0)
|
if (mask != 0)
|
||||||
{
|
{
|
||||||
meta_verbose ("Syncing new geometry to client, border: %s pos: %s size: %s\n",
|
meta_verbose ("Syncing new geometry to client, border: %s pos: %s size: %s\n",
|
||||||
mask & CWBorderWidth ? "true" : "false",
|
mask & CWBorderWidth ? "true" : "false",
|
||||||
mask & CWX ? "true" : "false",
|
need_move_client ? "true" : "false",
|
||||||
mask & CWWidth ? "true" : "false");
|
need_resize_client ? "true" : "false");
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
XConfigureWindow (window->display->xdisplay,
|
XConfigureWindow (window->display->xdisplay,
|
||||||
@ -638,10 +666,16 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
|
|
||||||
/* Now do the frame */
|
/* Now do the frame */
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
meta_frame_sync_to_window (window->frame);
|
meta_frame_sync_to_window (window->frame, need_move_frame, need_resize_frame);
|
||||||
|
|
||||||
if (need_configure_notify)
|
if (need_configure_notify)
|
||||||
send_configure_notify (window);
|
send_configure_notify (window);
|
||||||
|
|
||||||
|
/* Invariants leaving this function are:
|
||||||
|
* a) window->rect and frame->rect reflect the actual
|
||||||
|
* server-side size/pos of window->xwindow and frame->xwindow
|
||||||
|
* b) all constraints are obeyed by window->rect and frame->rect
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -649,7 +683,11 @@ meta_window_resize (MetaWindow *window,
|
|||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, FALSE, TRUE, FALSE, -1, -1, w, h);
|
int x, y;
|
||||||
|
|
||||||
|
meta_window_get_position (window, &x, &y);
|
||||||
|
|
||||||
|
meta_window_move_resize_internal (window, FALSE, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -657,8 +695,10 @@ meta_window_move (MetaWindow *window,
|
|||||||
int root_x_nw,
|
int root_x_nw,
|
||||||
int root_y_nw)
|
int root_y_nw)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, TRUE, FALSE, FALSE,
|
meta_window_move_resize_internal (window, FALSE,
|
||||||
root_x_nw, root_y_nw, -1, -1);
|
root_x_nw, root_y_nw,
|
||||||
|
window->rect.width,
|
||||||
|
window->rect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -668,7 +708,7 @@ meta_window_move_resize (MetaWindow *window,
|
|||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, TRUE, TRUE, FALSE,
|
meta_window_move_resize_internal (window, FALSE,
|
||||||
root_x_nw, root_y_nw,
|
root_x_nw, root_y_nw,
|
||||||
w, h);
|
w, h);
|
||||||
}
|
}
|
||||||
@ -676,7 +716,7 @@ meta_window_move_resize (MetaWindow *window,
|
|||||||
void
|
void
|
||||||
meta_window_queue_move_resize (MetaWindow *window)
|
meta_window_queue_move_resize (MetaWindow *window)
|
||||||
{
|
{
|
||||||
/* FIXME actually queue */
|
/* FIXME actually queue, don't do it immediately */
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
meta_window_get_position (window, &x, &y);
|
meta_window_get_position (window, &x, &y);
|
||||||
@ -778,6 +818,75 @@ meta_window_change_workspace (MetaWindow *window,
|
|||||||
meta_workspace_remove_window (window->workspaces->next->data, window);
|
meta_workspace_remove_window (window->workspaces->next->data, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_stick (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (window->on_all_workspaces)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We don't change window->workspaces, because we revert
|
||||||
|
* to that original workspace list if on_all_workspaces is
|
||||||
|
* toggled back off.
|
||||||
|
*/
|
||||||
|
window->on_all_workspaces = TRUE;
|
||||||
|
|
||||||
|
meta_window_set_current_workspace_hint (window);
|
||||||
|
|
||||||
|
meta_window_queue_calc_showing (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_unstick (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (!window->on_all_workspaces)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Revert to window->workspaces */
|
||||||
|
|
||||||
|
window->on_all_workspaces = FALSE;
|
||||||
|
|
||||||
|
/* We change ourselves to the active workspace, since otherwise you'd get
|
||||||
|
* a weird window-vaporization effect. Once we have UI for being
|
||||||
|
* on more than one workspace this should probably be add_workspace
|
||||||
|
* not change_workspace.
|
||||||
|
*/
|
||||||
|
if (!meta_workspace_contains_window (window->screen->active_workspace,
|
||||||
|
window))
|
||||||
|
meta_window_change_workspace (window, window->screen->active_workspace);
|
||||||
|
|
||||||
|
meta_window_set_current_workspace_hint (window);
|
||||||
|
|
||||||
|
meta_window_queue_calc_showing (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_window_set_current_workspace_hint (MetaWindow *window)
|
||||||
|
{
|
||||||
|
/* FIXME if on more than one workspace, we claim to be "sticky",
|
||||||
|
* the WM spec doesn't say what to do here.
|
||||||
|
*/
|
||||||
|
unsigned long data[1];
|
||||||
|
|
||||||
|
if (window->workspaces == NULL)
|
||||||
|
return Success; /* this happens when destroying windows */
|
||||||
|
|
||||||
|
if (window->on_all_workspaces ||
|
||||||
|
g_list_length (window->workspaces) > 1)
|
||||||
|
data[0] = 0xFFFFFFFF;
|
||||||
|
else
|
||||||
|
data[0] = meta_workspace_screen_index (window->workspaces->data);
|
||||||
|
|
||||||
|
meta_verbose ("Setting _NET_WM_DESKTOP of %s to %ld\n",
|
||||||
|
window->desc, data[0]);
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
XChangeProperty (window->display->xdisplay, window->xwindow,
|
||||||
|
window->display->atom_net_wm_desktop,
|
||||||
|
XA_CARDINAL,
|
||||||
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
|
return meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_raise (MetaWindow *window)
|
meta_window_raise (MetaWindow *window)
|
||||||
{
|
{
|
||||||
@ -891,9 +1000,19 @@ meta_window_client_message (MetaWindow *window,
|
|||||||
space);
|
space);
|
||||||
|
|
||||||
if (workspace)
|
if (workspace)
|
||||||
|
{
|
||||||
|
if (window->on_all_workspaces)
|
||||||
|
meta_window_unstick (window);
|
||||||
meta_window_change_workspace (window, workspace);
|
meta_window_change_workspace (window, workspace);
|
||||||
|
}
|
||||||
|
else if (space == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
meta_window_stick (window);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
meta_verbose ("No such workspace %d for screen\n", space);
|
meta_verbose ("No such workspace %d for screen\n", space);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1041,6 +1160,11 @@ process_property_notify (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
meta_warning ("Broken client changed client leader window or SM client ID\n");
|
meta_warning ("Broken client changed client leader window or SM client ID\n");
|
||||||
}
|
}
|
||||||
|
else if (event->atom ==
|
||||||
|
window->display->atom_net_wm_window_type)
|
||||||
|
{
|
||||||
|
update_net_wm_type (window);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1109,7 +1233,7 @@ process_configure_request (MetaWindow *window,
|
|||||||
window->size_hints.width = width;
|
window->size_hints.width = width;
|
||||||
window->size_hints.height = height;
|
window->size_hints.height = height;
|
||||||
|
|
||||||
meta_window_move_resize_internal (window, TRUE, TRUE, TRUE,
|
meta_window_move_resize_internal (window, TRUE,
|
||||||
window->size_hints.x,
|
window->size_hints.x,
|
||||||
window->size_hints.y,
|
window->size_hints.y,
|
||||||
window->size_hints.width,
|
window->size_hints.width,
|
||||||
@ -1427,6 +1551,7 @@ update_net_wm_state (MetaWindow *window)
|
|||||||
|
|
||||||
window->shaded = FALSE;
|
window->shaded = FALSE;
|
||||||
window->maximized = FALSE;
|
window->maximized = FALSE;
|
||||||
|
window->wm_state_modal = FALSE;
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
XGetWindowProperty (window->display->xdisplay, window->xwindow,
|
XGetWindowProperty (window->display->xdisplay, window->xwindow,
|
||||||
@ -1437,10 +1562,16 @@ update_net_wm_state (MetaWindow *window)
|
|||||||
|
|
||||||
result = meta_error_trap_pop (window->display);
|
result = meta_error_trap_pop (window->display);
|
||||||
if (result != Success)
|
if (result != Success)
|
||||||
|
{
|
||||||
|
recalc_window_type (window);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (type != XA_ATOM)
|
if (type != XA_ATOM)
|
||||||
|
{
|
||||||
|
recalc_window_type (window);
|
||||||
return -1; /* whatever */
|
return -1; /* whatever */
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < n_atoms)
|
while (i < n_atoms)
|
||||||
@ -1451,12 +1582,16 @@ update_net_wm_state (MetaWindow *window)
|
|||||||
window->maximized = TRUE;
|
window->maximized = TRUE;
|
||||||
else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert)
|
else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert)
|
||||||
window->maximized = TRUE;
|
window->maximized = TRUE;
|
||||||
|
else if (atoms[i] == window->display->atom_net_wm_state_modal)
|
||||||
|
window->wm_state_modal = TRUE;
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree (atoms);
|
XFree (atoms);
|
||||||
|
|
||||||
|
recalc_window_type (window);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1747,9 +1882,121 @@ update_transient_for (MetaWindow *window)
|
|||||||
else
|
else
|
||||||
meta_verbose ("Window %s is not transient\n", window->desc);
|
meta_verbose ("Window %s is not transient\n", window->desc);
|
||||||
|
|
||||||
|
/* may now be a dialog */
|
||||||
|
recalc_window_type (window);
|
||||||
|
|
||||||
return meta_error_trap_pop (window->display);
|
return meta_error_trap_pop (window->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_net_wm_type (MetaWindow *window)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
gint format;
|
||||||
|
gulong n_atoms;
|
||||||
|
gulong bytes_after;
|
||||||
|
Atom *atoms;
|
||||||
|
int result;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
window->type_atom = None;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
XGetWindowProperty (window->display->xdisplay, window->xwindow,
|
||||||
|
window->display->atom_net_wm_window_type,
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, XA_ATOM, &type, &format, &n_atoms,
|
||||||
|
&bytes_after, (guchar **)&atoms);
|
||||||
|
|
||||||
|
result = meta_error_trap_pop (window->display);
|
||||||
|
if (result != Success)
|
||||||
|
{
|
||||||
|
recalc_window_type (window);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != XA_ATOM)
|
||||||
|
{
|
||||||
|
recalc_window_type (window);
|
||||||
|
return -1; /* whatever */
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < n_atoms)
|
||||||
|
{
|
||||||
|
/* We break as soon as we find one we recognize,
|
||||||
|
* supposed to prefer those near the front of the list
|
||||||
|
*/
|
||||||
|
if (atoms[i] == window->display->atom_net_wm_window_type_desktop ||
|
||||||
|
atoms[i] == window->display->atom_net_wm_window_type_dock ||
|
||||||
|
atoms[i] == window->display->atom_net_wm_window_type_toolbar ||
|
||||||
|
atoms[i] == window->display->atom_net_wm_window_type_menu ||
|
||||||
|
atoms[i] == window->display->atom_net_wm_window_type_dialog ||
|
||||||
|
atoms[i] == window->display->atom_net_wm_window_type_normal)
|
||||||
|
{
|
||||||
|
window->type_atom = atoms[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree (atoms);
|
||||||
|
|
||||||
|
if (meta_is_verbose ())
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
str = XGetAtomName (window->display->xdisplay, window->type_atom);
|
||||||
|
if (meta_error_trap_pop (window->display))
|
||||||
|
str = NULL;
|
||||||
|
|
||||||
|
meta_verbose ("Window %s type atom %s\n", window->desc,
|
||||||
|
str ? str : "(none)");
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
XFree (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
recalc_window_type (window);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recalc_window_type (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (window->type_atom != None)
|
||||||
|
{
|
||||||
|
if (window->type_atom == window->display->atom_net_wm_window_type_desktop)
|
||||||
|
window->type = META_WINDOW_DESKTOP;
|
||||||
|
else if (window->type_atom == window->display->atom_net_wm_window_type_dock)
|
||||||
|
window->type = META_WINDOW_DOCK;
|
||||||
|
else if (window->type_atom == window->display->atom_net_wm_window_type_toolbar)
|
||||||
|
window->type = META_WINDOW_TOOLBAR;
|
||||||
|
else if (window->type_atom == window->display->atom_net_wm_window_type_menu)
|
||||||
|
window->type = META_WINDOW_MENU;
|
||||||
|
else if (window->type_atom == window->display->atom_net_wm_window_type_dialog)
|
||||||
|
window->type = META_WINDOW_DIALOG;
|
||||||
|
else if (window->type_atom == window->display->atom_net_wm_window_type_normal)
|
||||||
|
window->type = META_WINDOW_NORMAL;
|
||||||
|
}
|
||||||
|
else if (window->xtransient_for != None)
|
||||||
|
{
|
||||||
|
window->type = META_WINDOW_DIALOG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->type = META_WINDOW_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->type == META_WINDOW_DIALOG &&
|
||||||
|
window->wm_state_modal)
|
||||||
|
window->type = META_WINDOW_MODAL_DIALOG;
|
||||||
|
|
||||||
|
meta_verbose ("Calculated type %d for %s\n", window->type, window->desc);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constrain_size (MetaWindow *window,
|
constrain_size (MetaWindow *window,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
|
27
src/window.h
27
src/window.h
@ -26,6 +26,17 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_WINDOW_NORMAL,
|
||||||
|
META_WINDOW_DESKTOP,
|
||||||
|
META_WINDOW_DOCK,
|
||||||
|
META_WINDOW_DIALOG,
|
||||||
|
META_WINDOW_MODAL_DIALOG,
|
||||||
|
META_WINDOW_TOOLBAR,
|
||||||
|
META_WINDOW_MENU
|
||||||
|
} MetaWindowType;
|
||||||
|
|
||||||
struct _MetaWindow
|
struct _MetaWindow
|
||||||
{
|
{
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
@ -39,6 +50,9 @@ struct _MetaWindow
|
|||||||
char *desc; /* used in debug spew */
|
char *desc; /* used in debug spew */
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
|
MetaWindowType type;
|
||||||
|
Atom type_atom;
|
||||||
|
|
||||||
/* NOTE these four are not in UTF-8, we just treat them as random
|
/* NOTE these four are not in UTF-8, we just treat them as random
|
||||||
* binary data
|
* binary data
|
||||||
*/
|
*/
|
||||||
@ -57,6 +71,12 @@ struct _MetaWindow
|
|||||||
/* Whether we're shaded */
|
/* Whether we're shaded */
|
||||||
guint shaded : 1;
|
guint shaded : 1;
|
||||||
|
|
||||||
|
/* Whether we're sticky in the multi-workspace sense
|
||||||
|
* (vs. the not-scroll-with-viewport sense, we don't
|
||||||
|
* have no stupid viewports)
|
||||||
|
*/
|
||||||
|
guint on_all_workspaces : 1;
|
||||||
|
|
||||||
/* Mapped is what we think the mapped state should be;
|
/* Mapped is what we think the mapped state should be;
|
||||||
* so if we get UnmapNotify and mapped == TRUE then
|
* so if we get UnmapNotify and mapped == TRUE then
|
||||||
* it's a withdraw, if mapped == FALSE the UnmapNotify
|
* it's a withdraw, if mapped == FALSE the UnmapNotify
|
||||||
@ -88,6 +108,9 @@ struct _MetaWindow
|
|||||||
guint has_minimize_func : 1;
|
guint has_minimize_func : 1;
|
||||||
guint has_maximize_func : 1;
|
guint has_maximize_func : 1;
|
||||||
|
|
||||||
|
/* Weird "_NET_WM_STATE_MODAL" flag */
|
||||||
|
guint wm_state_modal : 1;
|
||||||
|
|
||||||
/* this flag tracks receipt of focus_in focus_out and
|
/* this flag tracks receipt of focus_in focus_out and
|
||||||
* determines whether we draw the focus
|
* determines whether we draw the focus
|
||||||
*/
|
*/
|
||||||
@ -126,6 +149,8 @@ void meta_window_shade (MetaWindow *window);
|
|||||||
void meta_window_unshade (MetaWindow *window);
|
void meta_window_unshade (MetaWindow *window);
|
||||||
void meta_window_change_workspace (MetaWindow *window,
|
void meta_window_change_workspace (MetaWindow *window,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
|
void meta_window_stick (MetaWindow *window);
|
||||||
|
void meta_window_unstick (MetaWindow *window);
|
||||||
|
|
||||||
/* args to move are window pos, not frame pos */
|
/* args to move are window pos, not frame pos */
|
||||||
void meta_window_move (MetaWindow *window,
|
void meta_window_move (MetaWindow *window,
|
||||||
@ -167,4 +192,6 @@ gboolean meta_window_property_notify (MetaWindow *window,
|
|||||||
XEvent *event);
|
XEvent *event);
|
||||||
gboolean meta_window_client_message (MetaWindow *window,
|
gboolean meta_window_client_message (MetaWindow *window,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
|
int meta_window_set_current_workspace_hint (MetaWindow *window);
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
||||||
|
|
||||||
static int set_current_workspace_hint (MetaWindow *window);
|
|
||||||
static int set_number_of_spaces_hint (MetaScreen *screen);
|
static int set_number_of_spaces_hint (MetaScreen *screen);
|
||||||
|
static int set_active_space_hint (MetaScreen *screen);
|
||||||
|
|
||||||
MetaWorkspace*
|
MetaWorkspace*
|
||||||
meta_workspace_new (MetaScreen *screen)
|
meta_workspace_new (MetaScreen *screen)
|
||||||
@ -82,12 +82,12 @@ void
|
|||||||
meta_workspace_add_window (MetaWorkspace *workspace,
|
meta_workspace_add_window (MetaWorkspace *workspace,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
g_return_if_fail (g_list_find (workspace->windows, window) == NULL);
|
g_return_if_fail (!meta_workspace_contains_window (workspace, window));
|
||||||
|
|
||||||
workspace->windows = g_list_prepend (workspace->windows, window);
|
workspace->windows = g_list_prepend (workspace->windows, window);
|
||||||
window->workspaces = g_list_prepend (window->workspaces, workspace);
|
window->workspaces = g_list_prepend (window->workspaces, workspace);
|
||||||
|
|
||||||
set_current_workspace_hint (window);
|
meta_window_set_current_workspace_hint (window);
|
||||||
|
|
||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
}
|
}
|
||||||
@ -96,16 +96,23 @@ void
|
|||||||
meta_workspace_remove_window (MetaWorkspace *workspace,
|
meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
g_return_if_fail (g_list_find (workspace->windows, window) != NULL);
|
g_return_if_fail (meta_workspace_contains_window (workspace, window));
|
||||||
|
|
||||||
workspace->windows = g_list_remove (workspace->windows, window);
|
workspace->windows = g_list_remove (workspace->windows, window);
|
||||||
window->workspaces = g_list_remove (window->workspaces, workspace);
|
window->workspaces = g_list_remove (window->workspaces, workspace);
|
||||||
|
|
||||||
set_current_workspace_hint (window);
|
meta_window_set_current_workspace_hint (window);
|
||||||
|
|
||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_workspace_contains_window (MetaWorkspace *workspace,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
return g_list_find (workspace->windows, window) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||||
{
|
{
|
||||||
@ -135,6 +142,8 @@ meta_workspace_activate (MetaWorkspace *workspace)
|
|||||||
|
|
||||||
workspace->screen->active_workspace = workspace;
|
workspace->screen->active_workspace = workspace;
|
||||||
|
|
||||||
|
set_active_space_hint (workspace->screen);
|
||||||
|
|
||||||
meta_workspace_queue_calc_showing (old);
|
meta_workspace_queue_calc_showing (old);
|
||||||
meta_workspace_queue_calc_showing (workspace);
|
meta_workspace_queue_calc_showing (workspace);
|
||||||
}
|
}
|
||||||
@ -184,32 +193,6 @@ meta_workspace_screen_index (MetaWorkspace *workspace)
|
|||||||
meta_bug ("Workspace does not exist to index!\n");
|
meta_bug ("Workspace does not exist to index!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_current_workspace_hint (MetaWindow *window)
|
|
||||||
{
|
|
||||||
/* if on more than one workspace, we claim to be "sticky" */
|
|
||||||
unsigned long data[1];
|
|
||||||
|
|
||||||
if (window->workspaces == NULL)
|
|
||||||
return Success; /* this happens when destroying windows */
|
|
||||||
|
|
||||||
if (g_list_length (window->workspaces) > 1)
|
|
||||||
data[0] = 0xFFFFFFFF;
|
|
||||||
else
|
|
||||||
data[0] = meta_workspace_screen_index (window->workspaces->data);
|
|
||||||
|
|
||||||
meta_verbose ("Setting _NET_WM_DESKTOP of %s to %ld\n",
|
|
||||||
window->desc, data[0]);
|
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
|
||||||
XChangeProperty (window->display->xdisplay, window->xwindow,
|
|
||||||
window->display->atom_net_wm_desktop,
|
|
||||||
XA_CARDINAL,
|
|
||||||
32, PropModeReplace, (guchar*) data, 1);
|
|
||||||
return meta_error_trap_pop (window->display);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_number_of_spaces_hint (MetaScreen *screen)
|
set_number_of_spaces_hint (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
@ -226,3 +209,20 @@ set_number_of_spaces_hint (MetaScreen *screen)
|
|||||||
32, PropModeReplace, (guchar*) data, 1);
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
return meta_error_trap_pop (screen->display);
|
return meta_error_trap_pop (screen->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_active_space_hint (MetaScreen *screen)
|
||||||
|
{
|
||||||
|
unsigned long data[1];
|
||||||
|
|
||||||
|
data[0] = meta_workspace_screen_index (screen->active_workspace);
|
||||||
|
|
||||||
|
meta_verbose ("Setting _NET_CURRENT_DESKTOP to %ld\n", data[0]);
|
||||||
|
|
||||||
|
meta_error_trap_push (screen->display);
|
||||||
|
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||||
|
screen->display->atom_net_current_desktop,
|
||||||
|
XA_CARDINAL,
|
||||||
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
|
return meta_error_trap_pop (screen->display);
|
||||||
|
}
|
||||||
|
@ -39,7 +39,8 @@ void meta_workspace_add_window (MetaWorkspace *workspace,
|
|||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
void meta_workspace_remove_window (MetaWorkspace *workspace,
|
void meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
gboolean meta_workspace_contains_window (MetaWorkspace *workspace,
|
||||||
|
MetaWindow *window);
|
||||||
void meta_workspace_activate (MetaWorkspace *workspace);
|
void meta_workspace_activate (MetaWorkspace *workspace);
|
||||||
int meta_workspace_index (MetaWorkspace *workspace);
|
int meta_workspace_index (MetaWorkspace *workspace);
|
||||||
int meta_workspace_screen_index (MetaWorkspace *workspace);
|
int meta_workspace_screen_index (MetaWorkspace *workspace);
|
||||||
|
Loading…
Reference in New Issue
Block a user