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