Mercurial > emacs
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, ¤t_left, ¤t_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, ¤t_left, ¤t_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 |