mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
...
This commit is contained in:
parent
ad6efc61b5
commit
0f5fdeb1b1
@ -49,6 +49,8 @@ metacity_SOURCES= \
|
||||
eventqueue.h \
|
||||
frame.c \
|
||||
frame.h \
|
||||
keybindings.c \
|
||||
keybindings.h \
|
||||
main.c \
|
||||
main.h \
|
||||
screen.c \
|
||||
@ -61,6 +63,8 @@ metacity_SOURCES= \
|
||||
util.h \
|
||||
window.c \
|
||||
window.h \
|
||||
workspace.c \
|
||||
workspace.h \
|
||||
$(copied_sources)
|
||||
|
||||
bin_PROGRAMS=metacity
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "window.h"
|
||||
#include "frame.h"
|
||||
#include "errors.h"
|
||||
#include "keybindings.h"
|
||||
#include "workspace.h"
|
||||
|
||||
static GSList *all_displays = NULL;
|
||||
static void meta_spew_event (MetaDisplay *display,
|
||||
@ -75,7 +77,8 @@ meta_display_open (const char *name)
|
||||
"_NET_WM_NAME",
|
||||
"WM_PROTOCOLS",
|
||||
"WM_TAKE_FOCUS",
|
||||
"WM_DELETE_WINDOW"
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
@ -103,8 +106,12 @@ meta_display_open (const char *name)
|
||||
display->xdisplay = xdisplay;
|
||||
display->error_traps = NULL;
|
||||
|
||||
display->workspaces = NULL;
|
||||
|
||||
/* we have to go ahead and do this so error handlers work */
|
||||
all_displays = g_slist_prepend (all_displays, display);
|
||||
|
||||
meta_display_init_keys (display);
|
||||
|
||||
screens = NULL;
|
||||
i = 0;
|
||||
@ -147,6 +154,7 @@ meta_display_open (const char *name)
|
||||
display->atom_wm_protocols = atoms[1];
|
||||
display->atom_wm_take_focus = atoms[2];
|
||||
display->atom_wm_delete_window = atoms[3];
|
||||
display->atom_wm_state = atoms[4];
|
||||
|
||||
/* Now manage all existing windows */
|
||||
tmp = display->screens;
|
||||
@ -287,10 +295,14 @@ meta_display_ungrab (MetaDisplay *display)
|
||||
{
|
||||
if (display->server_grab_count == 0)
|
||||
meta_bug ("Ungrabbed non-grabbed server\n");
|
||||
|
||||
|
||||
display->server_grab_count -= 1;
|
||||
if (display->server_grab_count == 0)
|
||||
{
|
||||
/* FIXME we want to purge all pending "queued" stuff
|
||||
* at this point, such as window hide/show
|
||||
*/
|
||||
|
||||
XUngrabServer (display->xdisplay);
|
||||
}
|
||||
XSync (display->xdisplay, False);
|
||||
@ -355,6 +367,7 @@ event_queue_callback (MetaEventQueue *queue,
|
||||
switch (event->type)
|
||||
{
|
||||
case KeyPress:
|
||||
meta_display_process_key_press (display, event);
|
||||
break;
|
||||
case KeyRelease:
|
||||
break;
|
||||
@ -429,15 +442,6 @@ event_queue_callback (MetaEventQueue *queue,
|
||||
case ReparentNotify:
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
if (window && event->xconfigure.override_redirect)
|
||||
{
|
||||
/* Unmanage it, override_redirect was toggled on?
|
||||
* Can this happen?
|
||||
*/
|
||||
meta_verbose ("Window %s toggled on override redirect\n",
|
||||
window->desc);
|
||||
meta_window_free (window);
|
||||
}
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
/* This comment and code is found in both twm and fvwm */
|
||||
@ -755,3 +759,45 @@ meta_display_unregister_x_window (MetaDisplay *display,
|
||||
|
||||
g_hash_table_remove (display->window_ids, &xwindow);
|
||||
}
|
||||
|
||||
MetaWorkspace*
|
||||
meta_display_get_workspace_by_index (MetaDisplay *display,
|
||||
int index)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
tmp = g_list_nth (display->workspaces, index);
|
||||
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return tmp->data;
|
||||
}
|
||||
|
||||
MetaWorkspace*
|
||||
meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
int index)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
tmp = display->workspaces;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
|
||||
if (w->screen == screen)
|
||||
{
|
||||
if (i == index)
|
||||
return w;
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -27,11 +27,12 @@
|
||||
#include <pango/pangox.h>
|
||||
#include "eventqueue.h"
|
||||
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaScreen MetaScreen;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaScreen MetaScreen;
|
||||
typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
typedef struct _MetaWorkspace MetaWorkspace;
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
@ -42,11 +43,14 @@ struct _MetaDisplay
|
||||
Atom atom_wm_protocols;
|
||||
Atom atom_wm_take_focus;
|
||||
Atom atom_wm_delete_window;
|
||||
|
||||
Atom atom_wm_state;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
*/
|
||||
MetaWindow *focus_window;
|
||||
|
||||
GList *workspaces;
|
||||
|
||||
/*< private-ish >*/
|
||||
MetaEventQueue *events;
|
||||
@ -82,4 +86,11 @@ void meta_display_unregister_x_window (MetaDisplay *display,
|
||||
MetaDisplay* meta_display_for_x_display (Display *xdisplay);
|
||||
GSList* meta_displays_list (void);
|
||||
|
||||
MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *display,
|
||||
int index);
|
||||
MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
int index);
|
||||
|
||||
|
||||
#endif
|
||||
|
402
src/frame.c
402
src/frame.c
@ -24,6 +24,19 @@
|
||||
#include "uislave.h"
|
||||
#include "colors.h"
|
||||
|
||||
struct _MetaFrameActionGrab
|
||||
{
|
||||
MetaFrameAction action;
|
||||
/* initial mouse position for drags */
|
||||
int start_root_x, start_root_y;
|
||||
/* initial window size or initial window position for drags */
|
||||
int start_window_x, start_window_y;
|
||||
/* button doing the dragging */
|
||||
int start_button;
|
||||
};
|
||||
|
||||
static void clear_tip (MetaFrame *frame);
|
||||
|
||||
static void
|
||||
meta_frame_init_info (MetaFrame *frame,
|
||||
MetaFrameInfo *info)
|
||||
@ -47,6 +60,11 @@ meta_frame_init_info (MetaFrame *frame,
|
||||
info->width = frame->rect.width;
|
||||
info->height = frame->rect.height;
|
||||
info->colors = &(frame->window->screen->colors);
|
||||
info->current_control = frame->current_control;
|
||||
if (frame->grab)
|
||||
info->current_control_state = META_STATE_ACTIVE;
|
||||
else
|
||||
info->current_control_state = META_STATE_PRELIGHT;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -201,11 +219,13 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
frame = g_new (MetaFrame, 1);
|
||||
|
||||
/* Fill in values that calc_geometry will use */
|
||||
frame->window = window;
|
||||
frame->xwindow = None;
|
||||
frame->theme_acquired = FALSE;
|
||||
|
||||
frame->grab = NULL;
|
||||
frame->current_control = META_FRAME_CONTROL_NONE;
|
||||
frame->tooltip_timeout = 0;
|
||||
|
||||
/* This fills in frame->rect as well. */
|
||||
meta_frame_calc_geometry (frame,
|
||||
window->rect.width,
|
||||
@ -226,7 +246,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
attrs.background_pixel = frame->bg_pixel;
|
||||
attrs.event_mask =
|
||||
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
/* We need OwnerGrabButtonMask because during a button
|
||||
* press we may need to transfer control to the UI slave.
|
||||
*/
|
||||
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask |
|
||||
PointerMotionMask | PointerMotionHintMask |
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
@ -245,8 +268,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
meta_verbose ("Frame is 0x%lx\n", frame->xwindow);
|
||||
|
||||
frame->action = META_FRAME_ACTION_NONE;
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
/* Reparent the client window; it may be destroyed,
|
||||
@ -277,10 +298,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
window->frame = frame;
|
||||
|
||||
/* Put our state back where it should be */
|
||||
if (window->iconic)
|
||||
meta_window_hide (window);
|
||||
else
|
||||
meta_window_show (window);
|
||||
meta_window_queue_calc_showing (window);
|
||||
|
||||
/* Ungrab server */
|
||||
meta_display_ungrab (window->display);
|
||||
@ -297,6 +315,9 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
|
||||
frame = window->frame;
|
||||
|
||||
if (frame->tooltip_timeout)
|
||||
clear_tip (frame);
|
||||
|
||||
if (frame->theme_data)
|
||||
{
|
||||
meta_frame_init_info (frame, &info);
|
||||
@ -330,23 +351,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
g_free (frame);
|
||||
|
||||
/* Put our state back where it should be */
|
||||
if (window->iconic)
|
||||
meta_window_hide (window);
|
||||
else
|
||||
meta_window_show (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_move (MetaFrame *frame,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
frame->rect.x = root_x;
|
||||
frame->rect.y = root_y;
|
||||
|
||||
XMoveWindow (frame->window->display->xdisplay,
|
||||
frame->xwindow,
|
||||
root_x, root_y);
|
||||
meta_window_queue_calc_showing (window);
|
||||
}
|
||||
|
||||
/* Just a chunk of process_configure_event in window.c,
|
||||
@ -414,6 +419,8 @@ meta_frame_recalc_now (MetaFrame *frame)
|
||||
frame->window->desc, frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height,
|
||||
frame->child_x, frame->child_y);
|
||||
|
||||
meta_frame_queue_draw (frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -513,48 +520,223 @@ frame_query_root_pointer (MetaFrame *frame,
|
||||
*y = root_y_return;
|
||||
}
|
||||
|
||||
static void
|
||||
show_tip_now (MetaFrame *frame)
|
||||
{
|
||||
const char *tiptext;
|
||||
|
||||
tiptext = NULL;
|
||||
switch (frame->current_control)
|
||||
{
|
||||
case META_FRAME_CONTROL_TITLE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
tiptext = _("Close Window");
|
||||
break;
|
||||
case META_FRAME_CONTROL_MENU:
|
||||
tiptext = _("Menu");
|
||||
break;
|
||||
case META_FRAME_CONTROL_ICONIFY:
|
||||
tiptext = _("Minimize Window");
|
||||
break;
|
||||
case META_FRAME_CONTROL_MAXIMIZE:
|
||||
tiptext = _("Maximize Window");
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_S:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SW:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_N:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_NE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_NW:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_W:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_E:
|
||||
break;
|
||||
case META_FRAME_CONTROL_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tiptext)
|
||||
{
|
||||
int x, y, width, height;
|
||||
MetaFrameInfo info;
|
||||
|
||||
meta_frame_init_info (frame, &info);
|
||||
frame->window->screen->engine->get_control_rect (&info,
|
||||
frame->current_control,
|
||||
&x, &y, &width, &height,
|
||||
frame->theme_data);
|
||||
|
||||
/* Display tip a couple pixels below control */
|
||||
meta_screen_show_tip (frame->window->screen,
|
||||
frame->rect.x + x,
|
||||
frame->rect.y + y + height + 2,
|
||||
tiptext);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tip_timeout_func (gpointer data)
|
||||
{
|
||||
MetaFrame *frame;
|
||||
|
||||
frame = data;
|
||||
|
||||
show_tip_now (frame);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define TIP_DELAY 250
|
||||
static void
|
||||
queue_tip (MetaFrame *frame)
|
||||
{
|
||||
if (frame->tooltip_timeout)
|
||||
g_source_remove (frame->tooltip_timeout);
|
||||
|
||||
frame->tooltip_timeout = g_timeout_add (250,
|
||||
tip_timeout_func,
|
||||
frame);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_tip (MetaFrame *frame)
|
||||
{
|
||||
if (frame->tooltip_timeout)
|
||||
{
|
||||
g_source_remove (frame->tooltip_timeout);
|
||||
frame->tooltip_timeout = 0;
|
||||
}
|
||||
meta_screen_hide_tip (frame->window->screen);
|
||||
}
|
||||
|
||||
static MetaFrameControl
|
||||
frame_get_control (MetaFrame *frame,
|
||||
int x, int y)
|
||||
{
|
||||
MetaFrameInfo info;
|
||||
meta_frame_init_info (frame, &info);
|
||||
|
||||
if (x < 0 || y < 0 ||
|
||||
x > frame->rect.width || y > frame->rect.height)
|
||||
return META_FRAME_CONTROL_NONE;
|
||||
|
||||
meta_frame_init_info (frame, &info);
|
||||
|
||||
return frame->window->screen->engine->get_control (&info,
|
||||
x, y,
|
||||
frame->theme_data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_move (MetaFrame *frame)
|
||||
update_move (MetaFrame *frame,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
int x, y;
|
||||
int dx, dy;
|
||||
|
||||
frame_query_root_pointer (frame, &x, &y);
|
||||
dx = x - frame->grab->start_root_x;
|
||||
dy = y - frame->grab->start_root_y;
|
||||
|
||||
dx = x - frame->start_root_x;
|
||||
dy = y - frame->start_root_y;
|
||||
|
||||
meta_frame_move (frame,
|
||||
frame->start_window_x + dx,
|
||||
frame->start_window_y + dy);
|
||||
meta_window_move (frame->window,
|
||||
frame->grab->start_window_x + dx,
|
||||
frame->grab->start_window_y + dy);
|
||||
}
|
||||
|
||||
static void
|
||||
update_resize_se (MetaFrame *frame)
|
||||
update_resize_se (MetaFrame *frame,
|
||||
int x, int y)
|
||||
{
|
||||
int x, y;
|
||||
int dx, dy;
|
||||
|
||||
frame_query_root_pointer (frame, &x, &y);
|
||||
|
||||
dx = x - frame->start_root_x;
|
||||
dy = y - frame->start_root_y;
|
||||
dx = x - frame->grab->start_root_x;
|
||||
dy = y - frame->grab->start_root_y;
|
||||
|
||||
meta_window_resize (frame->window,
|
||||
frame->start_window_x + dx,
|
||||
frame->start_window_y + dy);
|
||||
frame->grab->start_window_x + dx,
|
||||
frame->grab->start_window_y + dy);
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_control (MetaFrame *frame,
|
||||
int x_root, int y_root)
|
||||
{
|
||||
MetaFrameControl old;
|
||||
|
||||
if (frame->grab)
|
||||
return;
|
||||
|
||||
old = frame->current_control;
|
||||
|
||||
frame->current_control = frame_get_control (frame,
|
||||
x_root - frame->rect.x,
|
||||
y_root - frame->rect.y);
|
||||
|
||||
if (old != frame->current_control)
|
||||
{
|
||||
meta_frame_queue_draw (frame);
|
||||
|
||||
if (frame->current_control == META_FRAME_CONTROL_NONE)
|
||||
clear_tip (frame);
|
||||
else
|
||||
queue_tip (frame);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grab_action (MetaFrame *frame,
|
||||
MetaFrameAction action,
|
||||
Time time)
|
||||
{
|
||||
meta_verbose ("Grabbing action %d\n", action);
|
||||
|
||||
frame->grab = g_new0 (MetaFrameActionGrab, 1);
|
||||
|
||||
if (XGrabPointer (frame->window->display->xdisplay,
|
||||
frame->xwindow,
|
||||
False,
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | PointerMotionHintMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
None,
|
||||
None,
|
||||
time) != GrabSuccess)
|
||||
meta_warning ("Grab for frame action failed\n");
|
||||
|
||||
frame->grab->action = action;
|
||||
|
||||
/* display ACTIVE state */
|
||||
meta_frame_queue_draw (frame);
|
||||
|
||||
clear_tip (frame);
|
||||
}
|
||||
|
||||
static void
|
||||
ungrab_action (MetaFrame *frame,
|
||||
Time time)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
meta_verbose ("Ungrabbing action %d\n", frame->grab->action);
|
||||
|
||||
XUngrabPointer (frame->window->display->xdisplay,
|
||||
time);
|
||||
|
||||
g_free (frame->grab);
|
||||
frame->grab = NULL;
|
||||
|
||||
frame_query_root_pointer (frame, &x, &y);
|
||||
update_current_control (frame, x, y);
|
||||
|
||||
/* undisplay ACTIVE state */
|
||||
meta_frame_queue_draw (frame);
|
||||
|
||||
queue_tip (frame);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -568,12 +750,18 @@ meta_frame_event (MetaFrame *frame,
|
||||
case KeyRelease:
|
||||
break;
|
||||
case ButtonPress:
|
||||
if (frame->action == META_FRAME_ACTION_NONE)
|
||||
/* you can use button 2 to move a window without raising it */
|
||||
if (event->xbutton.button == 1)
|
||||
meta_window_raise (frame->window);
|
||||
|
||||
update_current_control (frame,
|
||||
event->xbutton.x_root,
|
||||
event->xbutton.y_root);
|
||||
|
||||
if (frame->grab == NULL)
|
||||
{
|
||||
MetaFrameControl control;
|
||||
control = frame_get_control (frame,
|
||||
event->xbutton.x,
|
||||
event->xbutton.y);
|
||||
control = frame->current_control;
|
||||
|
||||
if (((control == META_FRAME_CONTROL_TITLE ||
|
||||
control == META_FRAME_CONTROL_NONE) &&
|
||||
@ -582,12 +770,16 @@ meta_frame_event (MetaFrame *frame,
|
||||
{
|
||||
meta_verbose ("Begin move on %s\n",
|
||||
frame->window->desc);
|
||||
frame->action = META_FRAME_ACTION_MOVING;
|
||||
frame->start_root_x = event->xbutton.x_root;
|
||||
frame->start_root_y = event->xbutton.y_root;
|
||||
frame->start_window_x = frame->rect.x;
|
||||
frame->start_window_y = frame->rect.y;
|
||||
frame->start_button = event->xbutton.button;
|
||||
grab_action (frame, META_FRAME_ACTION_MOVING,
|
||||
event->xbutton.time);
|
||||
frame->grab->start_root_x = event->xbutton.x_root;
|
||||
frame->grab->start_root_y = event->xbutton.y_root;
|
||||
/* pos of client in root coords */
|
||||
frame->grab->start_window_x =
|
||||
frame->rect.x + frame->window->rect.x;
|
||||
frame->grab->start_window_y =
|
||||
frame->rect.y + frame->window->rect.y;
|
||||
frame->grab->start_button = event->xbutton.button;
|
||||
}
|
||||
else if (control == META_FRAME_CONTROL_DELETE &&
|
||||
event->xbutton.button == 1)
|
||||
@ -595,63 +787,92 @@ meta_frame_event (MetaFrame *frame,
|
||||
/* FIXME delete event */
|
||||
meta_verbose ("Close control clicked on %s\n",
|
||||
frame->window->desc);
|
||||
meta_window_delete (frame->window, event->xbutton.time);
|
||||
grab_action (frame, META_FRAME_ACTION_DELETING,
|
||||
event->xbutton.time);
|
||||
frame->grab->start_button = event->xbutton.button;
|
||||
}
|
||||
else if (control == META_FRAME_CONTROL_RESIZE_SE &&
|
||||
event->xbutton.button == 1)
|
||||
{
|
||||
meta_verbose ("Resize control clicked on %s\n",
|
||||
frame->window->desc);
|
||||
frame->action = META_FRAME_ACTION_RESIZING_SE;
|
||||
frame->start_root_x = event->xbutton.x_root;
|
||||
frame->start_root_y = event->xbutton.y_root;
|
||||
frame->start_window_x = frame->window->rect.width;
|
||||
frame->start_window_y = frame->window->rect.height;
|
||||
frame->start_button = event->xbutton.button;
|
||||
grab_action (frame, META_FRAME_ACTION_RESIZING_SE,
|
||||
event->xbutton.time);
|
||||
frame->grab->start_root_x = event->xbutton.x_root;
|
||||
frame->grab->start_root_y = event->xbutton.y_root;
|
||||
frame->grab->start_window_x = frame->window->rect.width;
|
||||
frame->grab->start_window_y = frame->window->rect.height;
|
||||
frame->grab->start_button = event->xbutton.button;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (event->xbutton.button == frame->start_button)
|
||||
if (frame->grab)
|
||||
meta_debug_spew ("Here! grab %p action %d buttons %d %d\n",
|
||||
frame->grab, frame->grab->action, frame->grab->start_button, event->xbutton.button);
|
||||
if (frame->grab &&
|
||||
event->xbutton.button == frame->grab->start_button)
|
||||
{
|
||||
switch (frame->action)
|
||||
switch (frame->grab->action)
|
||||
{
|
||||
case META_FRAME_ACTION_MOVING:
|
||||
update_move (frame);
|
||||
update_move (frame, event->xbutton.x_root, event->xbutton.y_root);
|
||||
ungrab_action (frame, event->xbutton.time);
|
||||
update_current_control (frame,
|
||||
event->xbutton.x_root, event->xbutton.y_root);
|
||||
break;
|
||||
|
||||
case META_FRAME_ACTION_RESIZING_SE:
|
||||
update_resize_se (frame);
|
||||
update_resize_se (frame, event->xbutton.x_root, event->xbutton.y_root);
|
||||
ungrab_action (frame, event->xbutton.time);
|
||||
update_current_control (frame,
|
||||
event->xbutton.x_root, event->xbutton.y_root);
|
||||
break;
|
||||
|
||||
case META_FRAME_ACTION_DELETING:
|
||||
/* Must ungrab before getting "real" control position */
|
||||
ungrab_action (frame, event->xbutton.time);
|
||||
update_current_control (frame,
|
||||
event->xbutton.x_root,
|
||||
event->xbutton.y_root);
|
||||
/* delete if we're still over the button */
|
||||
if (frame->current_control == META_FRAME_CONTROL_DELETE)
|
||||
meta_window_delete (frame->window, event->xbutton.time);
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning ("Unhandled action in button release\n");
|
||||
break;
|
||||
}
|
||||
|
||||
frame->action = META_FRAME_ACTION_NONE;
|
||||
}
|
||||
break;
|
||||
case MotionNotify:
|
||||
switch (frame->action)
|
||||
{
|
||||
case META_FRAME_ACTION_MOVING:
|
||||
update_move (frame);
|
||||
break;
|
||||
{
|
||||
int x, y;
|
||||
|
||||
case META_FRAME_ACTION_RESIZING_SE:
|
||||
update_resize_se (frame);
|
||||
break;
|
||||
|
||||
case META_FRAME_ACTION_NONE:
|
||||
#if 0
|
||||
meta_ui_slave_show_tip (frame->window->screen->uislave,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
"Hi this is a tooltip");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
frame_query_root_pointer (frame, &x, &y);
|
||||
if (frame->grab)
|
||||
{
|
||||
switch (frame->grab->action)
|
||||
{
|
||||
case META_FRAME_ACTION_MOVING:
|
||||
update_move (frame, x, y);
|
||||
break;
|
||||
|
||||
case META_FRAME_ACTION_RESIZING_SE:
|
||||
update_resize_se (frame, x, y);
|
||||
break;
|
||||
|
||||
case META_FRAME_ACTION_NONE:
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
update_current_control (frame, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EnterNotify:
|
||||
@ -663,6 +884,7 @@ meta_frame_event (MetaFrame *frame,
|
||||
event->xcrossing.time);
|
||||
break;
|
||||
case LeaveNotify:
|
||||
update_current_control (frame, -1, -1);
|
||||
break;
|
||||
case FocusIn:
|
||||
break;
|
||||
@ -698,10 +920,12 @@ meta_frame_event (MetaFrame *frame,
|
||||
}
|
||||
break;
|
||||
case UnmapNotify:
|
||||
frame->action = META_FRAME_ACTION_NONE;
|
||||
if (frame->grab)
|
||||
ungrab_action (frame, CurrentTime);
|
||||
break;
|
||||
case MapNotify:
|
||||
frame->action = META_FRAME_ACTION_NONE;
|
||||
if (frame->grab)
|
||||
ungrab_action (frame, CurrentTime);
|
||||
break;
|
||||
case MapRequest:
|
||||
break;
|
||||
|
20
src/frame.h
20
src/frame.h
@ -28,9 +28,12 @@ typedef enum
|
||||
{
|
||||
META_FRAME_ACTION_NONE,
|
||||
META_FRAME_ACTION_MOVING,
|
||||
META_FRAME_ACTION_DELETING,
|
||||
META_FRAME_ACTION_RESIZING_SE
|
||||
} MetaFrameAction;
|
||||
|
||||
typedef struct _MetaFrameActionGrab MetaFrameActionGrab;
|
||||
|
||||
struct _MetaFrame
|
||||
{
|
||||
/* window we frame */
|
||||
@ -48,23 +51,18 @@ struct _MetaFrame
|
||||
|
||||
gpointer theme_data;
|
||||
gulong bg_pixel;
|
||||
|
||||
MetaFrameAction action;
|
||||
/* initial mouse position for drags */
|
||||
int start_root_x, start_root_y;
|
||||
/* initial window size or initial window position for drags */
|
||||
int start_window_x, start_window_y;
|
||||
/* button doing the dragging */
|
||||
int start_button;
|
||||
|
||||
MetaFrameActionGrab *grab;
|
||||
|
||||
MetaFrameControl current_control;
|
||||
|
||||
guint tooltip_timeout;
|
||||
|
||||
guint theme_acquired : 1;
|
||||
};
|
||||
|
||||
void meta_window_ensure_frame (MetaWindow *window);
|
||||
void meta_window_destroy_frame (MetaWindow *window);
|
||||
void meta_frame_move (MetaFrame *frame,
|
||||
int root_x,
|
||||
int root_y);
|
||||
void meta_frame_child_configure_request (MetaFrame *frame);
|
||||
void meta_frame_recalc_now (MetaFrame *frame);
|
||||
void meta_frame_queue_recalc (MetaFrame *frame);
|
||||
|
172
src/keybindings.c
Normal file
172
src/keybindings.c
Normal file
@ -0,0 +1,172 @@
|
||||
/* Metacity Keybindings */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "keybindings.h"
|
||||
#include "workspace.h"
|
||||
#include "errors.h"
|
||||
|
||||
#include <X11/keysym.h>
|
||||
|
||||
/* Plainly we'll want some more configurable keybinding system
|
||||
* eventually.
|
||||
*/
|
||||
|
||||
typedef void (* MetaKeyHandler) (MetaDisplay *display,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
|
||||
static void handle_activate_workspace (MetaDisplay *display,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
|
||||
struct _MetaKeyBinding
|
||||
{
|
||||
KeySym keysym;
|
||||
gulong mask;
|
||||
MetaKeyHandler handler;
|
||||
gpointer data;
|
||||
int keycode;
|
||||
};
|
||||
|
||||
#define INTERESTING_MODIFIERS (ShiftMask | ControlMask | Mod1Mask)
|
||||
|
||||
static MetaKeyBinding bindings[] = {
|
||||
{ XK_F1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 },
|
||||
{ XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 }
|
||||
};
|
||||
|
||||
void
|
||||
meta_display_init_keys (MetaDisplay *display)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
{
|
||||
bindings[i].keycode = XKeysymToKeycode (display->xdisplay,
|
||||
bindings[i].keysym);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_grab_keys (MetaScreen *screen)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
{
|
||||
if (bindings[i].keycode != 0)
|
||||
{
|
||||
int result;
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XGrabKey (screen->display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, screen->xroot, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
result = meta_error_trap_pop (screen->display);
|
||||
if (result != Success)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = XKeysymToString (bindings[i].keysym);
|
||||
if (name == NULL)
|
||||
name = "(unknown)";
|
||||
|
||||
if (result == BadAccess)
|
||||
meta_warning (_("Some other program is already using the key %s as a binding\n"), name);
|
||||
else
|
||||
meta_bug ("Unexpected error setting up keybindings\n");
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_ungrab_keys (MetaScreen *screen)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
{
|
||||
if (bindings[i].keycode != 0)
|
||||
{
|
||||
XUngrabKey (screen->display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, screen->xroot);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_process_key_press (MetaDisplay *display,
|
||||
XEvent *event)
|
||||
{
|
||||
KeySym keysym;
|
||||
int i;
|
||||
|
||||
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
{
|
||||
if (bindings[i].keysym == keysym &&
|
||||
((event->xkey.state & INTERESTING_MODIFIERS) ==
|
||||
bindings[i].mask))
|
||||
{
|
||||
(* bindings[i].handler) (display, event, bindings[i].data);
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_activate_workspace (MetaDisplay *display,
|
||||
XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
int which;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
which = GPOINTER_TO_INT (data);
|
||||
|
||||
workspace = meta_display_get_workspace_by_index (display, which);
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
meta_workspace_activate (workspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could offer to create it I suppose */
|
||||
}
|
||||
}
|
||||
|
37
src/keybindings.h
Normal file
37
src/keybindings.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* Metacity Keybindings */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KEYBINDINGS_H
|
||||
#define META_KEYBINDINGS_H
|
||||
|
||||
#include "display.h"
|
||||
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_screen_grab_keys (MetaScreen *screen);
|
||||
void meta_screen_ungrab_keys (MetaScreen *screen);
|
||||
void meta_display_process_key_press (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
37
src/screen.c
37
src/screen.c
@ -26,6 +26,8 @@
|
||||
#include "colors.h"
|
||||
#include "uislave.h"
|
||||
#include "frame.h"
|
||||
#include "workspace.h"
|
||||
#include "keybindings.h"
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <locale.h>
|
||||
@ -100,9 +102,20 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
screen->engine = &meta_default_engine;
|
||||
|
||||
screen->showing_tooltip = FALSE;
|
||||
|
||||
/* Screens must have at least one workspace at all times,
|
||||
* so create that required workspace.
|
||||
*/
|
||||
screen->active_workspace = meta_workspace_new (screen);
|
||||
/* FIXME, for debugging create another one. */
|
||||
meta_workspace_new (screen);
|
||||
|
||||
meta_screen_init_visual_info (screen);
|
||||
meta_screen_init_ui_colors (screen);
|
||||
|
||||
meta_screen_grab_keys (screen);
|
||||
|
||||
screen->scratch_gc = XCreateGC (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
0,
|
||||
@ -121,6 +134,8 @@ meta_screen_new (MetaDisplay *display,
|
||||
void
|
||||
meta_screen_free (MetaScreen *screen)
|
||||
{
|
||||
meta_screen_ungrab_keys (screen);
|
||||
|
||||
meta_ui_slave_free (screen->uislave);
|
||||
|
||||
XFreeGC (screen->display->xdisplay,
|
||||
@ -419,3 +434,25 @@ meta_screen_queue_frame_redraws (MetaScreen *screen)
|
||||
{
|
||||
meta_screen_foreach_window (screen, queue_draw, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_screen_show_tip (MetaScreen *screen,
|
||||
int root_x,
|
||||
int root_y,
|
||||
const char *markup)
|
||||
{
|
||||
/* even if screen->showing_tip, may change position/text */
|
||||
meta_ui_slave_show_tip (screen->uislave, root_x, root_y, markup);
|
||||
screen->showing_tooltip = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_hide_tip (MetaScreen *screen)
|
||||
{
|
||||
if (screen->showing_tooltip)
|
||||
{
|
||||
meta_ui_slave_hide_tip (screen->uislave);
|
||||
screen->showing_tooltip = FALSE;
|
||||
}
|
||||
}
|
||||
|
10
src/screen.h
10
src/screen.h
@ -39,6 +39,8 @@ struct _MetaScreen
|
||||
MetaThemeEngine *engine;
|
||||
MetaUISlave *uislave;
|
||||
|
||||
MetaWorkspace *active_workspace;
|
||||
|
||||
XVisualInfo visual_info;
|
||||
MetaUIColors colors;
|
||||
|
||||
@ -46,6 +48,8 @@ struct _MetaScreen
|
||||
* left with a clip.
|
||||
*/
|
||||
GC scratch_gc;
|
||||
|
||||
guint showing_tooltip : 1;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
@ -68,6 +72,12 @@ void meta_screen_foreach_window (MetaScreen *scree
|
||||
gpointer data);
|
||||
void meta_screen_queue_frame_redraws (MetaScreen *screen);
|
||||
|
||||
void meta_screen_show_tip (MetaScreen *screen,
|
||||
int root_x,
|
||||
int root_y,
|
||||
const char *markup);
|
||||
|
||||
void meta_screen_hide_tip (MetaScreen *screen);
|
||||
|
||||
#endif
|
||||
|
||||
|
156
src/theme.c
156
src/theme.c
@ -58,6 +58,8 @@ struct _DefaultScreenData
|
||||
GC black_gc;
|
||||
GC selected_gc;
|
||||
GC selected_text_gc;
|
||||
GC active_gc;
|
||||
GC prelight_gc;
|
||||
};
|
||||
|
||||
/* FIXME store this on the screen */
|
||||
@ -114,6 +116,21 @@ default_acquire_frame (MetaFrameInfo *info)
|
||||
RootWindowOfScreen (info->screen),
|
||||
GCForeground,
|
||||
&vals);
|
||||
|
||||
vals.foreground = meta_get_x_pixel (info->screen,
|
||||
&info->colors->bg[META_STATE_ACTIVE]);
|
||||
screen_data->active_gc = XCreateGC (info->display,
|
||||
RootWindowOfScreen (info->screen),
|
||||
GCForeground,
|
||||
&vals);
|
||||
|
||||
vals.foreground = meta_get_x_pixel (info->screen,
|
||||
&info->colors->bg[META_STATE_PRELIGHT]);
|
||||
screen_data->prelight_gc = XCreateGC (info->display,
|
||||
RootWindowOfScreen (info->screen),
|
||||
GCForeground,
|
||||
&vals);
|
||||
|
||||
|
||||
color.red = color.green = color.blue = 0;
|
||||
vals.foreground = meta_get_x_pixel (info->screen,
|
||||
@ -422,6 +439,97 @@ set_clip (Display *display, GC gc, MetaRectangle *rect)
|
||||
}
|
||||
}
|
||||
|
||||
static MetaRectangle*
|
||||
control_rect (MetaFrameControl control,
|
||||
DefaultFrameGeometry *fgeom)
|
||||
{
|
||||
MetaRectangle *rect;
|
||||
|
||||
rect = NULL;
|
||||
switch (control)
|
||||
{
|
||||
case META_FRAME_CONTROL_TITLE:
|
||||
rect = &fgeom->title_rect;
|
||||
break;
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
rect = &fgeom->close_rect;
|
||||
break;
|
||||
case META_FRAME_CONTROL_MENU:
|
||||
rect = &fgeom->menu_rect;
|
||||
break;
|
||||
case META_FRAME_CONTROL_ICONIFY:
|
||||
rect = &fgeom->min_rect;
|
||||
break;
|
||||
case META_FRAME_CONTROL_MAXIMIZE:
|
||||
rect = &fgeom->max_rect;
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_S:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_SW:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_N:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_NE:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_NW:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_W:
|
||||
break;
|
||||
case META_FRAME_CONTROL_RESIZE_E:
|
||||
break;
|
||||
case META_FRAME_CONTROL_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_current_control_bg (MetaFrameInfo *info,
|
||||
DefaultFrameGeometry *fgeom)
|
||||
{
|
||||
int xoff, yoff;
|
||||
MetaRectangle *rect;
|
||||
|
||||
xoff = info->xoffset;
|
||||
yoff = info->yoffset;
|
||||
|
||||
rect = control_rect (info->current_control, fgeom);
|
||||
|
||||
if (rect == NULL)
|
||||
return;
|
||||
|
||||
if (info->current_control == META_FRAME_CONTROL_TITLE)
|
||||
return;
|
||||
|
||||
switch (info->current_control_state)
|
||||
{
|
||||
/* FIXME turn this off after testing */
|
||||
case META_STATE_PRELIGHT:
|
||||
XFillRectangle (info->display,
|
||||
info->drawable,
|
||||
screen_data->prelight_gc,
|
||||
xoff + rect->x,
|
||||
yoff + rect->y,
|
||||
rect->width, rect->height);
|
||||
break;
|
||||
|
||||
case META_STATE_ACTIVE:
|
||||
XFillRectangle (info->display,
|
||||
info->drawable,
|
||||
screen_data->active_gc,
|
||||
xoff + rect->x,
|
||||
yoff + rect->y,
|
||||
rect->width, rect->height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
default_expose_frame (MetaFrameInfo *info,
|
||||
int x, int y,
|
||||
@ -483,6 +591,8 @@ default_expose_frame (MetaFrameInfo *info,
|
||||
info->width - fgeom.right_width - fgeom.left_width + 1,
|
||||
info->height - fgeom.bottom_height - fgeom.top_height + 1);
|
||||
}
|
||||
|
||||
draw_current_control_bg (info, &fgeom);
|
||||
|
||||
if (fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0)
|
||||
{
|
||||
@ -527,7 +637,7 @@ default_expose_frame (MetaFrameInfo *info,
|
||||
}
|
||||
|
||||
if (fgeom.close_rect.width > 0 && fgeom.close_rect.height > 0)
|
||||
{
|
||||
{
|
||||
XDrawLine (info->display,
|
||||
info->drawable,
|
||||
screen_data->fg_gc,
|
||||
@ -644,6 +754,15 @@ default_get_control (MetaFrameInfo *info,
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.close_rect))
|
||||
return META_FRAME_CONTROL_DELETE;
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.min_rect))
|
||||
return META_FRAME_CONTROL_ICONIFY;
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.max_rect))
|
||||
return META_FRAME_CONTROL_MAXIMIZE;
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.menu_rect))
|
||||
return META_FRAME_CONTROL_MENU;
|
||||
|
||||
if (POINT_IN_RECT (x, y, fgeom.title_rect))
|
||||
return META_FRAME_CONTROL_TITLE;
|
||||
@ -655,6 +774,36 @@ default_get_control (MetaFrameInfo *info,
|
||||
return META_FRAME_CONTROL_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
default_get_control_rect (MetaFrameInfo *info,
|
||||
MetaFrameControl control,
|
||||
int *x, int *y,
|
||||
int *width, int *height,
|
||||
gpointer frame_data)
|
||||
{
|
||||
MetaRectangle *rect;
|
||||
DefaultFrameData *d;
|
||||
DefaultFrameGeometry fgeom;
|
||||
|
||||
d = frame_data;
|
||||
|
||||
calc_geometry (info, d, &fgeom);
|
||||
|
||||
rect = control_rect (control, &fgeom);
|
||||
|
||||
if (rect)
|
||||
{
|
||||
*x = rect->x;
|
||||
*y = rect->y;
|
||||
*width = rect->width;
|
||||
*height = rect->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
*x = *y = *width = *height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME add this to engine vtable */
|
||||
static void
|
||||
default_release_screen (Screen *screen)
|
||||
@ -668,6 +817,8 @@ default_release_screen (Screen *screen)
|
||||
XFreeGC (DisplayOfScreen (screen), screen_data->black_gc);
|
||||
XFreeGC (DisplayOfScreen (screen), screen_data->light_gc);
|
||||
XFreeGC (DisplayOfScreen (screen), screen_data->dark_gc);
|
||||
XFreeGC (DisplayOfScreen (screen), screen_data->active_gc);
|
||||
XFreeGC (DisplayOfScreen (screen), screen_data->prelight_gc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,5 +828,6 @@ MetaThemeEngine meta_default_engine = {
|
||||
default_release_frame,
|
||||
default_fill_frame_geometry,
|
||||
default_expose_frame,
|
||||
default_get_control
|
||||
default_get_control,
|
||||
default_get_control_rect
|
||||
};
|
||||
|
@ -76,6 +76,9 @@ struct _MetaFrameInfo
|
||||
const char *title;
|
||||
|
||||
const MetaUIColors *colors;
|
||||
|
||||
MetaFrameControl current_control;
|
||||
MetaUIState current_control_state;
|
||||
|
||||
/* Equal to child size before fill_frame_geometry
|
||||
* has been called
|
||||
@ -121,6 +124,12 @@ struct _MetaThemeEngine
|
||||
MetaFrameControl (* get_control) (MetaFrameInfo *info,
|
||||
int x, int y,
|
||||
gpointer frame_data);
|
||||
|
||||
void (* get_control_rect) (MetaFrameInfo *info,
|
||||
MetaFrameControl control,
|
||||
int *x, int *y,
|
||||
int *width, int *height,
|
||||
gpointer frame_data);
|
||||
};
|
||||
|
||||
extern MetaThemeEngine meta_default_engine;
|
||||
|
@ -305,3 +305,15 @@ meta_ui_slave_show_tip (MetaUISlave *uislave,
|
||||
|
||||
send_message (uislave, (MetaMessage*)&showtip);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_slave_hide_tip (MetaUISlave *uislave)
|
||||
{
|
||||
MetaMessageHideTip hidetip;
|
||||
|
||||
memset (&hidetip, 0, META_MESSAGE_LENGTH (MetaMessageHideTip));
|
||||
hidetip.header.message_code = MetaMessageHideTipCode;
|
||||
hidetip.header.length = META_MESSAGE_LENGTH (MetaMessageHideTip);
|
||||
|
||||
send_message (uislave, (MetaMessage*)&hidetip);
|
||||
}
|
||||
|
@ -62,5 +62,6 @@ void meta_ui_slave_show_tip (MetaUISlave *uislave,
|
||||
int root_x,
|
||||
int root_y,
|
||||
const char *markup_text);
|
||||
void meta_ui_slave_hide_tip (MetaUISlave *uislave);
|
||||
|
||||
#endif
|
||||
|
@ -63,6 +63,10 @@ message_callback (MetaMessageQueue *mq,
|
||||
message->show_tip.root_y,
|
||||
message->show_tip.markup);
|
||||
break;
|
||||
|
||||
case MetaMessageHideTipCode:
|
||||
meta_fixed_tip_hide ();
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_ui_warning ("Unhandled message code %d\n",
|
||||
|
219
src/window.c
219
src/window.c
@ -23,22 +23,33 @@
|
||||
#include "util.h"
|
||||
#include "frame.h"
|
||||
#include "errors.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
static void constrain_size (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int *new_width,
|
||||
int *new_height);
|
||||
static int update_size_hints (MetaWindow *window);
|
||||
static int update_title (MetaWindow *window);
|
||||
static int update_protocols (MetaWindow *window);
|
||||
static int update_wm_hints (MetaWindow *window);
|
||||
static gboolean process_configure_request (MetaWindow *window,
|
||||
int x, int y, int width, int height,
|
||||
int border_width);
|
||||
static gboolean process_property_notify (MetaWindow *window,
|
||||
XPropertyEvent *event);
|
||||
static void constrain_size (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int *new_width,
|
||||
int *new_height);
|
||||
static int update_size_hints (MetaWindow *window);
|
||||
static int update_title (MetaWindow *window);
|
||||
static int update_protocols (MetaWindow *window);
|
||||
static int update_wm_hints (MetaWindow *window);
|
||||
static int set_wm_state (MetaWindow *window,
|
||||
int state);
|
||||
static void send_configure_notify (MetaWindow *window);
|
||||
static gboolean process_configure_request (MetaWindow *window,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int border_width);
|
||||
static gboolean process_property_notify (MetaWindow *window,
|
||||
XPropertyEvent *event);
|
||||
static void meta_window_show (MetaWindow *window);
|
||||
static void meta_window_hide (MetaWindow *window);
|
||||
|
||||
|
||||
MetaWindow*
|
||||
meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
@ -88,6 +99,7 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
* type
|
||||
*/
|
||||
window->display = display;
|
||||
window->workspaces = NULL;
|
||||
|
||||
window->screen = NULL;
|
||||
tmp = display->screens;
|
||||
@ -141,21 +153,26 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
|
||||
if (window->initially_iconic)
|
||||
{
|
||||
/* WM_HINTS said iconic */
|
||||
window->iconic = TRUE;
|
||||
/* WM_HINTS said minimized */
|
||||
window->minimized = TRUE;
|
||||
meta_verbose ("Window %s asked to start out minimized\n", window->desc);
|
||||
}
|
||||
|
||||
meta_window_resize (window, window->size_hints.width, window->size_hints.height);
|
||||
meta_window_resize (window,
|
||||
window->size_hints.width,
|
||||
window->size_hints.height);
|
||||
|
||||
/* FIXME we have a tendency to set this then immediately
|
||||
* change it again.
|
||||
*/
|
||||
set_wm_state (window, window->iconic ? IconicState : NormalState);
|
||||
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
/* Put our state where it should be (ensure_frame also did this
|
||||
* for decorated windows, but should be harmless to do twice)
|
||||
*/
|
||||
if (window->iconic)
|
||||
meta_window_hide (window);
|
||||
else
|
||||
meta_window_show (window);
|
||||
meta_workspace_add_window (window->screen->active_workspace, window);
|
||||
|
||||
/* Put our state back where it should be */
|
||||
meta_window_queue_calc_showing (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@ -163,7 +180,26 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
void
|
||||
meta_window_free (MetaWindow *window)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
|
||||
|
||||
tmp = window->workspaces;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
GList *next;
|
||||
|
||||
next = tmp->next;
|
||||
|
||||
/* pops front of list */
|
||||
meta_workspace_remove_window (tmp->data, window);
|
||||
|
||||
tmp = next;
|
||||
}
|
||||
|
||||
g_assert (window->workspaces == NULL);
|
||||
|
||||
set_wm_state (window, WithdrawnState);
|
||||
|
||||
meta_display_unregister_x_window (window->display, window->xwindow);
|
||||
|
||||
@ -183,9 +219,64 @@ meta_window_free (MetaWindow *window)
|
||||
g_free (window);
|
||||
}
|
||||
|
||||
static int
|
||||
set_wm_state (MetaWindow *window,
|
||||
int state)
|
||||
{
|
||||
unsigned long data[1];
|
||||
|
||||
/* twm sets the icon window as data[1], I couldn't find that in
|
||||
* ICCCM.
|
||||
*/
|
||||
data[0] = state;
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
XChangeProperty (window->display->xdisplay, window->xwindow,
|
||||
window->display->atom_wm_state,
|
||||
window->display->atom_wm_state,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
return meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_calc_showing (MetaWindow *window)
|
||||
{
|
||||
gboolean on_workspace;
|
||||
|
||||
on_workspace = g_list_find (window->workspaces,
|
||||
window->screen->active_workspace) != NULL;
|
||||
|
||||
if (!on_workspace)
|
||||
meta_verbose ("Window %s is not on workspace %d\n",
|
||||
window->desc,
|
||||
meta_workspace_index (window->screen->active_workspace));
|
||||
else
|
||||
meta_verbose ("Window %s is on the active workspace %d\n",
|
||||
window->desc,
|
||||
meta_workspace_index (window->screen->active_workspace));
|
||||
|
||||
if (window->minimized || !on_workspace)
|
||||
{
|
||||
meta_window_hide (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_window_show (window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_queue_calc_showing (MetaWindow *window)
|
||||
{
|
||||
/* FIXME */
|
||||
meta_window_calc_showing (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_show (MetaWindow *window)
|
||||
{
|
||||
meta_verbose ("Showing window %s\n", window->desc);
|
||||
|
||||
if (window->frame)
|
||||
XMapWindow (window->display->xdisplay, window->frame->xwindow);
|
||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||
@ -193,25 +284,33 @@ meta_window_show (MetaWindow *window)
|
||||
/* These flags aren't always in sync, iconic
|
||||
* is set only here in show/hide, mapped
|
||||
* can be set in a couple other places where
|
||||
* we map/unmap
|
||||
* we map/unmap. So that's why both flags exist.
|
||||
*/
|
||||
window->mapped = TRUE;
|
||||
window->iconic = FALSE;
|
||||
|
||||
/* FIXME update WM_STATE */
|
||||
if (window->iconic)
|
||||
{
|
||||
window->iconic = FALSE;
|
||||
set_wm_state (window, NormalState);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_hide (MetaWindow *window)
|
||||
{
|
||||
meta_verbose ("Hiding window %s\n", window->desc);
|
||||
|
||||
if (window->frame)
|
||||
XUnmapWindow (window->display->xdisplay, window->frame->xwindow);
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
|
||||
window->mapped = FALSE;
|
||||
window->iconic = TRUE;
|
||||
|
||||
/* FIXME update WM_STATE */
|
||||
if (!window->iconic)
|
||||
{
|
||||
window->iconic = TRUE;
|
||||
set_wm_state (window, IconicState);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -259,6 +358,48 @@ meta_window_resize (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_move (MetaWindow *window,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
int new_x, new_y;
|
||||
|
||||
new_x = root_x_nw - window->frame->child_x;
|
||||
new_y = root_y_nw - window->frame->child_y;
|
||||
|
||||
if (new_x != window->frame->rect.x ||
|
||||
new_y != window->frame->rect.y)
|
||||
{
|
||||
window->frame->rect.x = new_x;
|
||||
window->frame->rect.y = new_y;
|
||||
|
||||
XMoveWindow (window->display->xdisplay,
|
||||
window->frame->xwindow,
|
||||
window->frame->rect.x,
|
||||
window->frame->rect.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (root_x_nw != window->rect.x ||
|
||||
root_y_nw != window->rect.y)
|
||||
{
|
||||
window->rect.x = root_x_nw;
|
||||
window->rect.y = root_y_nw;
|
||||
|
||||
XMoveWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
}
|
||||
}
|
||||
|
||||
send_configure_notify (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_delete (MetaWindow *window,
|
||||
Time timestamp)
|
||||
@ -308,6 +449,26 @@ meta_window_focus (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_raise (MetaWindow *window)
|
||||
{
|
||||
meta_verbose ("Raising window %s\n", window->desc);
|
||||
|
||||
if (window->frame == NULL)
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
|
||||
XRaiseWindow (window->display->xdisplay, window->xwindow);
|
||||
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
XRaiseWindow (window->display->xdisplay,
|
||||
window->frame->xwindow);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_send_icccm_message (MetaWindow *window,
|
||||
Atom atom,
|
||||
|
38
src/window.h
38
src/window.h
@ -30,6 +30,7 @@ struct _MetaWindow
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
GList *workspaces;
|
||||
Window xwindow;
|
||||
/* may be NULL! not all windows get decorated */
|
||||
MetaFrame *frame;
|
||||
@ -51,7 +52,7 @@ struct _MetaWindow
|
||||
*/
|
||||
guint iconic : 1;
|
||||
/* initially_iconic is the WM_HINTS setting when we first manage
|
||||
* the window.
|
||||
* the window. It's taken to mean initially minimized.
|
||||
*/
|
||||
guint initially_iconic : 1;
|
||||
|
||||
@ -75,20 +76,27 @@ struct _MetaWindow
|
||||
XSizeHints size_hints;
|
||||
};
|
||||
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
void meta_window_free (MetaWindow *window);
|
||||
void meta_window_show (MetaWindow *window);
|
||||
void meta_window_hide (MetaWindow *window);
|
||||
void meta_window_minimize (MetaWindow *window);
|
||||
void meta_window_unminimize (MetaWindow *window);
|
||||
void meta_window_resize (MetaWindow *window,
|
||||
int w,
|
||||
int h);
|
||||
void meta_window_delete (MetaWindow *window,
|
||||
Time timestamp);
|
||||
void meta_window_focus (MetaWindow *window,
|
||||
Time timestamp);
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
void meta_window_free (MetaWindow *window);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
void meta_window_queue_calc_showing (MetaWindow *window);
|
||||
void meta_window_minimize (MetaWindow *window);
|
||||
void meta_window_unminimize (MetaWindow *window);
|
||||
void meta_window_resize (MetaWindow *window,
|
||||
int w,
|
||||
int h);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
int root_x_nw,
|
||||
int root_y_nw);
|
||||
void meta_window_delete (MetaWindow *window,
|
||||
Time timestamp);
|
||||
void meta_window_focus (MetaWindow *window,
|
||||
Time timestamp);
|
||||
void meta_window_raise (MetaWindow *window);
|
||||
|
||||
|
||||
/* Sends a client message */
|
||||
void meta_window_send_icccm_message (MetaWindow *window,
|
||||
|
141
src/workspace.c
Normal file
141
src/workspace.c
Normal file
@ -0,0 +1,141 @@
|
||||
/* Metacity Workspaces */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "workspace.h"
|
||||
|
||||
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
||||
|
||||
MetaWorkspace*
|
||||
meta_workspace_new (MetaScreen *screen)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
workspace = g_new (MetaWorkspace, 1);
|
||||
|
||||
workspace->screen = screen;
|
||||
workspace->screen->display->workspaces =
|
||||
g_list_append (workspace->screen->display->workspaces, workspace);
|
||||
workspace->windows = NULL;
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_free (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
GList *next;
|
||||
next = tmp->next;
|
||||
/* pop front of list */
|
||||
meta_workspace_remove_window (workspace, tmp->data);
|
||||
|
||||
tmp = next;
|
||||
}
|
||||
|
||||
g_assert (workspace->windows == NULL);
|
||||
|
||||
workspace->screen->display->workspaces =
|
||||
g_list_remove (workspace->screen->display->workspaces, workspace);
|
||||
|
||||
g_free (workspace);
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_return_if_fail (g_list_find (workspace->windows, window) == NULL);
|
||||
|
||||
workspace->windows = g_list_prepend (workspace->windows, window);
|
||||
window->workspaces = g_list_prepend (window->workspaces, workspace);
|
||||
|
||||
meta_window_queue_calc_showing (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_return_if_fail (g_list_find (workspace->windows, window) != NULL);
|
||||
|
||||
workspace->windows = g_list_remove (workspace->windows, window);
|
||||
window->workspaces = g_list_remove (window->workspaces, workspace);
|
||||
|
||||
meta_window_queue_calc_showing (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_queue_calc_showing (tmp->data);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_activate (MetaWorkspace *workspace)
|
||||
{
|
||||
MetaWorkspace *old;
|
||||
|
||||
meta_verbose ("Activating workspace %d\n",
|
||||
meta_workspace_index (workspace));
|
||||
|
||||
if (workspace->screen->active_workspace == workspace)
|
||||
return;
|
||||
|
||||
old = workspace->screen->active_workspace;
|
||||
|
||||
workspace->screen->active_workspace = workspace;
|
||||
|
||||
meta_workspace_queue_calc_showing (old);
|
||||
meta_workspace_queue_calc_showing (workspace);
|
||||
}
|
||||
|
||||
int
|
||||
meta_workspace_index (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
tmp = workspace->screen->display->workspaces;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
if (tmp->data == workspace)
|
||||
return i;
|
||||
|
||||
++i;
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
meta_bug ("Workspace does not exist to index!\n");
|
||||
}
|
48
src/workspace.h
Normal file
48
src/workspace.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Metacity Workspaces */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_WORKSPACE_H
|
||||
#define META_WORKSPACE_H
|
||||
|
||||
#include "window.h"
|
||||
|
||||
struct _MetaWorkspace
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *windows;
|
||||
};
|
||||
|
||||
MetaWorkspace* meta_workspace_new (MetaScreen *screen);
|
||||
void meta_workspace_free (MetaWorkspace *workspace);
|
||||
void meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
void meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_workspace_activate (MetaWorkspace *workspace);
|
||||
int meta_workspace_index (MetaWorkspace *workspace);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user