AutoHotkey Community

It is currently May 26th, 2012, 4:12 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: April 5th, 2005, 7:54 pm 
Offline

Joined: November 8th, 2004, 12:46 am
Posts: 1271
This script emulates the copy selected text to clipboard behaviour common to Linux. An optional paste with middle mouse button is included in the script. Unfortunately certain types of edit controls do not return the selected text with ControlGet. Feel free to tweak this - the mouse move detection routine isn't perfect.

Code:
SetKeyDelay, -1
CoordMode, Mouse, Screen

~LButton::

WinGetClass, class, A
MouseGetPos, mx, my, , control, 1
x1 = %mx%
y1 = %my%

loop
{
  GetKeyState, keystate, LButton
  if keystate = U
  {
    MouseGetPos, mx, my
    x2 = %mx%
    y2 = %my%
    break
  }
}

x := (x2 - x1)
y := (y2 - y1)

if (x >= 6)
  gosub, get
if (y >= 6)
  gosub, get
if (x <= -6)
  gosub, get
if (y <= -6)
  gosub, get
return

get:
ControlGet, text, Selected, , %control%, ahk_class %class%
if text !=
{
  clipboard = %text%

;--------------------------------
; remove this line if you prefer selected text to stay highlighted:
  controlsend, %control%, {left}{right}, ahk_class %class%
;--------------------------------

/*
  tooltip, you selected:`n%text%`nfrom: %class%`, %control%
  sleep, 1000
  tooltip
*/
  return
}
return

~Mbutton::
Send, %text%
return

_________________
"Anything worth doing is worth doing slowly." - Mae West
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2005, 6:53 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Nice idea, Serenity!

Very few controls tell if they have selected texts. Many more react to Ctrl-C, copying (any) selection to the clipboard directly. Here is another version of your script using Ctrl-C:
Code:
CoordMode Mouse, Screen

~LButton::
   MouseGetPos x0, y0            ; save start mouse position
   Loop
   {
     Sleep 20                    ; yield time to others
     GetKeyState keystate, LButton
     IfEqual keystate, U, {
       MouseGetPos x, y          ; position when button released
       break
     }
   }
   if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)
   {                             ; mouse has moved
      clip0 := ClipBoardAll      ; save old clipboard
      ClipBoard =
      Send ^c                    ; selection -> clipboard
      ClipWait 1, 1              ; restore clipboard if no data
      IfEqual ClipBoard,, SetEnv ClipBoard, %clip0%
   }
return


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 8th, 2005, 12:15 am 
Offline

Joined: November 8th, 2004, 12:46 am
Posts: 1271
Thanks Laszlo. :) Your version works much better with Ctrl+C, and I didn't know you could do expressions like this:

Code:
if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)


I get this error message from time to time although I am unsure what triggers it:

Quote:
Error: GetClipboardData

Line#
013: }
014: if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)
015: {
016: clip0 = ClipBoardAll
017: ClipBoard =
018: Send,^c
019: ClipWait,1,1
---> 020: if ClipBoard =
020: ClipBoard = %clip0%
021: }
022: Return
025: Send,^v
026: Return
027: Exit
028: Exit

_________________
"Anything worth doing is worth doing slowly." - Mae West
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 8th, 2005, 12:30 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Serenity wrote:
I get this error message from time to time although I am unsure what triggers it:

Quote:
Error: GetClipboardData
---> 020: if ClipBoard =
That happens when the internal call to GetClipboardData() fails to retrieve the plain text or list of copied files that resides on the clipboard. If you find out any more about the conditions that trigger this error, please let me know. Also, if anyone else gets this error, it would help to know the circumstances.

Thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 8th, 2005, 12:37 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
This GetClipboardData error is strange. I have not seen it in my Win2k laptop. (Everyone: please try to reproduce it!) Serenity, have you tried increasing the ClipWait time? Maybe your PC is slow and the clipboard was still busy when AHK wanted to check it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 8th, 2005, 1:13 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
It's a very unexpected error because at that stage, the clipboard is already opened and fully owned by the script. I've never heard of GetClipboardData() failing under these conditions, especially since it's called with CF_TEXT (plain text) or CF_HDROP (list of copied files), which are very mainstream.

However, I have seen GetClipboardData() fail for ClipboardAll, and for this reason ClipboardAll ignores the error and simply tries to get as much data as it can.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 8th, 2005, 4:16 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
...just thinkin...
Maybe the clipboard still changes after ClipWait saw data there, and accessing it causes errors. You could try
Code:
ClipWait 1, 1
clip2 := ClipBoard
IfEqual clip2,, SetEnv ClipBoard, %clip0%
If it does not help, we can try waiting until the clipboard does not change for a while.
Code:
   clip0 := ClipBoardAll      ; save old clipboard
   ClipBoard =
   Send ^c                    ; selection -> clipboard
   ClipWait 1, 1              ; wait for some data
   clip1 := ClipBoard         ; current state of clipboard
   Loop
   {
      Sleep 20
      clip2 := ClipBoard
      IfEqual clip1,%clip2%, break ; exit if no change for 20 ms
      clip1 := ClipBoard      ; current state of clipboard
   }


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 13th, 2005, 1:33 pm 
Offline

Joined: September 24th, 2004, 3:00 pm
Posts: 814
Location: Germany
Hi,

I can reproduce the Error with the following Hotkey:

Code:
#q::
   Send, ^c
   ClipWait, 0.5, 1
   msgbox %Clipboard%
Return

Now if I've opened an archive in WinRAR and no file is selected (clicking on white space) this hotkey gives me that error.

Tekl


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 13th, 2005, 2:43 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Thanks for the script; it produces the same error for me.

The next update will contain the following change:
Fixed the Clipboard variable to avoid producing an error when a set of zero files was copied onto the clipboard. [thanks Serenity & Tekl]


Report this post
Top
 Profile  
Reply with quote  
PostPosted: April 16th, 2005, 10:16 pm 
Offline

Joined: April 16th, 2005, 10:06 pm
Posts: 1
I'm a newbie here but thought I'd add a couple cents...

couldn't the expression

if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)

be reduced to
if sqr((x-x0)^2+(y-y0)^2) > 5

and eliminate several logical OR's?

Sorry ... so new .. I'm not even sure if AHK has a square root function. LOL

Thanks to all for sharing code. Looking forward to learning this.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2005, 12:39 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Assuming you defined your own square root function, and replace ^ with ** (the power operator in AHK) it should work. (But it does not, because negative base is not allowed, and so the result is wrong.) In any case, your condition is different. The original one allows the mouse to move in a little square without the selection copied to the clipboard, you specify a circle. But it doesn't really matter.

If you care about fast execution, function calls, multiplications are usually slower than a series of comparisons. Especially, with short circuits (not calculating further when the overall result becomes determined from a few conditions). Much depend on the compiler, though. Stupid compilation of conditionals might flush the processor pipeline unnecessarily, causing wait states.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: To put it all together
PostPosted: February 6th, 2008, 7:48 pm 
Offline

Joined: February 6th, 2008, 7:44 pm
Posts: 1
Code:
CoordMode Mouse, Screen

~LButton::
   MouseGetPos x0, y0            ; save start mouse position
   Loop
   {
     Sleep 20                    ; yield time to others
     GetKeyState keystate, LButton
     IfEqual keystate, U, {
       MouseGetPos x, y          ; position when button released
       break
     }
   }
   if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)
   {                             ; mouse has moved
      clip0 := ClipBoardAll      ; save old clipboard
      ClipBoard =
      Send ^c                    ; selection -> clipboard
      ClipWait 1, 1              ; restore clipboard if no data
      IfEqual ClipBoard,, SetEnv ClipBoard, %clip0%
   }
return

~Mbutton::
Send, ^v                    ;Paste via middle mouse click
return

On an even cooler note, I pasted the code above using this script!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 7th, 2008, 1:40 am 
Offline

Joined: February 7th, 2008, 1:36 am
Posts: 1
Utch: great script. But when I select text by double-clicking, it doesn't work the same way as when I select by click-and-drag. Any way to fix that?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 7th, 2008, 2:05 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
JazzSinger wrote:
great script
Thx
JazzSinger wrote:
when I select text by double-clicking, it doesn't work the same way as when I select by click-and-drag
It was discussed a few times in the Forum. Windows handles the mouse differently, so there is no perfect Linux emulation possible. What you need is to detect when a new selection is made, but it is application dependent. Often double clicks select words, triple clicks select sentences or lines, quadruple clicks select paragraphs… In other applications triple clicks deselect the last selected words, so you don’t know if a click selected something new by just monitoring the mouse. Also, if you drag something around it may stay selected, or may not.

A possible solution could be to send Ctrl-C always when the mouse button is released. If the clipboard becomes empty, restore its previous content. However, at dragging you might not want to change the clipboard, but the script cannot tell. There are speed and memory problems, too. If you select many directories to drag somewhere, Ctrl-C might need a lot of time to update the clipboard. During the wait time the system may look frozen.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 26th, 2008, 11:52 pm 
Offline

Joined: February 25th, 2008, 4:13 pm
Posts: 37
I took a couple of scripts and pieced them together that seems to handle the double click. Here's the code:
Code:
CoordMode Mouse, Screen

~LButton::
If A_PriorHotkey = %A_ThisHotkey%
{
   If A_TimeSincePriorHotkey < 300 ; 300 ms to double click, adjust if needed
   {
      clip0 := ClipBoardAll      ; save old clipboard
      ClipBoard =
      Send ^c                    ; selection -> clipboard
      ClipWait 1, 1              ; restore clipboard if no data
      IfEqual ClipBoard,, SetEnv ClipBoard, %clip0%
   }
   else
   {
      MouseGetPos x0, y0            ; save start mouse position
      Loop
      {
        Sleep 20                    ; yield time to others
        GetKeyState keystate, LButton
        IfEqual keystate, U, {
          MouseGetPos x, y          ; position when button released
          break
        }
         }
      if (x-x0 > 5 or x-x0 < -5 or y-y0 > 5 or y-y0 < -5)
      {                             ; mouse has moved
         clip0 := ClipBoardAll      ; save old clipboard
         ClipBoard =
         Send ^c                    ; selection -> clipboard
         ClipWait 1, 1              ; restore clipboard if no data
         IfEqual ClipBoard,, SetEnv ClipBoard, %clip0%
      }
      return
   }
}

~Mbutton::
Send, ^v                    ;Paste via middle mouse click
return


I've found that I sometimes highlight the text I'm going to paste over though, which, in this case, replaces what's on the clipboard already. :) I don't know how Linux handles that, but it's something to get used to if you decided to use a script like this.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 20 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group