psychopy 2024.2.1__py3-none-any.whl → 2024.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of psychopy might be problematic. Click here for more details.

Files changed (276) hide show
  1. psychopy/.DS_Store +0 -0
  2. psychopy/GIT_SHA +1 -1
  3. psychopy/VERSION +1 -1
  4. psychopy/__init__.py +10 -1
  5. psychopy/__init__.py.orig +65 -0
  6. psychopy/app/{locale/ar_001/.DS_Store → .DS_Store} +0 -0
  7. psychopy/app/Resources/.DS_Store +0 -0
  8. psychopy/app/_psychopyApp.py +11 -3
  9. psychopy/app/appData.spec +1 -1
  10. psychopy/app/builder/builder.py +1 -1
  11. psychopy/app/builder/builder.py.orig +3932 -0
  12. psychopy/app/builder/dialogs/__init__.py.orig +1679 -0
  13. psychopy/app/builder/dialogs/paramCtrls.py +1 -1
  14. psychopy/app/builder/dialogs/paramCtrls.py.orig +713 -0
  15. psychopy/app/colorpicker/__init__.py.orig +411 -0
  16. psychopy/app/cortex.log +0 -0
  17. psychopy/app/jobs.py +8 -1
  18. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +2452 -1731
  19. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.mo +0 -0
  20. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.po +6127 -0
  21. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.mo +0 -0
  22. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.po +7366 -0
  23. psychopy/app/plugin_manager/dialog.py +9 -7
  24. psychopy/app/ribbon.py +2 -1
  25. psychopy/app/runner/runner.py +7 -5
  26. psychopy/clock.py +8 -4
  27. psychopy/core.py.orig +169 -0
  28. psychopy/demos/builder/Design Templates/randomisedBlocks/html/index.html +23 -0
  29. psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks-legacy-browsers.js +423 -0
  30. psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks.js +427 -0
  31. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/chooseBlock.xlsx +0 -0
  32. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/facesBlock.xlsx +0 -0
  33. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/housesBlock.xlsx +0 -0
  34. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face01.jpg +0 -0
  35. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face02.jpg +0 -0
  36. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face03.jpg +0 -0
  37. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house01.jpg +0 -0
  38. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house02.jpg +0 -0
  39. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house03.jpg +0 -0
  40. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.py +330 -0
  41. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +330 -0
  42. psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xml +298 -0
  43. psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xsd +120 -0
  44. psychopy/demos/builder/Tools/.DS_Store +0 -0
  45. psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
  46. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +38 -0
  47. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +3418 -0
  48. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
  49. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +2 -0
  50. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +15 -0
  51. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
  52. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.psyexp +323 -0
  53. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.py +562 -0
  54. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +562 -0
  55. psychopy/demos/builder/Tools/gammaCalibration/questStairs.xlsx +0 -0
  56. psychopy/demos/builder/Tools/gammaCalibration/readme.md +0 -0
  57. psychopy/demos/builder/Tools/gammaCalibration/resources/low_contrast.png +0 -0
  58. psychopy/demos/builder/Tools/gammaCalibration/resources/make_2nd_order_tex.py +59 -0
  59. psychopy/demos/builder/Tools/gammaCalibration/resources/second_order_tex.png +0 -0
  60. psychopy/demos/coder/.DS_Store +0 -0
  61. psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
  62. psychopy/demos/coder/iohub/.iohpid +1 -0
  63. psychopy/demos/coder/iohub/eyetracking/.iohpid +1 -0
  64. psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
  65. psychopy/demos/coder/stimuli/.DS_Store +0 -0
  66. psychopy/demos/coder/stimuli/radialGratingContracting.py +29 -0
  67. psychopy/experiment/_experiment.py.orig +1032 -0
  68. psychopy/experiment/components/.DS_Store +0 -0
  69. psychopy/experiment/components/_base.py +13 -4
  70. psychopy/experiment/components/_base.py.orig +823 -0
  71. psychopy/experiment/components/form/.DS_Store +0 -0
  72. psychopy/experiment/components/microphone/__init__.py +10 -1
  73. psychopy/experiment/components/microphone/__init__.py.orig +490 -0
  74. psychopy/experiment/components/polygon/__init__.py +21 -22
  75. psychopy/experiment/components/settings/__init__.py +13 -14
  76. psychopy/experiment/components/settings/__init__.py.orig +1337 -0
  77. psychopy/experiment/components/textbox/__init__.py.orig +310 -0
  78. psychopy/experiment/components/webcam/.DS_Store +0 -0
  79. psychopy/experiment/components/webcam/light/.DS_Store +0 -0
  80. psychopy/experiment/flow.py +10 -8
  81. psychopy/experiment/loops.py.orig +829 -0
  82. psychopy/experiment/params.py +8 -3
  83. psychopy/experiment/params.py.orig +408 -0
  84. psychopy/experiment/routine.py.orig +503 -0
  85. psychopy/experiment/routines/_base.py +15 -6
  86. psychopy/experiment/routines/counterbalance/__init__.py +1 -0
  87. psychopy/gui/qtgui.py +14 -7
  88. psychopy/gui/util.py +10 -14
  89. psychopy/gui/wxgui.py +10 -4
  90. psychopy/hardware/.DS_Store +0 -0
  91. psychopy/hardware/brainproducts.py.orig +680 -0
  92. psychopy/hardware/iolab.py.orig +238 -0
  93. psychopy/hardware/manager.py +1 -1
  94. psychopy/hardware/photodiode.py +59 -27
  95. psychopy/hardware/serialport.py +51 -0
  96. psychopy/hardware/speaker.py +4 -4
  97. psychopy/iohub/datastore/__init__.py.orig +443 -0
  98. psychopy/iohub/datastore/util.py.orig +692 -0
  99. psychopy/iohub/devices/mouse/darwin.py.orig +427 -0
  100. psychopy/iohub/devices/mouse/linux2.py.orig +198 -0
  101. psychopy/preferences/.DS_Store +0 -0
  102. psychopy/projects/pavlovia.py +10 -3
  103. psychopy/projects/pavlovia.py.orig +1295 -0
  104. psychopy/sound/backend_ptb.py +22 -5
  105. psychopy/sound/transcribe.py +24 -4
  106. psychopy/tests/.DS_Store +0 -0
  107. psychopy/tests/data/.DS_Store +0 -0
  108. psychopy/tests/data/TestCircle_fill_local.png +0 -0
  109. psychopy/tests/data/__test.png +0 -0
  110. psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
  111. psychopy/tests/data/aperture1_norm_local.png +0 -0
  112. psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
  113. psychopy/tests/data/beatandrcos_height_local.png +0 -0
  114. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  115. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  116. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  117. psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
  118. psychopy/tests/data/blend_add_height_local.png +0 -0
  119. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  120. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  121. psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
  122. psychopy/tests/data/blend_add_norm_local.png +0 -0
  123. psychopy/tests/data/blend_add_stencil_local.png +0 -0
  124. psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
  125. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  126. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  127. psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
  128. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  129. psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
  130. psychopy/tests/data/circleHex_height_local.png +0 -0
  131. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  132. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  133. psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
  134. psychopy/tests/data/circleHex_norm_local.png +0 -0
  135. psychopy/tests/data/circleHex_stencil_local.png +0 -0
  136. psychopy/tests/data/color_comparison_local.png +0 -0
  137. psychopy/tests/data/corrFullRandom_local.csv +16 -0
  138. psychopy/tests/data/corrFullRandom_local.tsv +6 -0
  139. psychopy/tests/data/correctScript/.DS_Store +0 -0
  140. psychopy/tests/data/dots_height_local.png +0 -0
  141. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  142. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  143. psychopy/tests/data/dots_normNoShade_local.png +0 -0
  144. psychopy/tests/data/dots_norm_local.png +0 -0
  145. psychopy/tests/data/dots_stencil_local.png +0 -0
  146. psychopy/tests/data/elarray1_height_local.png +0 -0
  147. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  148. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  149. psychopy/tests/data/elarray1_norm_local.png +0 -0
  150. psychopy/tests/data/elarray1_stencil_local.png +0 -0
  151. psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
  152. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  153. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  154. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  155. psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
  156. psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
  157. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  158. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  159. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  160. psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
  161. psychopy/tests/data/gabor1_height_local.png +0 -0
  162. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  163. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  164. psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
  165. psychopy/tests/data/gabor1_norm_local.png +0 -0
  166. psychopy/tests/data/gabor1_stencil_local.png +0 -0
  167. psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
  168. psychopy/tests/data/imageAndGauss_height_local.png +0 -0
  169. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  170. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  171. psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
  172. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  173. psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
  174. psychopy/tests/data/movFrame1_stencil_local.png +0 -0
  175. psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
  176. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  177. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  178. psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
  179. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  180. psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
  181. psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
  182. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  183. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  184. psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
  185. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  186. psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
  187. psychopy/tests/data/numpyImage_height_local.png +0 -0
  188. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  189. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  190. psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
  191. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  192. psychopy/tests/data/numpyImage_stencil_local.png +0 -0
  193. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  194. psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
  195. psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
  196. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  197. psychopy/tests/data/shape2_1_stencil_local.png +0 -0
  198. psychopy/tests/data/testLoopsBlocks.psyexp_local.py +328 -0
  199. psychopy/tests/data/text1_height_local.png +0 -0
  200. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  201. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  202. psychopy/tests/data/text1_norm_local.png +0 -0
  203. psychopy/tests/data/text1_stencil_local.png +0 -0
  204. psychopy/tests/data/text2_height.png +0 -0
  205. psychopy/tests/data/text2_normAddBlend.png +0 -0
  206. psychopy/tests/data/text2_normHexbackground.png +0 -0
  207. psychopy/tests/data/text2_stencil.png +0 -0
  208. psychopy/tests/data/wedge1_height_local.png +0 -0
  209. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  210. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  211. psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
  212. psychopy/tests/data/wedge1_norm_local.png +0 -0
  213. psychopy/tests/data/wedge1_stencil_local.png +0 -0
  214. psychopy/tests/test_app/.DS_Store +0 -0
  215. psychopy/tests/test_app/test_builder/.DS_Store +0 -0
  216. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.csv +9 -0
  217. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +177 -0
  218. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
  219. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
  220. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.csv +9 -0
  221. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +168 -0
  222. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
  223. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
  224. psychopy/tests/test_data/.DS_Store +0 -0
  225. psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +68 -0
  226. psychopy/tests/test_tools/test_arraytools.py +112 -0
  227. psychopy/tests/test_visual/test_image.py.orig +219 -0
  228. psychopy/tools/arraytools.py +47 -0
  229. psychopy/tools/versionchooser.py +1 -1
  230. psychopy/visual/backends/pygletbackend.py +26 -8
  231. psychopy/visual/basevisual.py.orig +1723 -0
  232. psychopy/visual/form.py.orig +1181 -0
  233. psychopy/visual/text.py.orig +752 -0
  234. psychopy/visual/textbox2/textbox2.py.orig +1315 -0
  235. psychopy/visual/window.py +13 -5
  236. psychopy/visual/windowwarp.py.orig +463 -0
  237. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/METADATA +9 -9
  238. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/RECORD +244 -78
  239. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/WHEEL +1 -1
  240. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/entry_points.txt +2 -0
  241. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  242. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  243. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  244. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  245. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  246. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  247. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  248. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  249. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  250. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  251. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  252. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  253. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  254. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  255. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  256. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  257. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  258. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  259. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  260. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  261. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  262. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  263. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  264. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  265. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  266. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  267. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  268. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  269. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  270. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  271. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  272. psychopy-2024.2.1.dist-info/licenses/AUTHORS.md +0 -138
  273. /psychopy/{app/locale/ar_001/LC_MESSAGE → demos/builder}/.DS_Store +0 -0
  274. /psychopy/{app/locale/es_ES/LC_MESSAGE → demos/builder/Experiments}/.DS_Store +0 -0
  275. /psychopy/{visual → demos/builder/Tools/gammaCalibration/data}/.DS_Store +0 -0
  276. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,427 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Part of the PsychoPy library
3
+ # Copyright (C) 2012-2020 iSolver Software Solutions (C) 2021 Open Science Tools Ltd.
4
+ # Distributed under the terms of the GNU General Public License (GPL).
5
+ from copy import copy
6
+ import Quartz as Qz
7
+ from AppKit import NSEvent
8
+
9
+ from . import MouseDevice
10
+ from .. import Keyboard, Computer, Device
11
+ from ...errors import print2err, printExceptionDetailsToStdErr
12
+ from ...constants import EventConstants, MouseConstants
13
+
14
+ currentSec = Computer.getTime
15
+
16
+ pressID = [
17
+ None,
18
+ Qz.kCGEventLeftMouseDown,
19
+ Qz.kCGEventRightMouseDown,
20
+ Qz.kCGEventOtherMouseDown]
21
+ releaseID = [
22
+ None,
23
+ Qz.kCGEventLeftMouseUp,
24
+ Qz.kCGEventRightMouseUp,
25
+ Qz.kCGEventOtherMouseUp]
26
+ dragID = [
27
+ None,
28
+ Qz.kCGEventLeftMouseDragged,
29
+ Qz.kCGEventRightMouseDragged,
30
+ Qz.kCGEventOtherMouseDragged]
31
+
32
+
33
+ class Mouse(MouseDevice):
34
+ """The Mouse class and related events represent a standard computer mouse
35
+ device and the events a standard mouse can produce.
36
+
37
+ Mouse position data is mapped to the coordinate space defined in the
38
+ ioHub configuration file for the Display.
39
+
40
+ Examples:
41
+
42
+ A. Print all mouse events received for 5 seconds::
43
+
44
+ from psychopy.iohub import launchHubServer
45
+ from psychopy.core import getTime
46
+
47
+ # Start the ioHub process. 'io' can now be used during the
48
+ # experiment to access iohub devices and read iohub device events.
49
+ io = launchHubServer()
50
+
51
+ mouse = io.devices.mouse
52
+
53
+ # Check for and print any Mouse events received for 5 seconds.
54
+ stime = getTime()
55
+ while getTime()-stime < 5.0:
56
+ for e in mouse.getEvents():
57
+ print(e)
58
+
59
+ # Stop the ioHub Server
60
+ io.quit()
61
+
62
+ B. Print current mouse position for 5 seconds::
63
+
64
+ from psychopy.iohub import launchHubServer
65
+ from psychopy.core import getTime
66
+
67
+ # Start the ioHub process. 'io' can now be used during the
68
+ # experiment to access iohub devices and read iohub device events.
69
+ io = launchHubServer()
70
+
71
+ mouse = io.devices.mouse
72
+
73
+ # Check for and print any Mouse events received for 5 seconds.
74
+ stime = getTime()
75
+ while getTime()-stime < 5.0:
76
+ print(mouse.getPosition())
77
+
78
+ # Stop the ioHub Server
79
+ io.quit()
80
+
81
+ """
82
+ __slots__ = ['_loop_source', '_tap', '_device_loop', '_CGEventTapEnable',
83
+ '_loop_mode', '_scrollPositionX']
84
+
85
+ _IOHUB_BUTTON_ID_MAPPINGS = {
86
+ Qz.kCGEventLeftMouseDown: MouseConstants.MOUSE_BUTTON_LEFT,
87
+ Qz.kCGEventRightMouseDown: MouseConstants.MOUSE_BUTTON_RIGHT,
88
+ Qz.kCGEventOtherMouseDown: MouseConstants.MOUSE_BUTTON_MIDDLE,
89
+ Qz.kCGEventLeftMouseUp: MouseConstants.MOUSE_BUTTON_LEFT,
90
+ Qz.kCGEventRightMouseUp: MouseConstants.MOUSE_BUTTON_RIGHT,
91
+ Qz.kCGEventOtherMouseUp: MouseConstants.MOUSE_BUTTON_MIDDLE
92
+ }
93
+
94
+ DEVICE_TIME_TO_SECONDS = 0.000000001
95
+
96
+ _EVENT_TEMPLATE_LIST = [0, # experiment id
97
+ 0, # session id
98
+ 0, # device id
99
+ 0, # Device._getNextEventID(),
100
+ 0, # ioHub Event type
101
+ 0.0, # event device time,
102
+ 0.0, # event logged_time,
103
+ 0.0, # event iohub Time,
104
+ 0.0, # confidence_interval,
105
+ 0.0, # delay,
106
+ 0, # filtered by ID (always 0 right now)
107
+ 0, # Display Index,
108
+ 0, # ioHub Button State,
109
+ 0, # ioHub Button ID,
110
+ 0, # Active Buttons,
111
+ 0.0, # x position of mouse in Display device coord's
112
+ 0.0, # y position of mouse in Display device coord's
113
+ 0, # Wheel dx
114
+ 0, # Wheel Absolute x
115
+ 0, # Wheel dy
116
+ 0, # Wheel Absolute y
117
+ 0, # modifiers
118
+ 0] # event.Window]
119
+
120
+ def __init__(self, *args, **kwargs):
121
+ MouseDevice.__init__(self, *args, **kwargs['dconfig'])
122
+
123
+ self._tap = Qz.CGEventTapCreate(
124
+ Qz.kCGSessionEventTap,
125
+ Qz.kCGHeadInsertEventTap,
126
+ Qz.kCGEventTapOptionDefault,
127
+ Qz.CGEventMaskBit(Qz.kCGEventMouseMoved) |
128
+ Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDown) |
129
+ Qz.CGEventMaskBit(Qz.kCGEventLeftMouseUp) |
130
+ Qz.CGEventMaskBit(Qz.kCGEventRightMouseDown) |
131
+ Qz.CGEventMaskBit(Qz.kCGEventRightMouseUp) |
132
+ Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDragged) |
133
+ Qz.CGEventMaskBit(Qz.kCGEventRightMouseDragged) |
134
+ Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDragged) |
135
+ Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDown) |
136
+ Qz.CGEventMaskBit(Qz.kCGEventScrollWheel) |
137
+ Qz.CGEventMaskBit(Qz.kCGEventOtherMouseUp),
138
+ self._nativeEventCallback,
139
+ None)
140
+
141
+ self._scrollPositionX = 0
142
+ self._CGEventTapEnable = Qz.CGEventTapEnable
143
+ self._loop_source = Qz.CFMachPortCreateRunLoopSource(
144
+ None, self._tap, 0)
145
+ self._device_loop = Qz.CFRunLoopGetCurrent()
146
+ self._loop_mode = Qz.kCFRunLoopDefaultMode
147
+
148
+ Qz.CFRunLoopAddSource(
149
+ self._device_loop,
150
+ self._loop_source,
151
+ self._loop_mode)
152
+
153
+
154
+ def _initialMousePos(self):
155
+ """If getPosition is called prior to any mouse events being received,
156
+ this method gets the current system cursor pos.
157
+ TODO: Implement OS X version
158
+ """
159
+ if self._position is None:
160
+ self._position = 0.0, 0.0
161
+ self._lastPosition = 0.0, 0.0
162
+
163
+ def _nativeSetMousePos(self, px, py):
164
+ result = Qz.CGWarpMouseCursorPosition(
165
+ Qz.CGPointMake(float(px), float(py)))
166
+ #print2err('_nativeSetMousePos result: ',result)
167
+
168
+ #def _nativeGetSystemCursorVisibility(self):
169
+ # return Qz.CGCursorIsVisible()
170
+ #
171
+ # def _nativeSetSystemCursorVisibility(self, v):
172
+ # if v and not Qz.CGCursorIsVisible():
173
+ # Qz.CGDisplayShowCursor(Qz.CGMainDisplayID())
174
+ # elif not v and Qz.CGCursorIsVisible():
175
+ # Qz.CGDisplayHideCursor(Qz.CGMainDisplayID())
176
+
177
+ #def _nativeLimitCursorToBoundingRect(self, clip_rect):
178
+ # print2err(
179
+ # 'WARNING: Mouse._nativeLimitCursorToBoundingRect not implemented on OSX yet.')
180
+ # native_clip_rect = None
181
+ # return native_clip_rect
182
+
183
+ def getScroll(self):
184
+ """
185
+ TODO: Update docs for OSX
186
+ Args: None
187
+ Returns
188
+ """
189
+ return self._scrollPositionX, self._scrollPositionY
190
+
191
+ def setScroll(self, sp):
192
+ """
193
+ TODO: Update docs for OSX
194
+ """
195
+ self._scrollPositionX, self._scrollPositionY = sp
196
+ return self._scrollPositionX, self._scrollPositionY
197
+
198
+ def _poll(self):
199
+ self._last_poll_time = currentSec()
200
+ while Qz.CFRunLoopRunInMode(self._loop_mode, 0.0, True) == Qz.kCFRunLoopRunHandledSource:
201
+ pass
202
+
203
+ def _nativeEventCallback(self, *args):
204
+ try:
205
+ proxy, etype, event, refcon = args
206
+ if self.isReportingEvents():
207
+ logged_time = currentSec()
208
+
209
+ if etype == Qz.kCGEventTapDisabledByTimeout:
210
+ print2err('** WARNING: Mouse Tap Disabled due to timeout. Re-enabling....: ', etype)
211
+ Qz.CGEventTapEnable(self._tap, True)
212
+ return event
213
+ else:
214
+ confidence_interval = 0.0
215
+ delay = 0.0
216
+ iohub_time = logged_time
217
+ device_time = Qz.CGEventGetTimestamp(event) * self.DEVICE_TIME_TO_SECONDS
218
+ ioe_type = EventConstants.UNDEFINED
219
+ px, py = Qz.CGEventGetLocation(event)
220
+ multi_click_count = Qz.CGEventGetIntegerValueField(event, Qz.kCGMouseEventClickState)
221
+ mouse_event = NSEvent.eventWithCGEvent_(event)
222
+
223
+ # TODO: window_handle seems to always be 0.
224
+ window_handle = mouse_event.windowNumber()
225
+
226
+ display_index = self.getDisplayIndexForMousePosition((px, py))
227
+ if display_index == -1:
228
+ if self._last_display_index is not None:
229
+ display_index = self._last_display_index
230
+ else:
231
+ # Do not report event to iohub if it does not map to a display
232
+ # ?? Can this ever actually happen ??
233
+ return event
234
+
235
+ <<<<<<< HEAD
236
+ enable_multi_window = self.getConfiguration().get('enable_multi_window', False)
237
+ if enable_multi_window is False:
238
+ px, py = self._display_device._pixel2DisplayCoord(px, py, display_index)
239
+ else:
240
+ wid, wx, wy = self._desktopToWindowPos((px, py))
241
+ if wid:
242
+ px, py = self._pix2windowUnits(wid, (wx, wy))
243
+ window_handle = wid
244
+ else:
245
+ window_handle = 0
246
+
247
+ =======
248
+ # result=self._validateMousePosition((px,py),display_index)
249
+ # if result != True:
250
+ # #print2err("!!! _validateMousePosition made adjustment: {0} to {1}".format((px,py),result))
251
+ # nx,ny=result
252
+ # display_index=self.getDisplayIndexForMousePosition((nx,ny))
253
+ # #print2err("Going to Update mousePosition: {0} => {1} on D {2}".format((px,py),(ny,ny),display_index))
254
+ # px,py=nx,ny
255
+ # self._nativeSetMousePos(px,py)
256
+
257
+ px, py = self._display_device._pixel2DisplayCoord(
258
+ px, py, display_index)
259
+ >>>>>>> release
260
+ self._lastPosition = self._position
261
+ self._position = px, py
262
+ self._last_display_index = self._display_index
263
+ self._display_index = display_index
264
+
265
+ # TO DO: Supported reporting scroll x info for OSX.
266
+ # This also suggests not having scroll up and down events and
267
+ # just having the one scroll event type, regardless of
268
+ # direction / dimension
269
+ scroll_dx = 0
270
+ scroll_dy = 0
271
+ button_state = 0
272
+ if etype in pressID:
273
+ button_state = MouseConstants.MOUSE_BUTTON_STATE_PRESSED
274
+ if multi_click_count > 1:
275
+ ioe_type = EventConstants.MOUSE_MULTI_CLICK
276
+ else:
277
+ ioe_type = EventConstants.MOUSE_BUTTON_PRESS
278
+ elif etype in releaseID:
279
+ button_state = MouseConstants.MOUSE_BUTTON_STATE_RELEASED
280
+ ioe_type = EventConstants.MOUSE_BUTTON_RELEASE
281
+ elif etype in dragID:
282
+ ioe_type = EventConstants.MOUSE_DRAG
283
+ elif etype == Qz.kCGEventMouseMoved:
284
+ ioe_type = EventConstants.MOUSE_MOVE
285
+ elif etype == Qz.kCGEventScrollWheel:
286
+ ioe_type = EventConstants.MOUSE_SCROLL
287
+ scroll_dy = Qz.CGEventGetIntegerValueField(event, Qz.kCGScrollWheelEventPointDeltaAxis1)
288
+ scroll_dx = Qz.CGEventGetIntegerValueField(event, Qz.kCGScrollWheelEventPointDeltaAxis2)
289
+ self._scrollPositionX += scroll_dx
290
+ self._scrollPositionY += scroll_dy
291
+
292
+ iohub_button_id = self._IOHUB_BUTTON_ID_MAPPINGS.get(etype, 0)
293
+
294
+ if iohub_button_id in self.activeButtons:
295
+ abuttons = int(button_state == MouseConstants.MOUSE_BUTTON_STATE_PRESSED)
296
+ self.activeButtons[iohub_button_id] = abuttons
297
+
298
+ pressed_buttons = 0
299
+ for k, v in self.activeButtons.items():
300
+ pressed_buttons += k * v
301
+
302
+ # Create Event List
303
+ # index 0 and 1 are session and exp. ID's
304
+ # index 2 is (yet to be used) device_id
305
+ ioe = self._EVENT_TEMPLATE_LIST
306
+ ioe[3] = Device._getNextEventID()
307
+ ioe[4] = ioe_type # event type code
308
+ ioe[5] = device_time
309
+ ioe[6] = logged_time
310
+ ioe[7] = iohub_time
311
+ ioe[8] = confidence_interval
312
+ ioe[9] = delay
313
+ # index 10 is filter id, not used at this time
314
+ ioe[11] = display_index
315
+ ioe[12] = button_state
316
+ ioe[13] = iohub_button_id
317
+ ioe[14] = pressed_buttons
318
+ ioe[15] = px
319
+ ioe[16] = py
320
+ ioe[17] = int(scroll_dx)
321
+ ioe[18] = int(self._scrollPositionX)
322
+ ioe[19] = int(scroll_dy)
323
+ ioe[20] = int(self._scrollPositionY)
324
+ ioe[21] = Keyboard._modifier_value
325
+ ioe[22] = window_handle
326
+
327
+ self._addNativeEventToBuffer(copy(ioe))
328
+
329
+ self._last_callback_time = logged_time
330
+ except Exception:
331
+ printExceptionDetailsToStdErr()
332
+ Qz.CGEventTapEnable(self._tap, False)
333
+
334
+ # Must return original event or no mouse events will get to OSX!
335
+ return event
336
+
337
+ def _getIOHubEventObject(self, native_event_data):
338
+ #ioHub.print2err('Event: ',native_event_data)
339
+ return native_event_data
340
+
341
+ def _close(self):
342
+ #try:
343
+ # self._nativeSetSystemCursorVisibility(True)
344
+ #except Exception:
345
+ # pass
346
+
347
+ try:
348
+ Qz.CGEventTapEnable(self._tap, False)
349
+ except Exception:
350
+ pass
351
+
352
+ try:
353
+ if Qz.CFRunLoopContainsSource(
354
+ self._device_loop,
355
+ self._loop_source,
356
+ self._loop_mode) is True:
357
+ Qz.CFRunLoopRemoveSource(
358
+ self._device_loop, self._loop_source, self._loop_mode)
359
+ finally:
360
+ self._loop_source = None
361
+ self._tap = None
362
+ self._device_loop = None
363
+ self._loop_mode = None
364
+
365
+ MouseDevice._close(self)
366
+ # END OF OSX MOUSE CLASS
367
+
368
+ """
369
+ CGEventTapInformation
370
+ Defines the structure used to report information about event taps.
371
+ typedef struct CGEventTapInformation
372
+ {
373
+ uint32_t eventTapID;
374
+ CGEventTapLocation tapPoint;
375
+ CGEventTapOptions options;
376
+ CGEventMask eventsOfInterest;
377
+ pid_t tappingProcess;
378
+ pid_t processBeingTapped;
379
+ bool enabled;
380
+ float minUsecLatency;
381
+ float avgUsecLatency;
382
+ float maxUsecLatency;
383
+ } CGEventTapInformation;
384
+ Fields
385
+
386
+ eventTapID
387
+ The unique identifier for the event tap.
388
+
389
+ tapPoint
390
+ The location of the event tap. See "Event Tap Locations."
391
+
392
+ options
393
+ The type of event tap (passive listener or active filter).
394
+
395
+ eventsOfInterest
396
+ The mask that identifies the set of events to be observed.
397
+
398
+ tappingProcess
399
+ The process ID of the application that created the event tap.
400
+
401
+ processBeingTapped
402
+ The process ID of the target application (non-zero only if the
403
+ event tap was created using the function CGEventTapCreateForPSN.
404
+
405
+ enabled
406
+ TRUE if the event tap is currently enabled; otherwise FALSE.
407
+
408
+ minUsecLatency
409
+ Minimum latency in microseconds. In this data structure,
410
+ latency is defined as the time in microseconds it takes
411
+ for an event tap to process and respond to an event passed to it.
412
+
413
+ avgUsecLatency
414
+ Average latency in microseconds. This is a weighted average
415
+ that gives greater weight to more recent events.
416
+
417
+ maxUsecLatency
418
+ Maximum latency in microseconds.
419
+
420
+ Discussion
421
+ To learn how to obtain information about event taps, see the
422
+ function CGGetEventTapList.
423
+ Availability
424
+ Available in OS X v10.4 and later.
425
+ Declared In
426
+ CGEventTypes.h
427
+ """
@@ -0,0 +1,198 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Part of the PsychoPy library
3
+ # Copyright (C) 2012-2020 iSolver Software Solutions (C) 2021 Open Science Tools Ltd.
4
+ # Distributed under the terms of the GNU General Public License (GPL).
5
+
6
+ from ctypes import cdll
7
+
8
+ from . import MouseDevice
9
+ from .. import Keyboard, Computer, Device, xlib
10
+ from ...constants import MouseConstants
11
+ from ...errors import print2err, printExceptionDetailsToStdErr
12
+
13
+ currentSec = Computer.getTime
14
+
15
+
16
+ class Mouse(MouseDevice):
17
+ """The Mouse class and related events represent a standard computer mouse
18
+ device and the events a standard mouse can produce.
19
+
20
+ Mouse position data is mapped to the coordinate space defined in the
21
+ ioHub configuration file for the Display.
22
+
23
+ """
24
+
25
+ _xdll = None
26
+ _xfixsdll = None
27
+ _xdisplay = None
28
+ _xscreen_count = None
29
+
30
+ __slots__ = ['_cursorVisible']
31
+
32
+ def __init__(self, *args, **kwargs):
33
+ MouseDevice.__init__(self, *args, **kwargs['dconfig'])
34
+
35
+ self._cursorVisible = True
36
+
37
+ if Mouse._xdll is None:
38
+ try:
39
+ Mouse._xdll = cdll.LoadLibrary('libX11.so')
40
+ try:
41
+ # should use linux cmd:
42
+ # find /usr/lib -name libXfixes.so\*
43
+ # to find full path to the lib (if it exists)
44
+ #
45
+ Mouse._xfixsdll = cdll.LoadLibrary('libXfixes.so')
46
+ except Exception:
47
+ try:
48
+ Mouse._xfixsdll = cdll.LoadLibrary(
49
+ 'libXfixes.so.3.1.0')
50
+ except Exception:
51
+ print2err(
52
+ 'ERROR: Mouse._xfixsdll is None. libXfixes.so could not be found')
53
+ except Exception:
54
+ print2err(
55
+ 'ERROR: Mouse._xdll is None. libX11.so could not be found')
56
+
57
+ Mouse._xdisplay = xlib.XOpenDisplay(None)
58
+ Mouse._xscreen_count = xlib.XScreenCount(Mouse._xdisplay)
59
+
60
+ if Mouse._xfixsdll and self._xdll and self._display_device and self._display_device._xwindow is None:
61
+ self._display_device._xwindow = self._xdll.XRootWindow(
62
+ Mouse._xdisplay, self._display_device.getIndex())
63
+
64
+
65
+ def _initialMousePos(self):
66
+ """If getPosition is called prior to any mouse events being received,
67
+ this method gets the current system cursor pos.
68
+ TODO: Implement Linux version
69
+ """
70
+ if self._position is None:
71
+ self._position = 0.0, 0.0
72
+ self._lastPosition = 0.0, 0.0
73
+
74
+ def _nativeSetMousePos(self, px, py):
75
+ Mouse._xdll.XWarpPointer(
76
+ Mouse._xdisplay,
77
+ None,
78
+ self._display_device._xwindow,
79
+ 0,
80
+ 0,
81
+ 0,
82
+ 0,
83
+ int(px),
84
+ int(py))
85
+ Mouse._xdll.XFlush(Mouse._xdisplay)
86
+
87
+ <<<<<<< HEAD
88
+ =======
89
+ #def _nativeGetSystemCursorVisibility(self):
90
+ # return self._cursorVisible
91
+
92
+ # def _nativeSetSystemCursorVisibility(self, v):
93
+ # if Mouse._xfixsdll is None:
94
+ # print2err(
95
+ # 'Xfixes DLL could not be loaded. Cursor visibility support is unavailable.')
96
+ # return True
97
+ #
98
+ # if v is True and self._nativeGetSystemCursorVisibility() is False:
99
+ # Mouse._xfixsdll.XFixesShowCursor(
100
+ # Mouse._xdisplay, self._display_device._xwindow)
101
+ # Mouse._xfixsdll.XFlush(Mouse._xdisplay)
102
+ # self._cursorVisible = True
103
+ # elif v is False and self._nativeGetSystemCursorVisibility() is True:
104
+ # Mouse._xfixsdll.XFixesHideCursor(
105
+ # Mouse._xdisplay, self._display_device._xwindow)
106
+ # Mouse._xfixsdll.XFlush(Mouse._xdisplay)
107
+ # self._cursorVisible = False
108
+ #
109
+ # return self._nativeGetSystemCursorVisibility()
110
+
111
+ #def _nativeLimitCursorToBoundingRect(self, clip_rect):
112
+ # print2err(
113
+ # 'WARNING: Mouse._nativeLimitCursorToBoundingRect not implemented on Linux yet.')
114
+ # native_clip_rect = None
115
+ # return native_clip_rect
116
+
117
+ >>>>>>> release
118
+ def _nativeEventCallback(self, event):
119
+ try:
120
+ if self.isReportingEvents():
121
+ logged_time = currentSec()
122
+ event_array = event[0]
123
+
124
+ psychowins = self._iohub_server._psychopy_windows.keys()
125
+ report_all = self.getConfiguration().get('report_system_wide_events', True)
126
+ if report_all is False and psychowins and event_array[-1] not in psychowins:
127
+ return True
128
+
129
+ event_array[3] = Device._getNextEventID()
130
+
131
+ display_index = self.getDisplayIndexForMousePosition((event_array[15], event_array[16]))
132
+ if display_index == -1:
133
+ if self._last_display_index is not None:
134
+ display_index = self._last_display_index
135
+ else:
136
+ # Do not report event to iohub if it does not map to a display
137
+ # ?? Can this ever actually happen ??
138
+ return True
139
+
140
+ enable_multi_window = self.getConfiguration().get('enable_multi_window', False)
141
+ if enable_multi_window is False:
142
+ # convert mouse position to psychopy window coord space
143
+ display_index = self._display_device.getIndex()
144
+ x, y = self._display_device._pixel2DisplayCoord(event_array[15], event_array[16], display_index)
145
+ event_array[15] = x
146
+ event_array[16] = y
147
+ else:
148
+ wid, wx, wy = self._desktopToWindowPos((event_array[15], event_array[16]))
149
+ if wid:
150
+ wx, wy = self._pix2windowUnits(wid, (wx, wy))
151
+ event_array[15], event_array[16] = x, y = wx, wy
152
+ event_array[-1] = wid
153
+ else:
154
+ event_array[-1] = 0
155
+ x = event_array[15]
156
+ y = event_array[16]
157
+
158
+ event_array[-2] = Keyboard._modifier_value
159
+ self._lastPosition = self._position
160
+ self._position = x, y
161
+
162
+ event_array[11] = display_index
163
+ self._last_display_index = self._display_index
164
+ self._display_index = display_index
165
+
166
+ bstate = event_array[-11]
167
+ bnum = event_array[-10]
168
+
169
+ if bnum is not MouseConstants.MOUSE_BUTTON_NONE:
170
+ self.activeButtons[bnum] = int(bstate)
171
+
172
+ self._scrollPositionY = event_array[-3]
173
+
174
+ self._addNativeEventToBuffer(event_array)
175
+
176
+ self._last_callback_time = logged_time
177
+ except Exception:
178
+ printExceptionDetailsToStdErr()
179
+ return True
180
+
181
+ def _getIOHubEventObject(self, native_event_data):
182
+ return native_event_data
183
+
184
+ def _close(self):
185
+ if Mouse._xdll:
186
+ #if Mouse._xfixsdll and self._nativeGetSystemCursorVisibility() is False:
187
+ # Mouse._xfixsdll.XFixesShowCursor(
188
+ # Mouse._xdisplay, self._display_device._xwindow)
189
+ Mouse._xdll.XCloseDisplay(Mouse._xdisplay)
190
+ Mouse._xdll = None
191
+ Mouse._xfixsdll = None
192
+ Mouse._xdisplay = None
193
+ Mouse._xscreen_count = None
194
+
195
+ try:
196
+ self._display_device._xwindow = None
197
+ except Exception:
198
+ pass
Binary file
@@ -1208,12 +1208,19 @@ class PavloviaProject(dict):
1208
1208
  None
1209
1209
  """
1210
1210
  localConfig = self.repo.git.config(l=True, local=True) # list local
1211
- if self.session.user['email'] in localConfig:
1212
- return # we already have it set up so can return
1213
1211
  # set the local config
1214
- with self.repo.config_writer() as config:
1212
+ config = self.repo.config_writer()
1213
+ # set config values if the user hasn't set them already
1214
+ # the -100 hack is because ConfigParser.get_value allows setting a default
1215
+ # but doing try...except on its custom errors is annoying!
1216
+ if config.get_value("user", "email", default=-100) == -100:
1215
1217
  config.set_value("user", "email", self.session.user['email'])
1216
1218
  config.set_value("user", "name", self.session.user['name'])
1219
+ if config.get_value("pull", "rebase", default=-100) == -100:
1220
+ config.set_value("pull", "rebase", False)
1221
+ if config.get_value("http", "postBuffer", default=-100) == -100:
1222
+ config.set_value("http", "postBuffer", 524288000)
1223
+ config.release() # saves the changes (not needed if using `with config_writer() as config`)
1217
1224
 
1218
1225
  def fork(self, to=None):
1219
1226
  # Sub in current user if none given