OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 | 8 |
9 #include "base/event_types.h" | 9 #include "base/event_types.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "ui/aura/window.h" | 12 #include "ui/aura/window.h" |
13 #include "ui/aura/window_tree_host.h" | 13 #include "ui/aura/window_tree_host.h" |
14 #include "ui/base/clipboard/clipboard.h" | 14 #include "ui/base/clipboard/clipboard.h" |
15 #include "ui/base/dragdrop/drop_target_event.h" | 15 #include "ui/base/dragdrop/drop_target_event.h" |
16 #include "ui/base/dragdrop/os_exchange_data.h" | 16 #include "ui/base/dragdrop/os_exchange_data.h" |
17 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" | 17 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" |
18 #include "ui/base/x/selection_utils.h" | 18 #include "ui/base/x/selection_utils.h" |
19 #include "ui/base/x/x11_foreign_window_manager.h" | 19 #include "ui/base/x/x11_foreign_window_manager.h" |
20 #include "ui/base/x/x11_util.h" | 20 #include "ui/base/x/x11_util.h" |
21 #include "ui/events/event.h" | 21 #include "ui/events/event.h" |
22 #include "ui/events/platform/platform_event_source.h" | 22 #include "ui/events/platform/platform_event_source.h" |
23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" | 23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" |
24 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" | 24 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" |
| 25 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h" |
25 #include "ui/wm/public/drag_drop_client.h" | 26 #include "ui/wm/public/drag_drop_client.h" |
26 #include "ui/wm/public/drag_drop_delegate.h" | 27 #include "ui/wm/public/drag_drop_delegate.h" |
27 | 28 |
28 using aura::client::DragDropDelegate; | 29 using aura::client::DragDropDelegate; |
29 using ui::OSExchangeData; | 30 using ui::OSExchangeData; |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 const int kMinXdndVersion = 5; | 34 const int kMinXdndVersion = 5; |
34 | 35 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 return ui::POST_DISPATCH_NONE; | 355 return ui::POST_DISPATCH_NONE; |
355 } | 356 } |
356 | 357 |
357 /////////////////////////////////////////////////////////////////////////////// | 358 /////////////////////////////////////////////////////////////////////////////// |
358 | 359 |
359 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11( | 360 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11( |
360 aura::Window* root_window, | 361 aura::Window* root_window, |
361 views::DesktopNativeCursorManager* cursor_manager, | 362 views::DesktopNativeCursorManager* cursor_manager, |
362 Display* xdisplay, | 363 Display* xdisplay, |
363 ::Window xwindow) | 364 ::Window xwindow) |
364 : move_loop_(this), | 365 : root_window_(root_window), |
365 root_window_(root_window), | |
366 xdisplay_(xdisplay), | 366 xdisplay_(xdisplay), |
367 xwindow_(xwindow), | 367 xwindow_(xwindow), |
368 atom_cache_(xdisplay_, kAtomsToCache), | 368 atom_cache_(xdisplay_, kAtomsToCache), |
369 target_window_(NULL), | 369 target_window_(NULL), |
370 waiting_on_status_(false), | 370 waiting_on_status_(false), |
371 status_received_since_enter_(false), | 371 status_received_since_enter_(false), |
372 source_provider_(NULL), | 372 source_provider_(NULL), |
373 source_current_window_(None), | 373 source_current_window_(None), |
374 source_state_(SOURCE_STATE_OTHER), | 374 source_state_(SOURCE_STATE_OTHER), |
375 drag_operation_(0), | 375 drag_operation_(0), |
(...skipping 24 matching lines...) Expand all Loading... |
400 // static | 400 // static |
401 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow( | 401 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow( |
402 ::Window window) { | 402 ::Window window) { |
403 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it = | 403 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it = |
404 g_live_client_map.Get().find(window); | 404 g_live_client_map.Get().find(window); |
405 if (it == g_live_client_map.Get().end()) | 405 if (it == g_live_client_map.Get().end()) |
406 return NULL; | 406 return NULL; |
407 return it->second; | 407 return it->second; |
408 } | 408 } |
409 | 409 |
| 410 void DesktopDragDropClientAuraX11::Init() { |
| 411 move_loop_ = CreateMoveLoop(this); |
| 412 } |
| 413 |
410 void DesktopDragDropClientAuraX11::OnXdndEnter( | 414 void DesktopDragDropClientAuraX11::OnXdndEnter( |
411 const XClientMessageEvent& event) { | 415 const XClientMessageEvent& event) { |
412 DVLOG(1) << "XdndEnter"; | 416 DVLOG(1) << "XdndEnter"; |
413 | 417 |
414 int version = (event.data.l[1] & 0xff000000) >> 24; | 418 int version = (event.data.l[1] & 0xff000000) >> 24; |
415 if (version < 3) { | 419 if (version < 3) { |
416 LOG(ERROR) << "Received old XdndEnter message."; | 420 LOG(ERROR) << "Received old XdndEnter message."; |
417 return; | 421 return; |
418 } | 422 } |
419 | 423 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 if (event.data.l[1] & 1) { | 480 if (event.data.l[1] & 1) { |
477 ::Atom atom_operation = event.data.l[4]; | 481 ::Atom atom_operation = event.data.l[4]; |
478 negotiated_operation_ = AtomToDragOperation(atom_operation); | 482 negotiated_operation_ = AtomToDragOperation(atom_operation); |
479 } else { | 483 } else { |
480 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; | 484 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; |
481 } | 485 } |
482 | 486 |
483 if (source_state_ == SOURCE_STATE_PENDING_DROP) { | 487 if (source_state_ == SOURCE_STATE_PENDING_DROP) { |
484 // We were waiting on the status message so we could send the XdndDrop. | 488 // We were waiting on the status message so we could send the XdndDrop. |
485 if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) { | 489 if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) { |
486 move_loop_.EndMoveLoop(); | 490 move_loop_->EndMoveLoop(); |
487 return; | 491 return; |
488 } | 492 } |
489 source_state_ = SOURCE_STATE_DROPPED; | 493 source_state_ = SOURCE_STATE_DROPPED; |
490 SendXdndDrop(source_window); | 494 SendXdndDrop(source_window); |
491 return; | 495 return; |
492 } | 496 } |
493 | 497 |
494 switch (negotiated_operation_) { | 498 switch (negotiated_operation_) { |
495 case ui::DragDropTypes::DRAG_COPY: | 499 case ui::DragDropTypes::DRAG_COPY: |
496 move_loop_.UpdateCursor(copy_grab_cursor_); | 500 move_loop_->UpdateCursor(copy_grab_cursor_); |
497 break; | 501 break; |
498 case ui::DragDropTypes::DRAG_MOVE: | 502 case ui::DragDropTypes::DRAG_MOVE: |
499 move_loop_.UpdateCursor(move_grab_cursor_); | 503 move_loop_->UpdateCursor(move_grab_cursor_); |
500 break; | 504 break; |
501 default: | 505 default: |
502 move_loop_.UpdateCursor(grab_cursor_); | 506 move_loop_->UpdateCursor(grab_cursor_); |
503 break; | 507 break; |
504 } | 508 } |
505 | 509 |
506 // Note: event.data.[2,3] specify a rectangle. It is a request by the other | 510 // Note: event.data.[2,3] specify a rectangle. It is a request by the other |
507 // window to not send further XdndPosition messages while the cursor is | 511 // window to not send further XdndPosition messages while the cursor is |
508 // within it. However, it is considered advisory and (at least according to | 512 // within it. However, it is considered advisory and (at least according to |
509 // the spec) the other side must handle further position messages within | 513 // the spec) the other side must handle further position messages within |
510 // it. GTK+ doesn't bother with this, so neither should we. | 514 // it. GTK+ doesn't bother with this, so neither should we. |
511 | 515 |
512 if (next_position_message_.get()) { | 516 if (next_position_message_.get()) { |
(...skipping 14 matching lines...) Expand all Loading... |
527 if (source_current_window_ != source_window) | 531 if (source_current_window_ != source_window) |
528 return; | 532 return; |
529 | 533 |
530 // Clear |negotiated_operation_| if the drag was rejected. | 534 // Clear |negotiated_operation_| if the drag was rejected. |
531 if ((event.data.l[1] & 1) == 0) | 535 if ((event.data.l[1] & 1) == 0) |
532 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; | 536 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; |
533 | 537 |
534 // Clear |source_current_window_| to avoid sending XdndLeave upon ending the | 538 // Clear |source_current_window_| to avoid sending XdndLeave upon ending the |
535 // move loop. | 539 // move loop. |
536 source_current_window_ = None; | 540 source_current_window_ = None; |
537 move_loop_.EndMoveLoop(); | 541 move_loop_->EndMoveLoop(); |
538 } | 542 } |
539 | 543 |
540 void DesktopDragDropClientAuraX11::OnXdndDrop( | 544 void DesktopDragDropClientAuraX11::OnXdndDrop( |
541 const XClientMessageEvent& event) { | 545 const XClientMessageEvent& event) { |
542 DVLOG(1) << "XdndDrop"; | 546 DVLOG(1) << "XdndDrop"; |
543 | 547 |
544 unsigned long source_window = event.data.l[0]; | 548 unsigned long source_window = event.data.l[0]; |
545 | 549 |
546 int drag_operation = ui::DragDropTypes::DRAG_NONE; | 550 int drag_operation = ui::DragDropTypes::DRAG_NONE; |
547 if (target_window_) { | 551 if (target_window_) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 624 |
621 // It is possible for the DesktopWindowTreeHostX11 to be destroyed during the | 625 // It is possible for the DesktopWindowTreeHostX11 to be destroyed during the |
622 // move loop, which would also destroy this drag-client. So keep track of | 626 // move loop, which would also destroy this drag-client. So keep track of |
623 // whether it is alive after the drag ends. | 627 // whether it is alive after the drag ends. |
624 base::WeakPtr<DesktopDragDropClientAuraX11> alive( | 628 base::WeakPtr<DesktopDragDropClientAuraX11> alive( |
625 weak_ptr_factory_.GetWeakPtr()); | 629 weak_ptr_factory_.GetWeakPtr()); |
626 | 630 |
627 // Windows has a specific method, DoDragDrop(), which performs the entire | 631 // Windows has a specific method, DoDragDrop(), which performs the entire |
628 // drag. We have to emulate this, so we spin off a nested runloop which will | 632 // drag. We have to emulate this, so we spin off a nested runloop which will |
629 // track all cursor movement and reroute events to a specific handler. | 633 // track all cursor movement and reroute events to a specific handler. |
630 move_loop_.SetDragImage(source_provider_->GetDragImage(), | 634 move_loop_->SetDragImage(source_provider_->GetDragImage(), |
631 source_provider_->GetDragImageOffset()); | 635 source_provider_->GetDragImageOffset()); |
632 move_loop_.RunMoveLoop(source_window, grab_cursor_); | 636 move_loop_->RunMoveLoop(source_window, grab_cursor_); |
633 | 637 |
634 if (alive) { | 638 if (alive) { |
635 move_loop_.SetDragImage(gfx::ImageSkia(), gfx::Vector2dF()); | 639 move_loop_->SetDragImage(gfx::ImageSkia(), gfx::Vector2dF()); |
636 | 640 |
637 source_provider_ = NULL; | 641 source_provider_ = NULL; |
638 g_current_drag_drop_client = NULL; | 642 g_current_drag_drop_client = NULL; |
639 drag_operation_ = 0; | 643 drag_operation_ = 0; |
640 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndActionList")); | 644 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndActionList")); |
641 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom(kXdndDirectSave0)); | 645 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom(kXdndDirectSave0)); |
642 | 646 |
643 return negotiated_operation_; | 647 return negotiated_operation_; |
644 } | 648 } |
645 return ui::DragDropTypes::DRAG_NONE; | 649 return ui::DragDropTypes::DRAG_NONE; |
646 } | 650 } |
647 | 651 |
648 void DesktopDragDropClientAuraX11::DragUpdate(aura::Window* target, | 652 void DesktopDragDropClientAuraX11::DragUpdate(aura::Window* target, |
649 const ui::LocatedEvent& event) { | 653 const ui::LocatedEvent& event) { |
650 NOTIMPLEMENTED(); | 654 NOTIMPLEMENTED(); |
651 } | 655 } |
652 | 656 |
653 void DesktopDragDropClientAuraX11::Drop(aura::Window* target, | 657 void DesktopDragDropClientAuraX11::Drop(aura::Window* target, |
654 const ui::LocatedEvent& event) { | 658 const ui::LocatedEvent& event) { |
655 NOTIMPLEMENTED(); | 659 NOTIMPLEMENTED(); |
656 } | 660 } |
657 | 661 |
658 void DesktopDragDropClientAuraX11::DragCancel() { | 662 void DesktopDragDropClientAuraX11::DragCancel() { |
659 move_loop_.EndMoveLoop(); | 663 move_loop_->EndMoveLoop(); |
660 } | 664 } |
661 | 665 |
662 bool DesktopDragDropClientAuraX11::IsDragDropInProgress() { | 666 bool DesktopDragDropClientAuraX11::IsDragDropInProgress() { |
663 return !!g_current_drag_drop_client; | 667 return !!g_current_drag_drop_client; |
664 } | 668 } |
665 | 669 |
666 void DesktopDragDropClientAuraX11::OnWindowDestroyed(aura::Window* window) { | 670 void DesktopDragDropClientAuraX11::OnWindowDestroyed(aura::Window* window) { |
667 DCHECK_EQ(target_window_, window); | 671 DCHECK_EQ(target_window_, window); |
668 target_window_ = NULL; | 672 target_window_ = NULL; |
669 } | 673 } |
670 | 674 |
671 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { | 675 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { |
672 repeat_mouse_move_timer_.Stop(); | 676 repeat_mouse_move_timer_.Stop(); |
673 ProcessMouseMove(gfx::Point(event->x_root, event->y_root), event->time); | 677 ProcessMouseMove(gfx::Point(event->x_root, event->y_root), event->time); |
674 } | 678 } |
675 | 679 |
676 void DesktopDragDropClientAuraX11::OnMouseReleased() { | 680 void DesktopDragDropClientAuraX11::OnMouseReleased() { |
677 repeat_mouse_move_timer_.Stop(); | 681 repeat_mouse_move_timer_.Stop(); |
678 | 682 |
679 if (source_state_ != SOURCE_STATE_OTHER) { | 683 if (source_state_ != SOURCE_STATE_OTHER) { |
680 // The user has previously released the mouse and is clicking in | 684 // The user has previously released the mouse and is clicking in |
681 // frustration. | 685 // frustration. |
682 move_loop_.EndMoveLoop(); | 686 move_loop_->EndMoveLoop(); |
683 return; | 687 return; |
684 } | 688 } |
685 | 689 |
686 if (source_current_window_ != None) { | 690 if (source_current_window_ != None) { |
687 if (waiting_on_status_) { | 691 if (waiting_on_status_) { |
688 if (status_received_since_enter_) { | 692 if (status_received_since_enter_) { |
689 // If we are waiting for an XdndStatus message, we need to wait for it | 693 // If we are waiting for an XdndStatus message, we need to wait for it |
690 // to complete. | 694 // to complete. |
691 source_state_ = SOURCE_STATE_PENDING_DROP; | 695 source_state_ = SOURCE_STATE_PENDING_DROP; |
692 | 696 |
693 // Start timer to end the move loop if the target takes too long to send | 697 // Start timer to end the move loop if the target takes too long to send |
694 // the XdndStatus and XdndFinished messages. | 698 // the XdndStatus and XdndFinished messages. |
695 StartEndMoveLoopTimer(); | 699 StartEndMoveLoopTimer(); |
696 return; | 700 return; |
697 } | 701 } |
698 | 702 |
699 move_loop_.EndMoveLoop(); | 703 move_loop_->EndMoveLoop(); |
700 return; | 704 return; |
701 } | 705 } |
702 | 706 |
703 if (negotiated_operation_ != ui::DragDropTypes::DRAG_NONE) { | 707 if (negotiated_operation_ != ui::DragDropTypes::DRAG_NONE) { |
704 // Start timer to end the move loop if the target takes too long to send | 708 // Start timer to end the move loop if the target takes too long to send |
705 // an XdndFinished message. It is important that StartEndMoveLoopTimer() | 709 // an XdndFinished message. It is important that StartEndMoveLoopTimer() |
706 // is called before SendXdndDrop() because SendXdndDrop() | 710 // is called before SendXdndDrop() because SendXdndDrop() |
707 // sends XdndFinished synchronously if the drop target is a Chrome | 711 // sends XdndFinished synchronously if the drop target is a Chrome |
708 // window. | 712 // window. |
709 StartEndMoveLoopTimer(); | 713 StartEndMoveLoopTimer(); |
710 | 714 |
711 // We have negotiated an action with the other end. | 715 // We have negotiated an action with the other end. |
712 source_state_ = SOURCE_STATE_DROPPED; | 716 source_state_ = SOURCE_STATE_DROPPED; |
713 SendXdndDrop(source_current_window_); | 717 SendXdndDrop(source_current_window_); |
714 return; | 718 return; |
715 } | 719 } |
716 } | 720 } |
717 | 721 |
718 move_loop_.EndMoveLoop(); | 722 move_loop_->EndMoveLoop(); |
719 } | 723 } |
720 | 724 |
721 void DesktopDragDropClientAuraX11::OnMoveLoopEnded() { | 725 void DesktopDragDropClientAuraX11::OnMoveLoopEnded() { |
722 if (source_current_window_ != None) { | 726 if (source_current_window_ != None) { |
723 SendXdndLeave(source_current_window_); | 727 SendXdndLeave(source_current_window_); |
724 source_current_window_ = None; | 728 source_current_window_ = None; |
725 } | 729 } |
726 target_current_context_.reset(); | 730 target_current_context_.reset(); |
727 repeat_mouse_move_timer_.Stop(); | 731 repeat_mouse_move_timer_.Stop(); |
728 end_move_loop_timer_.Stop(); | 732 end_move_loop_timer_.Stop(); |
729 } | 733 } |
730 | 734 |
| 735 scoped_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop( |
| 736 X11MoveLoopDelegate* delegate) { |
| 737 return scoped_ptr<X11MoveLoop>(new X11WholeScreenMoveLoop(this)); |
| 738 } |
| 739 |
731 XID DesktopDragDropClientAuraX11::FindWindowFor( | 740 XID DesktopDragDropClientAuraX11::FindWindowFor( |
732 const gfx::Point& screen_point) { | 741 const gfx::Point& screen_point) { |
733 views::X11TopmostWindowFinder finder; | 742 views::X11TopmostWindowFinder finder; |
734 ::Window target = finder.FindWindowAt(screen_point); | 743 ::Window target = finder.FindWindowAt(screen_point); |
735 | 744 |
736 if (target == None) | 745 if (target == None) |
737 return None; | 746 return None; |
738 | 747 |
739 // Figure out which window we should test as XdndAware. If |target| has | 748 // Figure out which window we should test as XdndAware. If |target| has |
740 // XdndProxy, it will set that proxy on target, and if not, |target|'s | 749 // XdndProxy, it will set that proxy on target, and if not, |target|'s |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 | 834 |
826 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() { | 835 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() { |
827 end_move_loop_timer_.Start(FROM_HERE, | 836 end_move_loop_timer_.Start(FROM_HERE, |
828 base::TimeDelta::FromMilliseconds( | 837 base::TimeDelta::FromMilliseconds( |
829 kEndMoveLoopTimeoutMs), | 838 kEndMoveLoopTimeoutMs), |
830 this, | 839 this, |
831 &DesktopDragDropClientAuraX11::EndMoveLoop); | 840 &DesktopDragDropClientAuraX11::EndMoveLoop); |
832 } | 841 } |
833 | 842 |
834 void DesktopDragDropClientAuraX11::EndMoveLoop() { | 843 void DesktopDragDropClientAuraX11::EndMoveLoop() { |
835 move_loop_.EndMoveLoop(); | 844 move_loop_->EndMoveLoop(); |
836 } | 845 } |
837 | 846 |
838 void DesktopDragDropClientAuraX11::DragTranslate( | 847 void DesktopDragDropClientAuraX11::DragTranslate( |
839 const gfx::Point& root_window_location, | 848 const gfx::Point& root_window_location, |
840 scoped_ptr<ui::OSExchangeData>* data, | 849 scoped_ptr<ui::OSExchangeData>* data, |
841 scoped_ptr<ui::DropTargetEvent>* event, | 850 scoped_ptr<ui::DropTargetEvent>* event, |
842 aura::client::DragDropDelegate** delegate) { | 851 aura::client::DragDropDelegate** delegate) { |
843 gfx::Point root_location = root_window_location; | 852 gfx::Point root_location = root_window_location; |
844 root_window_->GetHost()->ConvertPointFromNativeScreen(&root_location); | 853 root_window_->GetHost()->ConvertPointFromNativeScreen(&root_location); |
845 aura::Window* target_window = | 854 aura::Window* target_window = |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 xev.xclient.window = dest_window; | 1048 xev.xclient.window = dest_window; |
1040 xev.xclient.data.l[0] = xwindow_; | 1049 xev.xclient.data.l[0] = xwindow_; |
1041 xev.xclient.data.l[1] = 0; | 1050 xev.xclient.data.l[1] = 0; |
1042 xev.xclient.data.l[2] = CurrentTime; | 1051 xev.xclient.data.l[2] = CurrentTime; |
1043 xev.xclient.data.l[3] = None; | 1052 xev.xclient.data.l[3] = None; |
1044 xev.xclient.data.l[4] = None; | 1053 xev.xclient.data.l[4] = None; |
1045 SendXClientEvent(dest_window, &xev); | 1054 SendXClientEvent(dest_window, &xev); |
1046 } | 1055 } |
1047 | 1056 |
1048 } // namespace views | 1057 } // namespace views |
OLD | NEW |