comparison src/xterm.c @ 90472:138027c8c982

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 300-313) - Update from CVS - Update from CVS: lispref/display.texi (Forcing Redisplay): Fix typo. - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 105-106) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-74
author Miles Bader <miles@gnu.org>
date Sat, 17 Jun 2006 20:57:37 +0000
parents 60db44f4be6a 030275d8610f
children e33114b32ce5
comparison
equal deleted inserted replaced
90471:bdc1386b2827 90472:138027c8c982
357 static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, 357 static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
358 enum scroll_bar_part *, 358 enum scroll_bar_part *,
359 Lisp_Object *, Lisp_Object *, 359 Lisp_Object *, Lisp_Object *,
360 unsigned long *)); 360 unsigned long *));
361 static void x_check_fullscreen P_ ((struct frame *)); 361 static void x_check_fullscreen P_ ((struct frame *));
362 static void x_check_expected_move P_ ((struct frame *)); 362 static void x_check_expected_move P_ ((struct frame *, int, int));
363 static void x_sync_with_move P_ ((struct frame *, int, int, int));
363 static int handle_one_xevent P_ ((struct x_display_info *, XEvent *, 364 static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
364 int *, struct input_event *)); 365 int *, struct input_event *));
365 static SIGTYPE x_connection_closed P_ ((Display *, char *)); 366 static SIGTYPE x_connection_closed P_ ((Display *, char *));
366 367
367 368
6881 Only get real positions and check fullscreen when mapped. */ 6882 Only get real positions and check fullscreen when mapped. */
6882 if (FRAME_GTK_OUTER_WIDGET (f) 6883 if (FRAME_GTK_OUTER_WIDGET (f)
6883 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f))) 6884 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
6884 #endif 6885 #endif
6885 { 6886 {
6886 /* What we have now is the position of Emacs's own window.
6887 Convert that to the position of the window manager window. */
6888 x_real_positions (f, &f->left_pos, &f->top_pos); 6887 x_real_positions (f, &f->left_pos, &f->top_pos);
6889 6888
6890 x_check_expected_move (f);
6891 if (f->want_fullscreen & FULLSCREEN_WAIT) 6889 if (f->want_fullscreen & FULLSCREEN_WAIT)
6892 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); 6890 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
6893 } 6891 }
6894 6892
6895 #ifdef HAVE_X_I18N 6893 #ifdef HAVE_X_I18N
8510 register int xoff, yoff; 8508 register int xoff, yoff;
8511 int change_gravity; 8509 int change_gravity;
8512 { 8510 {
8513 int modified_top, modified_left; 8511 int modified_top, modified_left;
8514 8512
8515 if (change_gravity > 0) 8513 if (change_gravity != 0)
8516 { 8514 {
8515 FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
8516 FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
8517
8517 f->top_pos = yoff; 8518 f->top_pos = yoff;
8518 f->left_pos = xoff; 8519 f->left_pos = xoff;
8519 f->size_hint_flags &= ~ (XNegative | YNegative); 8520 f->size_hint_flags &= ~ (XNegative | YNegative);
8520 if (xoff < 0) 8521 if (xoff < 0)
8521 f->size_hint_flags |= XNegative; 8522 f->size_hint_flags |= XNegative;
8529 x_wm_set_size_hint (f, (long) 0, 0); 8530 x_wm_set_size_hint (f, (long) 0, 0);
8530 8531
8531 modified_left = f->left_pos; 8532 modified_left = f->left_pos;
8532 modified_top = f->top_pos; 8533 modified_top = f->top_pos;
8533 8534
8534 if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A) 8535 if (change_gravity != 0 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
8535 { 8536 {
8536 /* Some WMs (twm, wmaker at least) has an offset that is smaller 8537 /* Some WMs (twm, wmaker at least) has an offset that is smaller
8537 than the WM decorations. So we use the calculated offset instead 8538 than the WM decorations. So we use the calculated offset instead
8538 of the WM decoration sizes here (x/y_pixels_outer_diff). */ 8539 of the WM decoration sizes here (x/y_pixels_outer_diff). */
8539 modified_left += FRAME_X_OUTPUT (f)->move_offset_left; 8540 modified_left += FRAME_X_OUTPUT (f)->move_offset_left;
8541 } 8542 }
8542 8543
8543 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 8544 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
8544 modified_left, modified_top); 8545 modified_left, modified_top);
8545 8546
8546 if (FRAME_VISIBLE_P (f) 8547 x_sync_with_move (f, f->left_pos, f->top_pos,
8547 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN) 8548 FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
8548 { 8549 ? 1 : 0);
8549 FRAME_X_OUTPUT (f)->check_expected_move = 1; 8550
8550 FRAME_X_OUTPUT (f)->expected_top = f->top_pos; 8551 /* change_gravity is non-zero when this function is called from Lisp to
8551 FRAME_X_OUTPUT (f)->expected_left = f->left_pos; 8552 programmatically move a frame. In that case, we call
8552 } 8553 x_check_expected_move to discover if we have a "Type A" or "Type B"
8554 window manager, and, for a "Type A" window manager, adjust the position
8555 of the frame.
8556
8557 We call x_check_expected_move if a programmatic move occurred, and
8558 either the window manager type (A/B) is unknown or it is Type A but we
8559 need to compute the top/left offset adjustment for this frame. */
8560
8561 if (change_gravity != 0 &&
8562 (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
8563 || (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
8564 && (FRAME_X_OUTPUT (f)->move_offset_left == 0
8565 && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
8566 x_check_expected_move (f, modified_left, modified_top);
8553 8567
8554 UNBLOCK_INPUT; 8568 UNBLOCK_INPUT;
8555 } 8569 }
8556 8570
8557 /* Check if we need to resize the frame due to a fullscreen request. 8571 /* Check if we need to resize the frame due to a fullscreen request.
8582 f->want_fullscreen |= FULLSCREEN_WAIT; 8596 f->want_fullscreen |= FULLSCREEN_WAIT;
8583 } 8597 }
8584 } 8598 }
8585 } 8599 }
8586 8600
8587 /* If frame parameters are set after the frame is mapped, we need to move 8601 /* This function is called by x_set_offset to determine whether the window
8588 the window. 8602 manager interfered with the positioning of the frame. Type A window
8589 Some window managers moves the window to the right position, some 8603 managers position the surrounding window manager decorations a small
8590 moves the outer window manager window to the specified position. 8604 amount above and left of the user-supplied position. Type B window
8591 Here we check that we are in the right spot. If not, make a second 8605 managers position the surrounding window manager decorations at the
8592 move, assuming we are dealing with the second kind of window manager. */ 8606 user-specified position. If we detect a Type A window manager, we
8607 compensate by moving the window right and down by the proper amount. */
8608
8593 static void 8609 static void
8594 x_check_expected_move (f) 8610 x_check_expected_move (f, expected_left, expected_top)
8595 struct frame *f; 8611 struct frame *f;
8596 { 8612 int expected_left;
8597 if (FRAME_X_OUTPUT (f)->check_expected_move) 8613 int expected_top;
8598 { 8614 {
8599 int expect_top = FRAME_X_OUTPUT (f)->expected_top; 8615 int count = 0, current_left = 0, current_top = 0;
8600 int expect_left = FRAME_X_OUTPUT (f)->expected_left; 8616
8601 8617 /* x_real_positions returns the left and top offsets of the outermost
8602 if (expect_top != f->top_pos || expect_left != f->left_pos) 8618 window manager window around the frame. */
8619
8620 x_real_positions (f, &current_left, &current_top);
8621
8622 if (current_left != expected_left || current_top != expected_top)
8603 { 8623 {
8624 /* It's a "Type A" window manager. */
8625
8626 int adjusted_left;
8627 int adjusted_top;
8628
8604 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A; 8629 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
8605 FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos; 8630 FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
8606 FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos; 8631 FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
8607 8632
8608 f->left_pos = expect_left; 8633 /* Now fix the mispositioned frame's location. */
8609 f->top_pos = expect_top; 8634
8610 x_set_offset (f, expect_left, expect_top, 0); 8635 adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
8636 adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
8637
8638 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
8639 adjusted_left, adjusted_top);
8640
8641 x_sync_with_move (f, expected_left, expected_top, 0);
8611 } 8642 }
8612 else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN) 8643 else
8644 /* It's a "Type B" window manager. We don't have to adjust the
8645 frame's position. */
8646
8613 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B; 8647 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
8614 8648 }
8615 /* Just do this once */ 8649
8616 FRAME_X_OUTPUT (f)->check_expected_move = 0; 8650
8651 /* Wait for XGetGeometry to return up-to-date position information for a
8652 recently-moved frame. Call this immediately after calling XMoveWindow.
8653 If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
8654 frame has been moved to, so we use a fuzzy position comparison instead
8655 of an exact comparison. */
8656
8657 static void
8658 x_sync_with_move (f, left, top, fuzzy)
8659 struct frame *f;
8660 int left, top, fuzzy;
8661 {
8662 int count = 0;
8663
8664 while (count++ < 50)
8665 {
8666 int current_left = 0, current_top = 0;
8667
8668 /* In theory, this call to XSync only needs to happen once, but in
8669 practice, it doesn't seem to work, hence the need for the surrounding
8670 loop. */
8671
8672 XSync (FRAME_X_DISPLAY (f), False);
8673 x_real_positions (f, &current_left, &current_top);
8674
8675 if (fuzzy)
8676 {
8677 /* The left fuzz-factor is 10 pixels. The top fuzz-factor is 40
8678 pixels. */
8679
8680 if (abs (current_left - left) <= 10 && abs (current_top - top) <= 40)
8681 return;
8617 } 8682 }
8683 else if (current_left == left && current_top == top)
8684 return;
8685 }
8686
8687 /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
8688 will then return up-to-date position info. */
8689
8690 wait_reading_process_output (0, 500000, 0, 0, Qnil, NULL, 0);
8618 } 8691 }
8619 8692
8620 8693
8621 /* Change the size of frame F's X window to COLS/ROWS in the case F 8694 /* Change the size of frame F's X window to COLS/ROWS in the case F
8622 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to 8695 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to