From a6b2edc46756b60e976f1ef94ac3737ce417b1db Mon Sep 17 00:00:00 2001 From: rhp Date: Fri, 8 Jun 2001 02:17:48 +0000 Subject: [PATCH] ... --- src/display.c | 32 ++++++ src/display.h | 8 ++ src/frame.c | 38 ++++++-- src/theme.c | 11 ++- src/theme.h | 3 +- src/window.c | 262 ++++++++++++++++++++++++++++++++++---------------- src/window.h | 22 ++++- 7 files changed, 278 insertions(+), 98 deletions(-) diff --git a/src/display.c b/src/display.c index f9fb8ef55..8a38fdb16 100644 --- a/src/display.c +++ b/src/display.c @@ -157,6 +157,12 @@ meta_display_open (const char *name) display->atom_wm_delete_window = atoms[3]; display->atom_wm_state = atoms[4]; display->atom_net_close_window = atoms[5]; + + display->double_click_time = 250; + display->last_button_time = 0; + display->last_button_xwindow = None; + display->last_button_num = 0; + display->is_double_click = FALSE; /* Now manage all existing windows */ tmp = display->screens; @@ -335,6 +341,12 @@ meta_displays_list (void) return all_displays; } +gboolean +meta_display_is_double_click (MetaDisplay *display) +{ + return display->is_double_click; +} + static gboolean dump_events = TRUE; static void @@ -351,6 +363,26 @@ event_queue_callback (MetaEventQueue *queue, if (dump_events) meta_spew_event (display, event); + /* mark double click events, kind of a hack, oh well. */ + if (event->type == ButtonPress) + { + if (event->xbutton.button == display->last_button_num && + event->xbutton.window == display->last_button_xwindow && + event->xbutton.time < (display->last_button_time + display->double_click_time)) + { + display->is_double_click = TRUE; + meta_verbose ("This was the second click of a double click\n"); + } + else + { + display->is_double_click = FALSE; + } + + display->last_button_num = event->xbutton.button; + display->last_button_xwindow = event->xbutton.window; + display->last_button_time = event->xbutton.time; + } + modified = event_get_modified_window (display, event); if (modified != None) diff --git a/src/display.h b/src/display.h index 4a9df6460..bdb03be66 100644 --- a/src/display.h +++ b/src/display.h @@ -59,6 +59,13 @@ struct _MetaDisplay GHashTable *window_ids; GSList *error_traps; int server_grab_count; + + /* for double click */ + int double_click_time; + Time last_button_time; + Window last_button_xwindow; + int last_button_num; + guint is_double_click : 1; }; gboolean meta_display_open (const char *name); @@ -70,6 +77,7 @@ MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display, void meta_display_grab (MetaDisplay *display); void meta_display_ungrab (MetaDisplay *display); PangoContext* meta_display_get_pango_context (MetaDisplay *display); +gboolean meta_display_is_double_click (MetaDisplay *display); /* A given MetaWindow may have various X windows that "belong" * to it, such as the frame window. diff --git a/src/frame.c b/src/frame.c index fdd694896..fdeebeef6 100644 --- a/src/frame.c +++ b/src/frame.c @@ -44,7 +44,6 @@ struct _MetaFrameActionGrab PointerMotionMask | PointerMotionHintMask | \ EnterWindowMask | LeaveWindowMask) - static void clear_tip (MetaFrame *frame); static void @@ -58,6 +57,9 @@ meta_frame_init_info (MetaFrame *frame, if (frame->window->has_focus) info->flags |= META_FRAME_HAS_FOCUS; + + if (frame->window->shaded) + info->flags |= META_FRAME_SHADED; info->drawable = None; info->xoffset = 0; @@ -145,9 +147,13 @@ meta_frame_calc_geometry (MetaFrame *frame, */ window = frame->window; - + frame->rect.width = child_width; - frame->rect.height = child_height; + + if (window->shaded) + frame->rect.height = 0; + else + frame->rect.height = child_height; meta_frame_init_info (frame, &info); @@ -194,6 +200,7 @@ set_background_none (MetaFrame *frame) CWBackPixmap, &attrs); +#if 0 meta_debug_spew ("Frame size %d,%d %dx%d window size %d,%d %dx%d window pos %d,%d\n", frame->rect.x, frame->rect.y, @@ -205,6 +212,7 @@ set_background_none (MetaFrame *frame) frame->window->rect.height, frame->child_x, frame->child_y); +#endif } static void @@ -768,10 +776,26 @@ meta_frame_event (MetaFrame *frame, MetaFrameControl control; control = frame->current_control; - if (((control == META_FRAME_CONTROL_TITLE || - control == META_FRAME_CONTROL_NONE) && - event->xbutton.button == 1) || - event->xbutton.button == 2) + if (control == META_FRAME_CONTROL_TITLE && + event->xbutton.button == 1 && + meta_display_is_double_click (frame->window->display)) + { + meta_verbose ("Double click on title\n"); + + /* FIXME this catches double click that starts elsewhere + * with the second click on title, maybe no one will + * ever notice + */ + + if (frame->window->shaded) + meta_window_unshade (frame->window); + else + meta_window_shade (frame->window); + } + else if (((control == META_FRAME_CONTROL_TITLE || + control == META_FRAME_CONTROL_NONE) && + event->xbutton.button == 1) || + event->xbutton.button == 2) { meta_verbose ("Begin move on %s\n", frame->window->desc); diff --git a/src/theme.c b/src/theme.c index 700a2e62a..eb374375d 100644 --- a/src/theme.c +++ b/src/theme.c @@ -191,13 +191,20 @@ calc_geometry (MetaFrameInfo *info, int x; int button_y; int title_right_edge; + gboolean shaded; + + shaded = (info->flags & META_FRAME_SHADED) != 0; fgeom->top_height = MAX (d->layout_height + VERTICAL_TEXT_PAD * 2 + ABOVE_TITLE_PAD + BELOW_TITLE_PAD, BUTTON_HEIGHT + BUTTON_PAD * 2); - + fgeom->left_width = LEFT_WIDTH; fgeom->right_width = RIGHT_WIDTH; - fgeom->bottom_height = BOTTOM_HEIGHT; + + if (shaded) + fgeom->bottom_height = 0; + else + fgeom->bottom_height = BOTTOM_HEIGHT; x = info->width - fgeom->right_width; button_y = (fgeom->top_height - BUTTON_HEIGHT) / 2; diff --git a/src/theme.h b/src/theme.h index 5a7a9b93b..a80147a58 100644 --- a/src/theme.h +++ b/src/theme.h @@ -41,7 +41,8 @@ typedef enum META_FRAME_ALLOWS_MAXIMIZE = 1 << 3, META_FRAME_ALLOWS_RESIZE = 1 << 4, META_FRAME_TRANSIENT = 1 << 5, - META_FRAME_HAS_FOCUS = 1 << 6 + META_FRAME_HAS_FOCUS = 1 << 6, + META_FRAME_SHADED = 1 << 7 } MetaFrameFlags; typedef enum diff --git a/src/window.c b/src/window.c index 29dd5c1d8..8e169f3b2 100644 --- a/src/window.c +++ b/src/window.c @@ -143,6 +143,7 @@ meta_window_new (MetaDisplay *display, Window xwindow) window->has_focus = FALSE; window->maximized = FALSE; + window->shaded = FALSE; window->initially_iconic = FALSE; window->minimized = FALSE; window->iconic = FALSE; @@ -281,23 +282,35 @@ meta_window_queue_calc_showing (MetaWindow *window) void meta_window_show (MetaWindow *window) { - meta_verbose ("Showing window %s\n", window->desc); + meta_verbose ("Showing window %s, shaded: %d iconic: %d\n", + window->desc, window->shaded, window->iconic); + + /* Shaded means the frame is mapped but the window is not */ if (window->frame) XMapWindow (window->display->xdisplay, window->frame->xwindow); - XMapWindow (window->display->xdisplay, window->xwindow); - /* 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. So that's why both flags exist. - */ - window->mapped = TRUE; - - if (window->iconic) + if (window->shaded) { - window->iconic = FALSE; - set_wm_state (window, NormalState); + window->mapped = FALSE; + XUnmapWindow (window->display->xdisplay, window->xwindow); + + if (!window->iconic) + { + window->iconic = TRUE; + set_wm_state (window, IconicState); + } + } + else + { + window->mapped = TRUE; + XMapWindow (window->display->xdisplay, window->xwindow); + + if (window->iconic) + { + window->iconic = FALSE; + set_wm_state (window, NormalState); + } } } @@ -348,19 +361,15 @@ meta_window_maximize (MetaWindow *window) window->maximized = TRUE; - /* save size */ + /* save size/pos */ window->saved_rect = window->rect; if (window->frame) { window->saved_rect.x += window->frame->rect.x; window->saved_rect.y += window->frame->rect.y; } - - /* resize to current size with new maximization constraint */ - meta_window_resize (window, - window->rect.width, window->rect.height); - /* move to top left corner */ + /* find top left corner */ x = window->screen->active_workspace->workarea.x; y = window->screen->active_workspace->workarea.y; if (window->frame) @@ -368,8 +377,14 @@ meta_window_maximize (MetaWindow *window) x += window->frame->child_x; y += window->frame->child_y; } + - meta_window_move (window, x, y); + /* resize to current size with new maximization constraint, + * and move to top-left corner + */ + + meta_window_move_resize (window, x, y, + window->rect.width, window->rect.height); } } @@ -378,43 +393,146 @@ meta_window_unmaximize (MetaWindow *window) { if (window->maximized) { - int x, y; - - window->maximized = FALSE; + window->maximized = FALSE; - meta_window_resize (window, - window->saved_rect.width, - window->saved_rect.height); - - meta_window_move (window, - window->saved_rect.x, - window->saved_rect.y); + meta_window_move_resize (window, + window->saved_rect.x, + window->saved_rect.y, + window->saved_rect.width, + window->saved_rect.height); } } +void +meta_window_shade (MetaWindow *window) +{ + if (!window->shaded) + { + window->shaded = TRUE; + if (window->frame) + meta_frame_queue_recalc (window->frame); + meta_window_queue_calc_showing (window); + } +} + +void +meta_window_unshade (MetaWindow *window) +{ + if (window->shaded) + { + window->shaded = FALSE; + if (window->frame) + meta_frame_queue_recalc (window->frame); + meta_window_queue_calc_showing (window); + } +} + +static void +meta_window_move_resize_internal (MetaWindow *window, + gboolean move, + gboolean resize, + int root_x_nw, + int root_y_nw, + int w, + int h) +{ + if (resize) + meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h); + if (move) + meta_verbose ("Moving %s to %d,%d\n", window->desc, + root_x_nw, root_y_nw); + + if (resize) + { + constrain_size (window, w, h, &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) + resize = FALSE; + + window->rect.width = w; + window->rect.height = h; + } + + if (move) + { + 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) + move = FALSE; + + window->frame->rect.x = new_x; + window->frame->rect.y = new_y; + /* window->rect.x, window->rect.y remain relative to frame, + * remember they are the server coords + */ + } + else + { + if (root_x_nw == window->rect.x && + root_y_nw == window->rect.y) + move = FALSE; + + window->rect.x = root_x_nw; + window->rect.y = root_y_nw; + } + } + + /* Sync our new size/pos with X as efficiently as possible */ + + if (move && window->frame) + { + XMoveWindow (window->display->xdisplay, + window->frame->xwindow, + window->frame->rect.x, + window->frame->rect.y); + } + + meta_error_trap_push (window->display); + if ((move && window->frame == NULL) && resize) + { + XMoveResizeWindow (window->display->xdisplay, + window->xwindow, + window->rect.x, + window->rect.y, + window->rect.width, + window->rect.height); + } + else if (move && window->frame == NULL) + { + XMoveWindow (window->display->xdisplay, + window->xwindow, + window->rect.x, + window->rect.y); + } + else if (resize) + { + XResizeWindow (window->display->xdisplay, + window->xwindow, + w, h); + + } + meta_error_trap_pop (window->display); + + if (move) + send_configure_notify (window); + + if (window->frame && resize) + meta_frame_queue_recalc (window->frame); +} + void meta_window_resize (MetaWindow *window, int w, int h) { - meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h); - constrain_size (window, w, h, &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) - { - meta_error_trap_push (window->display); - XResizeWindow (window->display->xdisplay, - window->xwindow, - w, h); - meta_error_trap_pop (window->display); - window->rect.width = w; - window->rect.height = h; - - if (window->frame) - meta_frame_queue_recalc (window->frame); - } + meta_window_move_resize_internal (window, FALSE, TRUE, -1, -1, w, h); } void @@ -422,44 +540,20 @@ meta_window_move (MetaWindow *window, int root_x_nw, int root_y_nw) { - if (window->frame) - { - int new_x, new_y; + meta_window_move_resize_internal (window, TRUE, FALSE, + root_x_nw, root_y_nw, -1, -1); +} - 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; - /* window->rect.x, window->rect.y remain relative to frame, - * remember they are the server coords - */ - - 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_move_resize (MetaWindow *window, + int root_x_nw, + int root_y_nw, + int w, + int h) +{ + meta_window_move_resize_internal (window, TRUE, TRUE, + root_x_nw, root_y_nw, + w, h); } void diff --git a/src/window.h b/src/window.h index 38d4440a0..84e7f3b44 100644 --- a/src/window.h +++ b/src/window.h @@ -40,15 +40,21 @@ struct _MetaWindow char *title; /* Whether we're maximized */ - guint maximized : 1; + guint maximized : 1; + + /* Whether we're shaded */ + guint shaded : 1; + /* Mapped is what we think the mapped state should be; * so if we get UnmapNotify and mapped == TRUE then * it's a withdraw, if mapped == FALSE the UnmapNotify * is caused by us. */ guint mapped : 1 ; + /* Minimize is the state controlled by the minimize button */ guint minimized : 1; + /* Iconic is the state in WM_STATE; happens for workspaces/shading * in addition to minimize */ @@ -96,16 +102,24 @@ 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); void meta_window_maximize (MetaWindow *window); void meta_window_unmaximize (MetaWindow *window); +void meta_window_shade (MetaWindow *window); +void meta_window_unshade (MetaWindow *window); + /* 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_resize (MetaWindow *window, + int w, + int h); +void meta_window_move_resize (MetaWindow *window, + int root_x_nw, + int root_y_nw, + int w, + int h); void meta_window_delete (MetaWindow *window, Time timestamp); void meta_window_focus (MetaWindow *window,